Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 669c00c0 authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'mlx4-fixes'



Or Gerlitz says:

====================
Mellaox 40G driver fixes for 4.6-rc

With the fix for ARM bug being under the works, these are
few other fixes for mlx4 we have ready to go.

Eran addressed the problematic/wrong reporting of dropped packets, Daniel
fixed some matters related to PPC EEH's and Jenny's patch makes sure
VFs can't change the port's pause settings.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents a1459c1c d21ed3a3
Loading
Loading
Loading
Loading
+4 −1
Original line number Original line Diff line number Diff line
@@ -337,7 +337,7 @@ static int mlx4_en_get_sset_count(struct net_device *dev, int sset)
	case ETH_SS_STATS:
	case ETH_SS_STATS:
		return bitmap_iterator_count(&it) +
		return bitmap_iterator_count(&it) +
			(priv->tx_ring_num * 2) +
			(priv->tx_ring_num * 2) +
			(priv->rx_ring_num * 2);
			(priv->rx_ring_num * 3);
	case ETH_SS_TEST:
	case ETH_SS_TEST:
		return MLX4_EN_NUM_SELF_TEST - !(priv->mdev->dev->caps.flags
		return MLX4_EN_NUM_SELF_TEST - !(priv->mdev->dev->caps.flags
					& MLX4_DEV_CAP_FLAG_UC_LOOPBACK) * 2;
					& MLX4_DEV_CAP_FLAG_UC_LOOPBACK) * 2;
@@ -404,6 +404,7 @@ static void mlx4_en_get_ethtool_stats(struct net_device *dev,
	for (i = 0; i < priv->rx_ring_num; i++) {
	for (i = 0; i < priv->rx_ring_num; i++) {
		data[index++] = priv->rx_ring[i]->packets;
		data[index++] = priv->rx_ring[i]->packets;
		data[index++] = priv->rx_ring[i]->bytes;
		data[index++] = priv->rx_ring[i]->bytes;
		data[index++] = priv->rx_ring[i]->dropped;
	}
	}
	spin_unlock_bh(&priv->stats_lock);
	spin_unlock_bh(&priv->stats_lock);


@@ -477,6 +478,8 @@ static void mlx4_en_get_strings(struct net_device *dev,
				"rx%d_packets", i);
				"rx%d_packets", i);
			sprintf(data + (index++) * ETH_GSTRING_LEN,
			sprintf(data + (index++) * ETH_GSTRING_LEN,
				"rx%d_bytes", i);
				"rx%d_bytes", i);
			sprintf(data + (index++) * ETH_GSTRING_LEN,
				"rx%d_dropped", i);
		}
		}
		break;
		break;
	case ETH_SS_PRIV_FLAGS:
	case ETH_SS_PRIV_FLAGS:
+4 −1
Original line number Original line Diff line number Diff line
@@ -158,6 +158,7 @@ int mlx4_en_DUMP_ETH_STATS(struct mlx4_en_dev *mdev, u8 port, u8 reset)
	u64 in_mod = reset << 8 | port;
	u64 in_mod = reset << 8 | port;
	int err;
	int err;
	int i, counter_index;
	int i, counter_index;
	unsigned long sw_rx_dropped = 0;


	mailbox = mlx4_alloc_cmd_mailbox(mdev->dev);
	mailbox = mlx4_alloc_cmd_mailbox(mdev->dev);
	if (IS_ERR(mailbox))
	if (IS_ERR(mailbox))
