#include <linux/device.h>
#include <linux/etherdevice.h>
#include <linux/rtnetlink.h>
+#include <linux/sched.h>
#include <net/genetlink.h>
#include <net/cfg80211.h>
#include "nl80211.h"
#include "sysfs.h"
#include "debugfs.h"
#include "wext-compat.h"
+#include "ethtool.h"
/* name for sysfs, %d is appended */
#define PHY_NAME "phy"
/* for debugfs */
static struct dentry *ieee80211_debugfs_dir;
+/* for the cleanup, scan and event works */
+struct workqueue_struct *cfg80211_wq;
+
/* requires cfg80211_mutex to be held! */
struct cfg80211_registered_device *cfg80211_rdev_by_wiphy_idx(int wiphy_idx)
{
struct wireless_dev *wdev;
int err = 0;
- if (!rdev->wiphy.netnsok)
+ if (!(rdev->wiphy.flags & WIPHY_FLAG_NETNS_OK))
return -EOPNOTSUPP;
list_for_each_entry(wdev, &rdev->netdev_list, list) {
rdev->wiphy.dev.class = &ieee80211_class;
rdev->wiphy.dev.platform_data = rdev;
- rdev->wiphy.ps_default = CONFIG_CFG80211_DEFAULT_PS_VALUE;
+#ifdef CONFIG_CFG80211_DEFAULT_PS
+ rdev->wiphy.flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT;
+#endif
wiphy_net_set(&rdev->wiphy, &init_net);
if (IS_ERR(rdev->wiphy.debugfsdir))
rdev->wiphy.debugfsdir = NULL;
- if (wiphy->custom_regulatory) {
+ if (wiphy->flags & WIPHY_FLAG_CUSTOM_REGULATORY) {
struct regulatory_request request;
request.wiphy_idx = get_wiphy_idx(wiphy);
* First remove the hardware from everywhere, this makes
* it impossible to find from userspace.
*/
- cfg80211_debugfs_rdev_del(rdev);
+ debugfs_remove_recursive(rdev->wiphy.debugfsdir);
list_del(&rdev->list);
/*
cfg80211_rdev_list_generation++;
device_del(&rdev->wiphy.dev);
- debugfs_remove(rdev->wiphy.debugfsdir);
mutex_unlock(&cfg80211_mutex);
wdev->wext.default_key = -1;
wdev->wext.default_mgmt_key = -1;
wdev->wext.connect.auth_type = NL80211_AUTHTYPE_AUTOMATIC;
- wdev->wext.ps = wdev->wiphy->ps_default;
+ if (wdev->wiphy->flags & WIPHY_FLAG_PS_ON_BY_DEFAULT)
+ wdev->wext.ps = true;
+ else
+ wdev->wext.ps = false;
wdev->wext.ps_timeout = 100;
if (rdev->ops->set_power_mgmt)
if (rdev->ops->set_power_mgmt(wdev->wiphy, dev,
wdev->wext.ps = false;
}
#endif
+ if (!dev->ethtool_ops)
+ dev->ethtool_ops = &cfg80211_ethtool_ops;
+
+ if ((wdev->iftype == NL80211_IFTYPE_STATION ||
+ wdev->iftype == NL80211_IFTYPE_ADHOC) && !wdev->use_4addr)
+ dev->priv_flags |= IFF_DONT_BRIDGE;
break;
case NETDEV_GOING_DOWN:
switch (wdev->iftype) {
break;
case NETDEV_DOWN:
dev_hold(dev);
- schedule_work(&wdev->cleanup_work);
+ queue_work(cfg80211_wq, &wdev->cleanup_work);
break;
case NETDEV_UP:
/*
mutex_unlock(&rdev->devlist_mtx);
dev_put(dev);
}
-#ifdef CONFIG_CFG80211_WEXT
cfg80211_lock_rdev(rdev);
mutex_lock(&rdev->devlist_mtx);
+#ifdef CONFIG_CFG80211_WEXT
wdev_lock(wdev);
switch (wdev->iftype) {
case NL80211_IFTYPE_ADHOC:
break;
}
wdev_unlock(wdev);
+#endif
rdev->opencount++;
mutex_unlock(&rdev->devlist_mtx);
cfg80211_unlock_rdev(rdev);
-#endif
break;
case NETDEV_UNREGISTER:
/*
if (err)
goto out_fail_reg;
+ cfg80211_wq = create_singlethread_workqueue("cfg80211");
+ if (!cfg80211_wq)
+ goto out_fail_wq;
+
return 0;
+out_fail_wq:
+ regulatory_exit();
out_fail_reg:
debugfs_remove(ieee80211_debugfs_dir);
out_fail_nl80211:
wiphy_sysfs_exit();
regulatory_exit();
unregister_pernet_device(&cfg80211_pernet_ops);
+ destroy_workqueue(cfg80211_wq);
}
module_exit(cfg80211_exit);