void nf_conntrack_l3proto_unregister(struct nf_conntrack_l3proto *proto)
{
	struct net *net;

	BUG_ON(proto->l3proto >= AF_MAX);

	mutex_lock(&nf_ct_proto_mutex);
	BUG_ON(nf_ct_l3protos[proto->l3proto] != proto);
	rcu_assign_pointer(nf_ct_l3protos[proto->l3proto],
			   &nf_conntrack_l3proto_generic);
	nf_ct_l3proto_unregister_sysctl(proto);
	mutex_unlock(&nf_ct_proto_mutex);

	synchronize_rcu();

	/* Remove all contrack entries for this protocol */
	rtnl_lock();
	for_each_net(net)
		nf_ct_iterate_cleanup(net, kill_l3proto, proto);
	rtnl_unlock();
}
Beispiel #2
0
static int mlxsw_sp_dpipe_table_erif_counters_update(void *priv, bool enable)
{
	struct mlxsw_sp *mlxsw_sp = priv;
	int i;

	rtnl_lock();
	for (i = 0; i < MLXSW_CORE_RES_GET(mlxsw_sp->core, MAX_RIFS); i++) {
		struct mlxsw_sp_rif *rif = mlxsw_sp_rif_by_index(mlxsw_sp, i);

		if (!rif)
			continue;
		if (enable)
			mlxsw_sp_rif_counter_alloc(mlxsw_sp, rif,
						   MLXSW_SP_RIF_COUNTER_EGRESS);
		else
			mlxsw_sp_rif_counter_free(mlxsw_sp, rif,
						  MLXSW_SP_RIF_COUNTER_EGRESS);
	}
	rtnl_unlock();
	return 0;
}
void ip_mc_drop_socket(struct sock *sk)
{
    struct ip_mc_socklist *iml;

    if (sk->protinfo.af_inet.mc_list == NULL)
        return;

    rtnl_lock();
    while ((iml=sk->protinfo.af_inet.mc_list) != NULL) {
        struct in_device *in_dev;
        sk->protinfo.af_inet.mc_list = iml->next;

        if ((in_dev = inetdev_by_index(iml->multi.imr_ifindex)) != NULL) {
            ip_mc_dec_group(in_dev, iml->multi.imr_multiaddr.s_addr);
            in_dev_put(in_dev);
        }
        sock_kfree_s(sk, iml, sizeof(*iml));

    }
    rtnl_unlock();
}
Beispiel #4
0
static void enic_reset(struct work_struct *work)
{
	struct enic *enic = container_of(work, struct enic, reset);

	if (!netif_running(enic->netdev))
		return;

	rtnl_lock();

	spin_lock(&enic->devcmd_lock);
	vnic_dev_hang_notify(enic->vdev);
	spin_unlock(&enic->devcmd_lock);

	enic_stop(enic->netdev);
	enic_dev_soft_reset(enic);
	enic_reset_mcaddrs(enic);
	enic_init_vnic_resources(enic);
	enic_open(enic->netdev);

	rtnl_unlock();
}
Beispiel #5
0
static int __init ifb_init_module(void)
{
	int i, err;

	rtnl_lock();
	err = __rtnl_link_register(&ifb_link_ops);
	if (err < 0)
		goto out;

	for (i = 0; i < numifbs && !err; i++) {
		err = ifb_init_one(i);
		cond_resched();
	}
	if (err)
		__rtnl_link_unregister(&ifb_link_ops);

out:
	rtnl_unlock();

	return err;
}
static ssize_t store_stp_state(struct device *d,
			       struct device_attribute *attr, const char *buf,
			       size_t len)
{
	struct net_bridge *br = to_bridge(d);
	char *endp;
	unsigned long val;

	if (!capable(CAP_NET_ADMIN))
		return -EPERM;

	val = simple_strtoul(buf, &endp, 0);
	if (endp == buf)
		return -EINVAL;

	rtnl_lock();
	br_stp_set_enabled(br, val);
	rtnl_unlock();

	return len;
}
Beispiel #7
0
static void packet_flush_mclist(struct sock *sk)
{
    struct packet_opt *po = pkt_sk(sk);
    struct packet_mclist *ml;

    if (!po->mclist)
        return;

    rtnl_lock();
    while ((ml = po->mclist) != NULL) {
        struct net_device *dev;

        po->mclist = ml->next;
        if ((dev = dev_get_by_index(ml->ifindex)) != NULL) {
            packet_dev_mc(dev, ml, -1);
            dev_put(dev);
        }
        kfree(ml);
    }
    rtnl_unlock();
}
Beispiel #8
0
static struct net_device *ipmr_reg_vif(void)
{
	struct net_device *dev;
	struct in_device *in_dev;