@@ -180,6 +181,7 @@ int mlx4_en_DUMP_ETH_STATS(struct mlx4_en_dev *mdev, u8 port, u8 reset)
	for (i = 0; i < priv->rx_ring_num; i++) {
	for (i = 0; i < priv->rx_ring_num; i++) {
		stats->rx_packets += priv->rx_ring[i]->packets;
		stats->rx_packets += priv->rx_ring[i]->packets;
		stats->rx_bytes += priv->rx_ring[i]->bytes;
		stats->rx_bytes += priv->rx_ring[i]->bytes;
		sw_rx_dropped += priv->rx_ring[i]->dropped;
		priv->port_stats.rx_chksum_good += priv->rx_ring[i]->csum_ok;
		priv->port_stats.rx_chksum_good += priv->rx_ring[i]->csum_ok;
		priv->port_stats.rx_chksum_none += priv->rx_ring[i]->csum_none;
		priv->port_stats.rx_chksum_none += priv->rx_ring[i]->csum_none;
		priv->port_stats.rx_chksum_complete += priv->rx_ring[i]->csum_complete;
		priv->port_stats.rx_chksum_complete += priv->rx_ring[i]->csum_complete;
@@ -236,7 +238,8 @@ int mlx4_en_DUMP_ETH_STATS(struct mlx4_en_dev *mdev, u8 port, u8 reset)
					  &mlx4_en_stats->MCAST_prio_1,
					  &mlx4_en_stats->MCAST_prio_1,
					  NUM_PRIORITIES);
					  NUM_PRIORITIES);
	stats->collisions = 0;
	stats->collisions = 0;
	stats->rx_dropped = be32_to_cpu(mlx4_en_stats->RDROP);
	stats->rx_dropped = be32_to_cpu(mlx4_en_stats->RDROP) +
			    sw_rx_dropped;
	stats->rx_length_errors = be32_to_cpu(mlx4_en_stats->RdropLength);
	stats->rx_length_errors = be32_to_cpu(mlx4_en_stats->RdropLength);
	stats->rx_over_errors = 0;
	stats->rx_over_errors = 0;
	stats->rx_crc_errors = be32_to_cpu(mlx4_en_stats->RCRC);
	stats->rx_crc_errors = be32_to_cpu(mlx4_en_stats->RCRC);
+1 −1
Original line number Original line Diff line number Diff line
@@ -943,7 +943,7 @@ int mlx4_en_process_rx_cq(struct net_device *dev, struct mlx4_en_cq *cq, int bud
		/* GRO not possible, complete processing here */
		/* GRO not possible, complete processing here */
		skb = mlx4_en_rx_skb(priv, rx_desc, frags, length);
		skb = mlx4_en_rx_skb(priv, rx_desc, frags, length);
		if (!skb) {
		if (!skb) {
			priv->stats.rx_dropped++;
			ring->dropped++;
			goto next;
			goto next;
		}
		}


+57 −19
Original line number Original line Diff line number Diff line
@@ -3172,6 +3172,34 @@ static int mlx4_check_dev_cap(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap
	return 0;
	return 0;
}
}


static int mlx4_pci_enable_device(struct mlx4_dev *dev)
{
	struct pci_dev *pdev = dev->persist->pdev;
	int err = 0;

	mutex_lock(&dev->persist->pci_status_mutex);
	if (dev->persist->pci_status == MLX4_PCI_STATUS_DISABLED) {
		err = pci_enable_device(pdev);
		if (!err)
			dev->persist->pci_status = MLX4_PCI_STATUS_ENABLED;
	}
	mutex_unlock(&dev->persist->pci_status_mutex);

	return err;
}

static void mlx4_pci_disable_device(struct mlx4_dev *dev)
{
	struct pci_dev *pdev = dev->persist->pdev;

	mutex_lock(&dev->persist->pci_status_mutex);
	if (dev->persist->pci_status == MLX4_PCI_STATUS_ENABLED) {
		pci_disable_device(pdev);
		dev->persist->pci_status = MLX4_PCI_STATUS_DISABLED;
	}
	mutex_unlock(&dev->persist->pci_status_mutex);
}

static int mlx4_load_one(struct pci_dev *pdev, int pci_dev_data,
static int mlx4_load_one(struct pci_dev *pdev, int pci_dev_data,
			 int total_vfs, int *nvfs, struct mlx4_priv *priv,
			 int total_vfs, int *nvfs, struct mlx4_priv *priv,
			 int reset_flow)
			 int reset_flow)
