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: Govindarajulu Varadarajan <gvaradar@cisco.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
136f55f660
commit
ab123fe071
@ -2047,28 +2047,42 @@ static int enic_stop(struct net_device *netdev)
|
|||||||
return 0;
|
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)
|
static int enic_change_mtu(struct net_device *netdev, int new_mtu)
|
||||||
{
|
{
|
||||||
struct enic *enic = netdev_priv(netdev);
|
struct enic *enic = netdev_priv(netdev);
|
||||||
int running = netif_running(netdev);
|
|
||||||
|
|
||||||
if (enic_is_dynamic(enic) || enic_is_sriov_vf(enic))
|
if (enic_is_dynamic(enic) || enic_is_sriov_vf(enic))
|
||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
|
|
||||||
if (running)
|
|
||||||
enic_stop(netdev);
|
|
||||||
|
|
||||||
netdev->mtu = new_mtu;
|
|
||||||
|
|
||||||
if (netdev->mtu > enic->port_mtu)
|
if (netdev->mtu > enic->port_mtu)
|
||||||
netdev_warn(netdev,
|
netdev_warn(netdev,
|
||||||
"interface MTU (%d) set higher than port MTU (%d)\n",
|
"interface MTU (%d) set higher than port MTU (%d)\n",
|
||||||
netdev->mtu, enic->port_mtu);
|
netdev->mtu, enic->port_mtu);
|
||||||
|
|
||||||
if (running)
|
return _enic_change_mtu(netdev, new_mtu);
|
||||||
enic_open(netdev);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void enic_change_mtu_work(struct work_struct *work)
|
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 enic *enic = container_of(work, struct enic, change_mtu_work);
|
||||||
struct net_device *netdev = enic->netdev;
|
struct net_device *netdev = enic->netdev;
|
||||||
int new_mtu = vnic_dev_mtu(enic->vdev);
|
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();
|
rtnl_lock();
|
||||||
|
(void)_enic_change_mtu(netdev, new_mtu);
|
||||||
/* 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);
|
|
||||||
|
|
||||||
rtnl_unlock();
|
rtnl_unlock();
|
||||||
|
|
||||||
netdev_info(netdev, "interface MTU set as %d\n", netdev->mtu);
|
netdev_info(netdev, "interface MTU set as %d\n", netdev->mtu);
|
||||||
|
Loading…
Reference in New Issue
Block a user