	dev = alloc_netdev(sizeof(struct net_device_stats), "pimreg",
			   reg_vif_setup);

	if (dev == NULL)
		return NULL;

	if (register_netdevice(dev)) {
		free_netdev(dev);
		return NULL;
	}
	dev->iflink = 0;

	rcu_read_lock();
	if ((in_dev = __in_dev_get_rcu(dev)) == NULL) {
		rcu_read_unlock();
		goto failure;
	}

	ipv4_devconf_setall(in_dev);
	IPV4_DEVCONF(in_dev->cnf, RP_FILTER) = 0;
	rcu_read_unlock();

	if (dev_open(dev))
		goto failure;

	return dev;

failure:
	/* allow the register to be completed before unregistering. */
	rtnl_unlock();
	rtnl_lock();

	unregister_netdevice(dev);
	return NULL;
}
Beispiel #9
0
int register_netdev(struct net_device *dev)
{
	int err;

	rtnl_lock();

	/*
	 *	If the name is a format string the caller wants us to
	 *	do a name allocation
	 */
	 
	if (strchr(dev->name, '%'))
	{
		err = -EBUSY;
		if(dev_alloc_name(dev, dev->name)<0)
			goto out;
	}
	
	/*
	 *	Back compatibility hook. Kill this one in 2.5
	 */
	
	if (dev->name[0]==0 || dev->name[0]==' ')
	{
		err = -EBUSY;
		if(dev_alloc_name(dev, "eth%d")<0)
			goto out;
	}
		
		
	err = -EIO;
	if (register_netdevice(dev))
		goto out;

	err = 0;

out:
	rtnl_unlock();
	return err;
}
Beispiel #10
0
static int __init pxa250_irda_init(void)
{
	struct net_device *dev;
	int err;

	/* STUART */
	err = request_mem_region(__PREG(STRBR), 0x24, "IrDA") ? 0 : -EBUSY;
	if (err)
		goto err_mem_1;

	/* FIR */
	err = request_mem_region(__PREG(ICCR0), 0x1c, "IrDA") ? 0 : -EBUSY;
	if (err)
		goto err_mem_2;


	rtnl_lock();
	dev = dev_alloc("irda%d", &err);
	if (dev) {
		dev->irq    = IRQ_STUART;
		dev->init   = pxa250_irda_net_init;
		dev->uninit = pxa250_irda_net_uninit;

		err = register_netdevice(dev);

		if (err)
			kfree(dev);
		else
			netdev = dev;
	}
	rtnl_unlock();

	if (err) {
		release_mem_region(__PREG(ICCR0), 0x1c);
err_mem_2:
		release_mem_region(__PREG(STRBR), 0x24);
	}
err_mem_1:
	return err;
}
Beispiel #11
0
void ieee80211_unregister_hw(struct ieee80211_hw *hw)
{
	struct ieee80211_local *local = hw_to_local(hw);

	tasklet_kill(&local->tx_pending_tasklet);
	tasklet_kill(&local->tasklet);

	pm_qos_remove_notifier(PM_QOS_NETWORK_LATENCY,
			       &local->network_latency_notifier);

	rtnl_lock();

	/*
	 * At this point, interface list manipulations are fine
	 * because the driver cannot be handing us frames any
	 * more and the tasklet is killed.
	 */
	ieee80211_remove_interfaces(local);

	rtnl_unlock();

	cancel_work_sync(&local->reconfig_filter);

	ieee80211_clear_tx_pending(local);
	sta_info_stop(local);
	rate_control_deinitialize(local);

	if (skb_queue_len(&local->skb_queue) ||
	    skb_queue_len(&local->skb_queue_unreliable))
		printk(KERN_WARNING "%s: skb_queue not empty\n",
		       wiphy_name(local->hw.wiphy));
	skb_queue_purge(&local->skb_queue);
	skb_queue_purge(&local->skb_queue_unreliable);

	destroy_workqueue(local->workqueue);
	wiphy_unregister(local->hw.wiphy);
	ieee80211_wep_free(local);
	ieee80211_led_exit(local);
	kfree(local->int_scan_req);
}
Beispiel #12
0
void efx_ef10_sriov_fini(struct efx_nic *efx)
{
#ifdef CONFIG_SFC_SRIOV
	struct efx_ef10_nic_data *nic_data = efx->nic_data;
	unsigned int i;
	int rc;

	if (!nic_data->vf) {
		/* Remove any un-assigned orphaned VFs */
#if !defined(EFX_USE_KCOMPAT) || defined(EFX_HAVE_PCI_DEV_FLAGS_ASSIGNED)
		if (pci_num_vf(efx->pci_dev) && !pci_vfs_assigned(efx->pci_dev))
#endif
			pci_disable_sriov(efx->pci_dev);
		return;
	}

	/* Remove any VFs in the host */
	for (i = 0; i < efx->vf_count; ++i) {
		struct efx_nic *vf_efx = nic_data->vf[i].efx;

		if (vf_efx) {
			efx_device_detach_sync(vf_efx);
			rtnl_lock();
			efx_net_stop(vf_efx->net_dev);
			rtnl_unlock();
			down_write(&vf_efx->filter_sem);
			vf_efx->type->filter_table_remove(vf_efx);
			up_write(&vf_efx->filter_sem);
			efx_ef10_vadaptor_free(vf_efx, EVB_PORT_ID_ASSIGNED);
			vf_efx->pci_dev->driver->remove(vf_efx->pci_dev);
		}
	}

	rc = efx_ef10_pci_sriov_disable(efx, true);
	if (rc)
		netif_dbg(efx, drv, efx->net_dev, "Disabling SRIOV was not successful rc=%d\n", rc);
	else
		netif_dbg(efx, drv, efx->net_dev, "SRIOV disabled\n");
#endif
}
static int unregister_vlan_device(const char *vlan_IF_name)
{
	struct net_device *dev = NULL;
	int ret;


	dev = dev_get_by_name(vlan_IF_name);
	ret = -EINVAL;
	if (dev) {
		if (dev->priv_flags & IFF_802_1Q_VLAN) {
			rtnl_lock();

			ret = unregister_vlan_dev(VLAN_DEV_INFO(dev)->real_dev,
						  VLAN_DEV_INFO(dev)->vlan_id);

			dev_put(dev);
			unregister_netdevice(dev);

			rtnl_unlock();

			if (ret == 1)
				ret = 0;
		} else {
			printk(VLAN_ERR 
			       "%s: ERROR:	Tried to remove a non-vlan device "
			       "with VLAN code, name: %s  priv_flags: %hX\n",
			       __FUNCTION__, dev->name, dev->priv_flags);
			dev_put(dev);
			ret = -EPERM;
		}
	} else {
#ifdef VLAN_DEBUG
		printk(VLAN_DBG "%s: WARNING: Could not find dev.\n", __FUNCTION__);
#endif
		ret = -EINVAL;
	}

	return ret;
}
Beispiel #14
0
static void __exit rh_release(void)
{
	unsigned int sum = 0;
	int i;

	pr_info("rxhook (v%s) is unloaded\n", RXHOOK_VERSION);

	rtnl_lock();
	netdev_rx_handler_unregister(rh->dev);
	rtnl_unlock();

	kfree(rh);
	rh = NULL;

	for(i = 0; i < 10; i++) {
		pr_info("pps[%d] = %d\n", i, pps[i]);
		sum += pps[i];
	}
	pr_info("sum: %u\n", sum);

	return;
}
Beispiel #15
0
static int tun_chr_close(struct inode *inode, struct file *file)
{
	struct tun_struct *tun = (struct tun_struct *)file->private_data;

	DBG(KERN_INFO "%s: tun_chr_close\n", tun->name);

	if (tun->flags & TUN_IFF_SET) {
		rtnl_lock();
		dev_close(&tun->dev);
		rtnl_unlock();

		/* Drop TX queue */
		skb_queue_purge(&tun->txq);

		unregister_netdev(&tun->dev);
	}

	kfree(tun);
	file->private_data = NULL;

	return 0;
}
Beispiel #16
0
/*
 * Write mgmt frame to this file to send it
 */