@@ -3582,7 +3610,7 @@ static int __mlx4_init_one(struct pci_dev *pdev, int pci_dev_data,


	pr_info(DRV_NAME ": Initializing %s\n", pci_name(pdev));
	pr_info(DRV_NAME ": Initializing %s\n", pci_name(pdev));


	err = pci_enable_device(pdev);
	err = mlx4_pci_enable_device(&priv->dev);
	if (err) {
	if (err) {
		dev_err(&pdev->dev, "Cannot enable PCI device, aborting\n");
		dev_err(&pdev->dev, "Cannot enable PCI device, aborting\n");
		return err;
		return err;
@@ -3715,7 +3743,7 @@ static int __mlx4_init_one(struct pci_dev *pdev, int pci_dev_data,
	pci_release_regions(pdev);
	pci_release_regions(pdev);


err_disable_pdev:
err_disable_pdev:
	pci_disable_device(pdev);
	mlx4_pci_disable_device(&priv->dev);
	pci_set_drvdata(pdev, NULL);
	pci_set_drvdata(pdev, NULL);
	return err;
	return err;
}
}
@@ -3775,6 +3803,7 @@ static int mlx4_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
	priv->pci_dev_data = id->driver_data;
	priv->pci_dev_data = id->driver_data;
	mutex_init(&dev->persist->device_state_mutex);
	mutex_init(&dev->persist->device_state_mutex);
	mutex_init(&dev->persist->interface_state_mutex);
	mutex_init(&dev->persist->interface_state_mutex);
	mutex_init(&dev->persist->pci_status_mutex);


	ret = devlink_register(devlink, &pdev->dev);
	ret = devlink_register(devlink, &pdev->dev);
	if (ret)
	if (ret)
@@ -3923,7 +3952,7 @@ static void mlx4_remove_one(struct pci_dev *pdev)
	}
	}


	pci_release_regions(pdev);
	pci_release_regions(pdev);
	pci_disable_device(pdev);
	mlx4_pci_disable_device(dev);
	devlink_unregister(devlink);
	devlink_unregister(devlink);
	kfree(dev->persist);
	kfree(dev->persist);
	devlink_free(devlink);
	devlink_free(devlink);
@@ -4042,7 +4071,7 @@ static pci_ers_result_t mlx4_pci_err_detected(struct pci_dev *pdev,
	if (state == pci_channel_io_perm_failure)
	if (state == pci_channel_io_perm_failure)
		return PCI_ERS_RESULT_DISCONNECT;
		return PCI_ERS_RESULT_DISCONNECT;


	pci_disable_device(pdev);
	mlx4_pci_disable_device(persist->dev);
	return PCI_ERS_RESULT_NEED_RESET;
	return PCI_ERS_RESULT_NEED_RESET;
}
}


