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

Commit ab123fe0 authored by Govindarajulu Varadarajan's avatar Govindarajulu Varadarajan Committed by David S. Miller
Browse files

enic: handle mtu change for vf properly



When driver gets notification for mtu change, driver does not handle it for
all RQs. It handles only RQ[0].

Fix is to use enic_change_mtu() interface to change mtu for vf.

Signed-off-by: default avatarGovindarajulu Varadarajan <gvaradar@cisco.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 136f55f6
Loading
Loading
Loading
Loading
+27 −51
Original line number Diff line number Diff line
@@ -2047,28 +2047,42 @@ static int enic_stop(struct net_device *netdev)
	return 0;
}

static int _enic_change_mtu(struct net_device *netdev, int new_mtu)
{
	bool running = netif_running(netdev);
	int err = 0;

	ASSERT_RTNL();
	if (running) {
		err = enic_stop(netdev);
		if (err)
			return err;
	}

	netdev->mtu = new_mtu;

	if (running) {
		err = enic_open(netdev);
		if (err)
			return err;
	}

	return 0;
}

static int enic_change_mtu(struct net_device *netdev, int new_mtu)
{
	struct enic *enic = netdev_priv(netdev);
	int running = netif_running(netdev);

	if (enic_is_dynamic(enic) || enic_is_sriov_vf(enic))
		return -EOPNOTSUPP;

	if (running)
		enic_stop(netdev);

	netdev->mtu = new_mtu;

	if (netdev->mtu > enic->port_mtu)
		netdev_warn(netdev,
			    "interface MTU (%d) set higher than port MTU (%d)\n",
			    netdev->mtu, enic->port_mtu);

	if (running)
		enic_open(netdev);

	return 0;
	return _enic_change_mtu(netdev, new_mtu);
}

static void enic_change_mtu_work(struct work_struct *work)
@@ -2076,47 +2090,9 @@ static void enic_change_mtu_work(struct work_struct *work)
	struct enic *enic = container_of(work, struct enic, change_mtu_work);
	struct net_device *netdev = enic->netdev;
	int new_mtu = vnic_dev_mtu(enic->vdev);
	int err;
	unsigned int i;

	new_mtu = max_t(int, ENIC_MIN_MTU, min_t(int, ENIC_MAX_MTU, new_mtu));

	rtnl_lock();

	/* Stop RQ */
	del_timer_sync(&enic->notify_timer);

	for (i = 0; i < enic->rq_count; i++)
		napi_disable(&enic->napi[i]);

	vnic_intr_mask(&enic->intr[0]);
	enic_synchronize_irqs(enic);
	err = vnic_rq_disable(&enic->rq[0]);
	if (err) {
		rtnl_unlock();
		netdev_err(netdev, "Unable to disable RQ.\n");
		return;
	}
	vnic_rq_clean(&enic->rq[0], enic_free_rq_buf);
	vnic_cq_clean(&enic->cq[0]);
	vnic_intr_clean(&enic->intr[0]);

	/* Fill RQ with new_mtu-sized buffers */
	netdev->mtu = new_mtu;
	vnic_rq_fill(&enic->rq[0], enic_rq_alloc_buf);
	/* Need at least one buffer on ring to get going */
	if (vnic_rq_desc_used(&enic->rq[0]) == 0) {
		rtnl_unlock();
		netdev_err(netdev, "Unable to alloc receive buffers.\n");
		return;
	}

	/* Start RQ */
	vnic_rq_enable(&enic->rq[0]);
	napi_enable(&enic->napi[0]);
	vnic_intr_unmask(&enic->intr[0]);
	enic_notify_timer_start(enic);

	(void)_enic_change_mtu(netdev, new_mtu);
	rtnl_unlock();

	netdev_info(netdev, "interface MTU set as %d\n", netdev->mtu);