static ssize_t wil_write_file_txmgmt(struct file *file, const char __user *buf,
				     size_t len, loff_t *ppos)
{
	struct wil6210_priv *wil = file->private_data;
#if 0
	struct net_device *ndev = wil_to_ndev(wil);
#endif
	struct wiphy *wiphy = wil_to_wiphy(wil);
	struct wireless_dev *wdev = wil_to_wdev(wil);
	int rc;
	void *frame = kmalloc(len, GFP_KERNEL);
	if (!frame)
		return -ENOMEM;
	if (copy_from_user(frame, buf, len))
		return -EIO;
#if 0
	rc = wmi_set_channel(wil, 1);
	if (rc)
		return rc;
	rc = wmi_call(wil, WMI_RX_ON_CMDID, NULL, 0,
		      WMI_RX_ON_DONE_EVENTID, NULL, 0, 20);
	if (rc)
		return rc;
#endif
	rc = wil_cfg80211_mgmt_tx(wiphy, wdev, wdev->preset_chandef.chan,
				  true, 0, frame,
				  len, true, false, NULL);
	kfree(frame);
	wil_info(wil, "%s() -> %d\n", __func__, rc);
#if 0
	msleep(300);
	rtnl_lock();
	dev_close(ndev);
	ndev->flags &= ~IFF_UP;
	rtnl_unlock();
	wil_reset(wil);
#endif
	return len;
}
Beispiel #17
0
/*
 * Handle link status changes. For RNDIS_STATUS_NETWORK_CHANGE emulate link
 * down/up sequence. In case of RNDIS_STATUS_MEDIA_CONNECT when carrier is
 * present send GARP packet to network peers with netif_notify_peers().
 */
