#include <linux/etherdevice.h>
#include <linux/if_arp.h>
#include <linux/mii.h>
+#include <linux/rtnetlink.h>
#include <linux/usb.h>
#include <linux/usb/cdc.h>
#include <linux/usb/usbnet.h>
struct usbnet *dev = netdev_priv(to_net_dev(d));
struct qmi_wwan_state *info = (void *)&dev->data;
bool enable;
- int err;
+ int ret;
if (strtobool(buf, &enable))
return -EINVAL;
if (enable == (info->flags & QMI_WWAN_FLAG_RAWIP))
return len;
+ if (!rtnl_trylock())
+ return restart_syscall();
+
/* we don't want to modify a running netdev */
if (netif_running(dev->net)) {
netdev_err(dev->net, "Cannot change a running device\n");
- return -EBUSY;
+ ret = -EBUSY;
+ goto err;
}
/* let other drivers deny the change */
- err = call_netdevice_notifiers(NETDEV_PRE_TYPE_CHANGE, dev->net);
- err = notifier_to_errno(err);
- if (err) {
+ ret = call_netdevice_notifiers(NETDEV_PRE_TYPE_CHANGE, dev->net);
+ ret = notifier_to_errno(ret);
+ if (ret) {
netdev_err(dev->net, "Type change was refused\n");
- return err;
+ goto err;
}
if (enable)
info->flags &= ~QMI_WWAN_FLAG_RAWIP;
qmi_wwan_netdev_setup(dev->net);
call_netdevice_notifiers(NETDEV_POST_TYPE_CHANGE, dev->net);
- return len;
+ ret = len;
+err:
+ rtnl_unlock();
+ return ret;
}
static DEVICE_ATTR_RW(raw_ip);