@@ -4050,45 +4079,53 @@ static pci_ers_result_t mlx4_pci_slot_reset(struct pci_dev *pdev)
{
{
	struct mlx4_dev_persistent *persist = pci_get_drvdata(pdev);
	struct mlx4_dev_persistent *persist = pci_get_drvdata(pdev);
	struct mlx4_dev	 *dev  = persist->dev;
	struct mlx4_dev	 *dev  = persist->dev;
	struct mlx4_priv *priv = mlx4_priv(dev);
	int err;
	int               ret;
	int nvfs[MLX4_MAX_PORTS + 1] = {0, 0, 0};
	int total_vfs;


	mlx4_err(dev, "mlx4_pci_slot_reset was called\n");
	mlx4_err(dev, "mlx4_pci_slot_reset was called\n");
	ret = pci_enable_device(pdev);
	err = mlx4_pci_enable_device(dev);
	if (ret) {
	if (err) {
		mlx4_err(dev, "Can not re-enable device, ret=%d\n", ret);
		mlx4_err(dev, "Can not re-enable device, err=%d\n", err);
		return PCI_ERS_RESULT_DISCONNECT;
		return PCI_ERS_RESULT_DISCONNECT;
	}
	}


	pci_set_master(pdev);
	pci_set_master(pdev);
	pci_restore_state(pdev);
	pci_restore_state(pdev);
	pci_save_state(pdev);
	pci_save_state(pdev);
	return PCI_ERS_RESULT_RECOVERED;
}

static void mlx4_pci_resume(struct pci_dev *pdev)
{
	struct mlx4_dev_persistent *persist = pci_get_drvdata(pdev);
	struct mlx4_dev	 *dev  = persist->dev;
	struct mlx4_priv *priv = mlx4_priv(dev);
	int nvfs[MLX4_MAX_PORTS + 1] = {0, 0, 0};
	int total_vfs;
	int err;


	mlx4_err(dev, "%s was called\n", __func__);
	total_vfs = dev->persist->num_vfs;
	total_vfs = dev->persist->num_vfs;
	memcpy(nvfs, dev->persist->nvfs, sizeof(dev->persist->nvfs));
	memcpy(nvfs, dev->persist->nvfs, sizeof(dev->persist->nvfs));


	mutex_lock(&persist->interface_state_mutex);
	mutex_lock(&persist->interface_state_mutex);
	if (!(persist->interface_state & MLX4_INTERFACE_STATE_UP)) {
	if (!(persist->interface_state & MLX4_INTERFACE_STATE_UP)) {
		ret = mlx4_load_one(pdev, priv->pci_dev_data, total_vfs, nvfs,
		err = mlx4_load_one(pdev, priv->pci_dev_data, total_vfs, nvfs,
				    priv, 1);
				    priv, 1);
		if (ret) {
		if (err) {
			mlx4_err(dev, "%s: mlx4_load_one failed, ret=%d\n",
			mlx4_err(dev, "%s: mlx4_load_one failed, err=%d\n",
				 __func__,  ret);
				 __func__,  err);
			goto end;
			goto end;
		}
		}


		ret = restore_current_port_types(dev, dev->persist->
		err = restore_current_port_types(dev, dev->persist->
						 curr_port_type, dev->persist->
						 curr_port_type, dev->persist->
						 curr_port_poss_type);
						 curr_port_poss_type);
		if (ret)
		if (err)
			mlx4_err(dev, "could not restore original port types (%d)\n", ret);
			mlx4_err(dev, "could not restore original port types (%d)\n", err);
	}
	}
end:
end:
	mutex_unlock(&persist->interface_state_mutex);
	mutex_unlock(&persist->interface_state_mutex);


	return ret ? PCI_ERS_RESULT_DISCONNECT : PCI_ERS_RESULT_RECOVERED;
}
}


static void mlx4_shutdown(struct pci_dev *pdev)
static void mlx4_shutdown(struct pci_dev *pdev)
@@ -4105,6 +4142,7 @@ static void mlx4_shutdown(struct pci_dev *pdev)
static const struct pci_error_handlers mlx4_err_handler = {
static const struct pci_error_handlers mlx4_err_handler = {
	.error_detected = mlx4_pci_err_detected,
	.error_detected = mlx4_pci_err_detected,
	.slot_reset     = mlx4_pci_slot_reset,
	.slot_reset     = mlx4_pci_slot_reset,
	.resume		= mlx4_pci_resume,
};
};


static struct pci_driver mlx4_driver = {
static struct pci_driver mlx4_driver = {
+2 −0
Original line number Original line Diff line number Diff line
@@ -586,6 +586,8 @@ struct mlx4_mfunc_master_ctx {
	struct mlx4_master_qp0_state qp0_state[MLX4_MAX_PORTS + 1];
	struct mlx4_master_qp0_state qp0_state[MLX4_MAX_PORTS + 1];
	int			init_port_ref[MLX4_MAX_PORTS + 1];
	int			init_port_ref[MLX4_MAX_PORTS + 1];
	u16			max_mtu[MLX4_MAX_PORTS + 1];
	u16			max_mtu[MLX4_MAX_PORTS + 1];
	u8			pptx;
	u8			pprx;
	int			disable_mcast_ref[MLX4_MAX_PORTS + 1];
	int			disable_mcast_ref[MLX4_MAX_PORTS + 1];
	struct mlx4_resource_tracker res_tracker;
	struct mlx4_resource_tracker res_tracker;
	struct workqueue_struct *comm_wq;
	struct workqueue_struct *comm_wq;
Loading