static void netvsc_link_change(struct work_struct *w)
{
	struct net_device_context *ndev_ctx =
		container_of(w, struct net_device_context, dwork.work);
	struct hv_device *device_obj = ndev_ctx->device_ctx;
	struct net_device *net = hv_get_drvdata(device_obj);
	struct netvsc_device *net_device;
	struct rndis_device *rdev;
	struct netvsc_reconfig *event = NULL;
	bool notify = false, reschedule = false;
	unsigned long flags, next_reconfig, delay;

	rtnl_lock();
	if (ndev_ctx->start_remove)
		goto out_unlock;

	net_device = ndev_ctx->nvdev;
	rdev = net_device->extension;

	next_reconfig = ndev_ctx->last_reconfig + LINKCHANGE_INT;
	if (time_is_after_jiffies(next_reconfig)) {
		/* link_watch only sends one notification with current state
		 * per second, avoid doing reconfig more frequently. Handle
		 * wrap around.
		 */
		delay = next_reconfig - jiffies;
		delay = delay < LINKCHANGE_INT ? delay : LINKCHANGE_INT;
		schedule_delayed_work(&ndev_ctx->dwork, delay);
		goto out_unlock;
	}
	ndev_ctx->last_reconfig = jiffies;

	spin_lock_irqsave(&ndev_ctx->lock, flags);
	if (!list_empty(&ndev_ctx->reconfig_events)) {
		event = list_first_entry(&ndev_ctx->reconfig_events,
					 struct netvsc_reconfig, list);
		list_del(&event->list);
		reschedule = !list_empty(&ndev_ctx->reconfig_events);
	}
Beispiel #18
0
static void __exit pxa250_irda_exit(void)
{
	struct net_device *dev = netdev;

	netdev = NULL;
	if (dev) {
		rtnl_lock();
		unregister_netdevice(dev);
		rtnl_unlock();
	}

        release_mem_region(__PREG(ICCR0), 0x1c);

	release_mem_region(__PREG(STRBR), 0x24);

	/*
	 * We now know that the netdevice is no longer in use, and all
	 * references to our driver have been removed.  The only structure
	 * which may still be present is the netdevice, which will get
	 * cleaned up by net/core/dev.c
	 */
}
Beispiel #19
0
static int __init rh_init(void)
{
	int rc = 0, err;
	int i;

	pr_info("rxhook (v%s) is loaded\n", RXHOOK_VERSION);

	rh = kmalloc(sizeof(struct rh_dev), GFP_KERNEL);
	if (rh == 0) {
		pr_info("fail to kmalloc: *rh_dev\n");
		rc = -1;
		goto out;
	}

	rh->dev = dev_get_by_name(&init_net, ifname);
	if (!rh->dev) {
		pr_err("Could not find %s\n", ifname);
		rc = -1;
		goto out;
	}

	rh->cpu = smp_processor_id();
	pr_info("cpuid: %d\n", rh->cpu);

	// register
	rtnl_lock();
	err = netdev_rx_handler_register(rh->dev, rh_handle_frame, rh);
	rtnl_unlock();
	if (err) {
		pr_err("%s failed to register rx_handler\n", ifname);
	}

	for(i = 0; i < 10; i++)
		pps[i] = 0;

out:
	return rc;
}
Beispiel #20
0
/*
 * Send GARP packet to network peers after migrations.
 * After Quick Migration, the network is not immediately operational in the
 * current context when receiving RNDIS_STATUS_MEDIA_CONNECT event. So, add
 * another netif_notify_peers() into a delayed work, otherwise GARP packet
 * will not be sent after quick migration, and cause network disconnection.
 * Also, we update the carrier status here.
 */
static void netvsc_link_change(void *data)
{
	struct delayed_work *w = (struct delayed_work *)data;
	struct net_device_context *ndev_ctx;
	struct net_device *net;
	struct netvsc_device *net_device;
	struct rndis_device *rdev;
	bool notify, refresh = false;
	char *argv[] = { "/etc/init.d/network", "restart", NULL };
	char *envp[] = { "HOME=/", "PATH=/sbin:/usr/sbin:/bin:/usr/bin", NULL };

	rtnl_lock();

	ndev_ctx = container_of(w, struct net_device_context, dwork);
	net_device = hv_get_drvdata(ndev_ctx->device_ctx);
	rdev = net_device->extension;
	net = net_device->ndev;

	if (rdev->link_state) {
		netif_carrier_off(net);
		notify = false;
	} else {
		netif_carrier_on(net);
		notify = true;
		if (rdev->link_change) {
			rdev->link_change = false;
			refresh = true;
		}
	}

	rtnl_unlock();

	if (refresh)
		call_usermodehelper(argv[0], argv, envp, UMH_WAIT_EXEC);

	if (notify)
		netif_notify_peers(net);
}
Beispiel #21
0
int __init teql_init(void)
#endif
{
	int err;

	rtnl_lock();

	the_master.dev.priv = (void*)&the_master;
	err = dev_alloc_name(&the_master.dev, "teql%d");
	if (err < 0)
		return err;
	memcpy(the_master.qops.id, the_master.dev.name, IFNAMSIZ);
	the_master.dev.init = teql_master_init;

	err = register_netdevice(&the_master.dev);
	if (err == 0) {
		err = register_qdisc(&the_master.qops);
		if (err)
			unregister_netdevice(&the_master.dev);
	}
	rtnl_unlock();
	return err;
}
Beispiel #22
0
static int wiphy_suspend(struct device *dev, pm_message_t state)
{
	struct cfg80211_registered_device *rdev = dev_to_rdev(dev);
	int ret = 0;

	rdev->suspend_at = get_seconds();

	rtnl_lock();
	if (rdev->wiphy.registered) {
		if (!rdev->wiphy.wowlan_config)
			cfg80211_leave_all(rdev);
		if (rdev->ops->suspend)
			ret = rdev_suspend(rdev, rdev->wiphy.wowlan_config);
		if (ret == 1) {
			/* Driver refuse to configure wowlan */
			cfg80211_leave_all(rdev);
			ret = rdev_suspend(rdev, NULL);
		}
	}
	rtnl_unlock();

	return ret;
}
Beispiel #23
0
/*
 * Close down an X.25 channel.
 * This means flushing out any pending queues, and then restoring the
 * TTY line discipline to what it was before it got hooked to X.25
 * (which usually is TTY again).
 */
static void x25_asy_close_tty(struct tty_struct *tty)
{
	struct x25_asy *sl = tty->disc_data;
	int err;

	/* First make sure we're connected. */
	if (!sl || sl->magic != X25_ASY_MAGIC)
		return;

	rtnl_lock();
	if (sl->dev->flags & IFF_UP)
		dev_close(sl->dev);
	rtnl_unlock();

	err = lapb_unregister(sl->dev);
	if (err != LAPB_OK)
		pr_err("x25_asy_close: lapb_unregister error: %d\n",
		       err);

	tty->disc_data = NULL;
	sl->tty = NULL;
	x25_asy_free(sl);
}
Beispiel #24
0
static struct vport *gre_tnl_create(const struct vport_parms *parms)
{
	struct net *net = ovs_dp_get_net(parms->dp);
	struct net_device *dev;
	struct vport *vport;

	vport = ovs_vport_alloc(0, &ovs_gre_vport_ops, parms);
	if (IS_ERR(vport))
		return vport;

	rtnl_lock();
	dev = gretap_fb_dev_create(net, parms->name, NET_NAME_USER);
	if (IS_ERR(dev)) {
		rtnl_unlock();
		ovs_vport_free(vport);
		return ERR_CAST(dev);
	}

	dev_change_flags(dev, dev->flags | IFF_UP);
	rtnl_unlock();

	return vport;
}
Beispiel #25
0
static int brc_add_del_port(struct net_device *dev, int port_ifindex, int add)
{
	struct sk_buff *request;
	struct net_device *port;
	int err;

	port = __dev_get_by_index(&init_net, port_ifindex);
	if (!port)
		return -EINVAL;

	/* Save name of dev and port because there's a race between the
	 * rtnl_unlock() and the brc_send_simple_command(). */
	request = brc_make_request(add ? BRC_GENL_C_PORT_ADD : BRC_GENL_C_PORT_DEL,
				   dev->name, port->name);
	if (!request)
		return -ENOMEM;

	rtnl_unlock();
	err = brc_send_simple_command(request);
	rtnl_lock();

	return err;
}
Beispiel #26
0
static void restore_slaves(struct net_device *hsr_dev)
{
	struct hsr_priv *hsr_priv;
	int i;
	int res;

	hsr_priv = netdev_priv(hsr_dev);

	rtnl_lock();

	/* Restore promiscuity */
	for (i = 0; i < HSR_MAX_SLAVE; i++) {
		if (!hsr_priv->slave[i])
			continue;
		res = dev_set_promiscuity(hsr_priv->slave[i], -1);
		if (res)
			netdev_info(hsr_dev,
				    "Cannot restore slave promiscuity (%s, %d)\n",
				    hsr_priv->slave[i]->name, res);
	}

	rtnl_unlock();
}
static ssize_t ieee80211_if_write(
	struct ieee80211_sub_if_data *sdata,
	const char __user *userbuf,
	size_t count, loff_t *ppos,
	ssize_t (*write)(struct ieee80211_sub_if_data *, const char *, int))
{
	char buf[64];
	ssize_t ret;

	if (count >= sizeof(buf))
		return -E2BIG;

	if (copy_from_user(buf, userbuf, count))
		return -EFAULT;
	buf[count] = '\0';

	ret = -ENODEV;
	rtnl_lock();
	ret = (*write)(sdata, buf, count);
	rtnl_unlock();

	return ret;
}
Beispiel #28
0
static ssize_t ieee80211_if_write(
	struct ieee80211_sub_if_data *sdata,
	const char __user *userbuf,
	size_t count, loff_t *ppos,
	ssize_t (*write)(struct ieee80211_sub_if_data *, const char *, int))
{
	u8 *buf;
	ssize_t ret = -ENODEV;

	buf = kzalloc(count, GFP_KERNEL);
	if (!buf)
		return -ENOMEM;

	if (copy_from_user(buf, userbuf, count))
		return -EFAULT;

	rtnl_lock();
	if (sdata->dev->reg_state == NETREG_REGISTERED)
		ret = (*write)(sdata, buf, count);
	rtnl_unlock();

	return ret;
}
static ssize_t set_phy_flash_cfg(struct device *dev,
				 struct device_attribute *attr,
				 const char *buf, size_t count)
{
	struct efx_nic *efx = pci_get_drvdata(to_pci_dev(dev));
	enum efx_phy_mode old_mode, new_mode;
	int err;

	rtnl_lock();
	old_mode = efx->phy_mode;
	if (count == 0 || *buf == '0')
		new_mode = old_mode & ~PHY_MODE_SPECIAL;
	else
		new_mode = PHY_MODE_SPECIAL;
	if (old_mode == new_mode) {
		err = 0;
	} else if (efx->state != STATE_RUNNING || netif_running(efx->net_dev)) {
		err = -EBUSY;
	} else {
		/* Reset the PHY, reconfigure the MAC and enable/disable
		 * MAC stats accordingly. */
		efx->phy_mode = new_mode;
		if (new_mode & PHY_MODE_SPECIAL)
			falcon_stop_nic_stats(efx);
		if (falcon_board(efx)->type->id == FALCON_BOARD_SFE4001)
			err = sfe4001_poweron(efx);
		else
			err = sfn4111t_reset(efx);
		if (!err)
			err = efx_reconfigure_port(efx);
		if (!(new_mode & PHY_MODE_SPECIAL))
			falcon_start_nic_stats(efx);
	}
	rtnl_unlock();

	return err ? err : count;
}
Beispiel #30
0
int ieee802154_disassociate_req(struct sk_buff *skb, struct genl_info *info)
{
	struct net_device *dev;
	struct ieee802154_addr addr;
	int ret = -EOPNOTSUPP;

	if ((!info->attrs[IEEE802154_ATTR_DEST_HW_ADDR] &&
	    !info->attrs[IEEE802154_ATTR_DEST_SHORT_ADDR]) ||
	    !info->attrs[IEEE802154_ATTR_REASON])
		return -EINVAL;

	dev = ieee802154_nl_get_dev(info);
	if (!dev)
		return -ENODEV;
	if (!ieee802154_mlme_ops(dev)->disassoc_req)
		goto out;

	if (info->attrs[IEEE802154_ATTR_DEST_HW_ADDR]) {
		addr.mode = IEEE802154_ADDR_LONG;
		addr.extended_addr = nla_get_hwaddr(
				info->attrs[IEEE802154_ATTR_DEST_HW_ADDR]);
	} else {
		addr.mode = IEEE802154_ADDR_SHORT;
		addr.short_addr = nla_get_shortaddr(
				info->attrs[IEEE802154_ATTR_DEST_SHORT_ADDR]);
	}
	rtnl_lock();
	addr.pan_id = dev->ieee802154_ptr->pan_id;
	rtnl_unlock();

	ret = ieee802154_mlme_ops(dev)->disassoc_req(dev, &addr,
			nla_get_u8(info->attrs[IEEE802154_ATTR_REASON]));

out:
	dev_put(dev);
	return ret;
}