aboutsummaryrefslogtreecommitdiffstats
path: root/net/wireless
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2009-12-04 16:25:15 -0500
committerDavid S. Miller <davem@davemloft.net>2009-12-04 16:25:15 -0500
commit8f56874bd7e8bee73ed6a1cf80dcec2753616262 (patch)
treeaebd15dea662ef5efd89402b8fd92fec540a98eb /net/wireless
parent47e1c323069bcef0acb8a2b48921688573f5ca63 (diff)
parent159bcfeb9123c91f0dc885a42b6387a98192f896 (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6
Diffstat (limited to 'net/wireless')
-rw-r--r--net/wireless/core.c12
-rw-r--r--net/wireless/core.h2
-rw-r--r--net/wireless/ibss.c2
-rw-r--r--net/wireless/nl80211.c120
-rw-r--r--net/wireless/reg.c6
-rw-r--r--net/wireless/scan.c2
-rw-r--r--net/wireless/sme.c6
-rw-r--r--net/wireless/wext-compat.c42
-rw-r--r--net/wireless/wext-core.c3
9 files changed, 185 insertions, 10 deletions
diff --git a/net/wireless/core.c b/net/wireless/core.c
index fe6f402a22af..c2a2c563d21a 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -45,6 +45,9 @@ DEFINE_MUTEX(cfg80211_mutex);
45/* for debugfs */ 45/* for debugfs */
46static struct dentry *ieee80211_debugfs_dir; 46static struct dentry *ieee80211_debugfs_dir;
47 47
48/* for the cleanup, scan and event works */
49struct workqueue_struct *cfg80211_wq;
50
48/* requires cfg80211_mutex to be held! */ 51/* requires cfg80211_mutex to be held! */
49struct cfg80211_registered_device *cfg80211_rdev_by_wiphy_idx(int wiphy_idx) 52struct cfg80211_registered_device *cfg80211_rdev_by_wiphy_idx(int wiphy_idx)
50{ 53{
@@ -727,7 +730,7 @@ static int cfg80211_netdev_notifier_call(struct notifier_block * nb,
727 break; 730 break;
728 case NETDEV_DOWN: 731 case NETDEV_DOWN:
729 dev_hold(dev); 732 dev_hold(dev);
730 schedule_work(&wdev->cleanup_work); 733 queue_work(cfg80211_wq, &wdev->cleanup_work);
731 break; 734 break;
732 case NETDEV_UP: 735 case NETDEV_UP:
733 /* 736 /*
@@ -845,8 +848,14 @@ static int __init cfg80211_init(void)
845 if (err) 848 if (err)
846 goto out_fail_reg; 849 goto out_fail_reg;
847 850
851 cfg80211_wq = create_singlethread_workqueue("cfg80211");
852 if (!cfg80211_wq)
853 goto out_fail_wq;
854
848 return 0; 855 return 0;
849 856
857out_fail_wq:
858 regulatory_exit();
850out_fail_reg: 859out_fail_reg:
851 debugfs_remove(ieee80211_debugfs_dir); 860 debugfs_remove(ieee80211_debugfs_dir);
852out_fail_nl80211: 861out_fail_nl80211:
@@ -868,5 +877,6 @@ static void cfg80211_exit(void)
868 wiphy_sysfs_exit(); 877 wiphy_sysfs_exit();
869 regulatory_exit(); 878 regulatory_exit();
870 unregister_pernet_device(&cfg80211_pernet_ops); 879 unregister_pernet_device(&cfg80211_pernet_ops);
880 destroy_workqueue(cfg80211_wq);
871} 881}
872module_exit(cfg80211_exit); 882module_exit(cfg80211_exit);
diff --git a/net/wireless/core.h b/net/wireless/core.h
index a9db9e6255bb..4ef3efc94106 100644
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
@@ -91,6 +91,8 @@ bool wiphy_idx_valid(int wiphy_idx)
91 return (wiphy_idx >= 0); 91 return (wiphy_idx >= 0);
92} 92}
93 93
94
95extern struct workqueue_struct *cfg80211_wq;
94extern struct mutex cfg80211_mutex; 96extern struct mutex cfg80211_mutex;
95extern struct list_head cfg80211_rdev_list; 97extern struct list_head cfg80211_rdev_list;
96extern int cfg80211_rdev_list_generation; 98extern int cfg80211_rdev_list_generation;
diff --git a/net/wireless/ibss.c b/net/wireless/ibss.c
index 34dfc93fa713..6ef5a491fb4b 100644
--- a/net/wireless/ibss.c
+++ b/net/wireless/ibss.c
@@ -70,7 +70,7 @@ void cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid, gfp_t gfp)
70 spin_lock_irqsave(&wdev->event_lock, flags); 70 spin_lock_irqsave(&wdev->event_lock, flags);
71 list_add_tail(&ev->list, &wdev->event_list); 71 list_add_tail(&ev->list, &wdev->event_list);
72 spin_unlock_irqrestore(&wdev->event_lock, flags); 72 spin_unlock_irqrestore(&wdev->event_lock, flags);
73 schedule_work(&rdev->event_work); 73 queue_work(cfg80211_wq, &rdev->event_work);
74} 74}
75EXPORT_SYMBOL(cfg80211_ibss_joined); 75EXPORT_SYMBOL(cfg80211_ibss_joined);
76 76
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 149539ade15e..a6028433e3a0 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -139,6 +139,8 @@ static struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] __read_mostly = {
139 [NL80211_ATTR_WPA_VERSIONS] = { .type = NLA_U32 }, 139 [NL80211_ATTR_WPA_VERSIONS] = { .type = NLA_U32 },
140 [NL80211_ATTR_PID] = { .type = NLA_U32 }, 140 [NL80211_ATTR_PID] = { .type = NLA_U32 },
141 [NL80211_ATTR_4ADDR] = { .type = NLA_U8 }, 141 [NL80211_ATTR_4ADDR] = { .type = NLA_U8 },
142 [NL80211_ATTR_PMKID] = { .type = NLA_BINARY,
143 .len = WLAN_PMKID_LEN },
142}; 144};
143 145
144/* policy for the attributes */ 146/* policy for the attributes */
@@ -450,6 +452,9 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
450 sizeof(u32) * dev->wiphy.n_cipher_suites, 452 sizeof(u32) * dev->wiphy.n_cipher_suites,
451 dev->wiphy.cipher_suites); 453 dev->wiphy.cipher_suites);
452 454
455 NLA_PUT_U8(msg, NL80211_ATTR_MAX_NUM_PMKIDS,
456 dev->wiphy.max_num_pmkids);
457
453 nl_modes = nla_nest_start(msg, NL80211_ATTR_SUPPORTED_IFTYPES); 458 nl_modes = nla_nest_start(msg, NL80211_ATTR_SUPPORTED_IFTYPES);
454 if (!nl_modes) 459 if (!nl_modes)
455 goto nla_put_failure; 460 goto nla_put_failure;
@@ -561,6 +566,9 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
561 CMD(deauth, DEAUTHENTICATE); 566 CMD(deauth, DEAUTHENTICATE);
562 CMD(disassoc, DISASSOCIATE); 567 CMD(disassoc, DISASSOCIATE);
563 CMD(join_ibss, JOIN_IBSS); 568 CMD(join_ibss, JOIN_IBSS);
569 CMD(set_pmksa, SET_PMKSA);
570 CMD(del_pmksa, DEL_PMKSA);
571 CMD(flush_pmksa, FLUSH_PMKSA);
564 if (dev->wiphy.flags & WIPHY_FLAG_NETNS_OK) { 572 if (dev->wiphy.flags & WIPHY_FLAG_NETNS_OK) {
565 i++; 573 i++;
566 NLA_PUT_U32(msg, i, NL80211_CMD_SET_WIPHY_NETNS); 574 NLA_PUT_U32(msg, i, NL80211_CMD_SET_WIPHY_NETNS);
@@ -4221,6 +4229,99 @@ static int nl80211_wiphy_netns(struct sk_buff *skb, struct genl_info *info)
4221 return err; 4229 return err;
4222} 4230}
4223 4231
4232static int nl80211_setdel_pmksa(struct sk_buff *skb, struct genl_info *info)
4233{
4234 struct cfg80211_registered_device *rdev;
4235 int (*rdev_ops)(struct wiphy *wiphy, struct net_device *dev,
4236 struct cfg80211_pmksa *pmksa) = NULL;
4237 int err;
4238 struct net_device *dev;
4239 struct cfg80211_pmksa pmksa;
4240
4241 memset(&pmksa, 0, sizeof(struct cfg80211_pmksa));
4242
4243 if (!info->attrs[NL80211_ATTR_MAC])
4244 return -EINVAL;
4245
4246 if (!info->attrs[NL80211_ATTR_PMKID])
4247 return -EINVAL;
4248
4249 rtnl_lock();
4250
4251 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
4252 if (err)
4253 goto out_rtnl;
4254
4255 pmksa.pmkid = nla_data(info->attrs[NL80211_ATTR_PMKID]);
4256 pmksa.bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
4257
4258 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION) {
4259 err = -EOPNOTSUPP;
4260 goto out;
4261 }
4262
4263 switch (info->genlhdr->cmd) {
4264 case NL80211_CMD_SET_PMKSA:
4265 rdev_ops = rdev->ops->set_pmksa;
4266 break;
4267 case NL80211_CMD_DEL_PMKSA:
4268 rdev_ops = rdev->ops->del_pmksa;
4269 break;
4270 default:
4271 WARN_ON(1);
4272 break;
4273 }
4274
4275 if (!rdev_ops) {
4276 err = -EOPNOTSUPP;
4277 goto out;
4278 }
4279
4280 err = rdev_ops(&rdev->wiphy, dev, &pmksa);
4281
4282 out:
4283 cfg80211_unlock_rdev(rdev);
4284 dev_put(dev);
4285 out_rtnl:
4286 rtnl_unlock();
4287
4288 return err;
4289}
4290
4291static int nl80211_flush_pmksa(struct sk_buff *skb, struct genl_info *info)
4292{
4293 struct cfg80211_registered_device *rdev;
4294 int err;
4295 struct net_device *dev;
4296
4297 rtnl_lock();
4298
4299 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
4300 if (err)
4301 goto out_rtnl;
4302
4303 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION) {
4304 err = -EOPNOTSUPP;
4305 goto out;
4306 }
4307
4308 if (!rdev->ops->flush_pmksa) {
4309 err = -EOPNOTSUPP;
4310 goto out;
4311 }
4312
4313 err = rdev->ops->flush_pmksa(&rdev->wiphy, dev);
4314
4315 out:
4316 cfg80211_unlock_rdev(rdev);
4317 dev_put(dev);
4318 out_rtnl:
4319 rtnl_unlock();
4320
4321 return err;
4322
4323}
4324
4224static struct genl_ops nl80211_ops[] = { 4325static struct genl_ops nl80211_ops[] = {
4225 { 4326 {
4226 .cmd = NL80211_CMD_GET_WIPHY, 4327 .cmd = NL80211_CMD_GET_WIPHY,
@@ -4465,6 +4566,25 @@ static struct genl_ops nl80211_ops[] = {
4465 .policy = nl80211_policy, 4566 .policy = nl80211_policy,
4466 .dumpit = nl80211_dump_survey, 4567 .dumpit = nl80211_dump_survey,
4467 }, 4568 },
4569 {
4570 .cmd = NL80211_CMD_SET_PMKSA,
4571 .doit = nl80211_setdel_pmksa,
4572 .policy = nl80211_policy,
4573 .flags = GENL_ADMIN_PERM,
4574 },
4575 {
4576 .cmd = NL80211_CMD_DEL_PMKSA,
4577 .doit = nl80211_setdel_pmksa,
4578 .policy = nl80211_policy,
4579 .flags = GENL_ADMIN_PERM,
4580 },
4581 {
4582 .cmd = NL80211_CMD_FLUSH_PMKSA,
4583 .doit = nl80211_flush_pmksa,
4584 .policy = nl80211_policy,
4585 .flags = GENL_ADMIN_PERM,
4586 },
4587
4468}; 4588};
4469static struct genl_multicast_group nl80211_mlme_mcgrp = { 4589static struct genl_multicast_group nl80211_mlme_mcgrp = {
4470 .name = "mlme", 4590 .name = "mlme",
diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index 1f33017737fd..c01470e7de15 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -1931,7 +1931,7 @@ static void print_rd_rules(const struct ieee80211_regdomain *rd)
1931 const struct ieee80211_freq_range *freq_range = NULL; 1931 const struct ieee80211_freq_range *freq_range = NULL;
1932 const struct ieee80211_power_rule *power_rule = NULL; 1932 const struct ieee80211_power_rule *power_rule = NULL;
1933 1933
1934 printk(KERN_INFO "\t(start_freq - end_freq @ bandwidth), " 1934 printk(KERN_INFO " (start_freq - end_freq @ bandwidth), "
1935 "(max_antenna_gain, max_eirp)\n"); 1935 "(max_antenna_gain, max_eirp)\n");
1936 1936
1937 for (i = 0; i < rd->n_reg_rules; i++) { 1937 for (i = 0; i < rd->n_reg_rules; i++) {
@@ -1944,7 +1944,7 @@ static void print_rd_rules(const struct ieee80211_regdomain *rd)
1944 * in certain regions 1944 * in certain regions
1945 */ 1945 */
1946 if (power_rule->max_antenna_gain) 1946 if (power_rule->max_antenna_gain)
1947 printk(KERN_INFO "\t(%d KHz - %d KHz @ %d KHz), " 1947 printk(KERN_INFO " (%d KHz - %d KHz @ %d KHz), "
1948 "(%d mBi, %d mBm)\n", 1948 "(%d mBi, %d mBm)\n",
1949 freq_range->start_freq_khz, 1949 freq_range->start_freq_khz,
1950 freq_range->end_freq_khz, 1950 freq_range->end_freq_khz,
@@ -1952,7 +1952,7 @@ static void print_rd_rules(const struct ieee80211_regdomain *rd)
1952 power_rule->max_antenna_gain, 1952 power_rule->max_antenna_gain,
1953 power_rule->max_eirp); 1953 power_rule->max_eirp);
1954 else 1954 else
1955 printk(KERN_INFO "\t(%d KHz - %d KHz @ %d KHz), " 1955 printk(KERN_INFO " (%d KHz - %d KHz @ %d KHz), "
1956 "(N/A, %d mBm)\n", 1956 "(N/A, %d mBm)\n",
1957 freq_range->start_freq_khz, 1957 freq_range->start_freq_khz,
1958 freq_range->end_freq_khz, 1958 freq_range->end_freq_khz,
diff --git a/net/wireless/scan.c b/net/wireless/scan.c
index 96df34c3c6ee..12dfa62aad18 100644
--- a/net/wireless/scan.c
+++ b/net/wireless/scan.c
@@ -88,7 +88,7 @@ void cfg80211_scan_done(struct cfg80211_scan_request *request, bool aborted)
88 WARN_ON(request != wiphy_to_dev(request->wiphy)->scan_req); 88 WARN_ON(request != wiphy_to_dev(request->wiphy)->scan_req);
89 89
90 request->aborted = aborted; 90 request->aborted = aborted;
91 schedule_work(&wiphy_to_dev(request->wiphy)->scan_done_wk); 91 queue_work(cfg80211_wq, &wiphy_to_dev(request->wiphy)->scan_done_wk);
92} 92}
93EXPORT_SYMBOL(cfg80211_scan_done); 93EXPORT_SYMBOL(cfg80211_scan_done);
94 94
diff --git a/net/wireless/sme.c b/net/wireless/sme.c
index 0115d07d2c1a..2333d78187e4 100644
--- a/net/wireless/sme.c
+++ b/net/wireless/sme.c
@@ -488,7 +488,7 @@ void cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
488 spin_lock_irqsave(&wdev->event_lock, flags); 488 spin_lock_irqsave(&wdev->event_lock, flags);
489 list_add_tail(&ev->list, &wdev->event_list); 489 list_add_tail(&ev->list, &wdev->event_list);
490 spin_unlock_irqrestore(&wdev->event_lock, flags); 490 spin_unlock_irqrestore(&wdev->event_lock, flags);
491 schedule_work(&rdev->event_work); 491 queue_work(cfg80211_wq, &rdev->event_work);
492} 492}
493EXPORT_SYMBOL(cfg80211_connect_result); 493EXPORT_SYMBOL(cfg80211_connect_result);
494 494
@@ -583,7 +583,7 @@ void cfg80211_roamed(struct net_device *dev, const u8 *bssid,
583 spin_lock_irqsave(&wdev->event_lock, flags); 583 spin_lock_irqsave(&wdev->event_lock, flags);
584 list_add_tail(&ev->list, &wdev->event_list); 584 list_add_tail(&ev->list, &wdev->event_list);
585 spin_unlock_irqrestore(&wdev->event_lock, flags); 585 spin_unlock_irqrestore(&wdev->event_lock, flags);
586 schedule_work(&rdev->event_work); 586 queue_work(cfg80211_wq, &rdev->event_work);
587} 587}
588EXPORT_SYMBOL(cfg80211_roamed); 588EXPORT_SYMBOL(cfg80211_roamed);
589 589
@@ -681,7 +681,7 @@ void cfg80211_disconnected(struct net_device *dev, u16 reason,
681 spin_lock_irqsave(&wdev->event_lock, flags); 681 spin_lock_irqsave(&wdev->event_lock, flags);
682 list_add_tail(&ev->list, &wdev->event_list); 682 list_add_tail(&ev->list, &wdev->event_list);
683 spin_unlock_irqrestore(&wdev->event_lock, flags); 683 spin_unlock_irqrestore(&wdev->event_lock, flags);
684 schedule_work(&rdev->event_work); 684 queue_work(cfg80211_wq, &rdev->event_work);
685} 685}
686EXPORT_SYMBOL(cfg80211_disconnected); 686EXPORT_SYMBOL(cfg80211_disconnected);
687 687
diff --git a/net/wireless/wext-compat.c b/net/wireless/wext-compat.c
index 29091ac9f989..584eb4826e02 100644
--- a/net/wireless/wext-compat.c
+++ b/net/wireless/wext-compat.c
@@ -1401,6 +1401,47 @@ int cfg80211_wext_giwessid(struct net_device *dev,
1401} 1401}
1402EXPORT_SYMBOL_GPL(cfg80211_wext_giwessid); 1402EXPORT_SYMBOL_GPL(cfg80211_wext_giwessid);
1403 1403
1404int cfg80211_wext_siwpmksa(struct net_device *dev,
1405 struct iw_request_info *info,
1406 struct iw_point *data, char *extra)
1407{
1408 struct wireless_dev *wdev = dev->ieee80211_ptr;
1409 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
1410 struct cfg80211_pmksa cfg_pmksa;
1411 struct iw_pmksa *pmksa = (struct iw_pmksa *)extra;
1412
1413 memset(&cfg_pmksa, 0, sizeof(struct cfg80211_pmksa));
1414
1415 if (wdev->iftype != NL80211_IFTYPE_STATION)
1416 return -EINVAL;
1417
1418 cfg_pmksa.bssid = pmksa->bssid.sa_data;
1419 cfg_pmksa.pmkid = pmksa->pmkid;
1420
1421 switch (pmksa->cmd) {
1422 case IW_PMKSA_ADD:
1423 if (!rdev->ops->set_pmksa)
1424 return -EOPNOTSUPP;
1425
1426 return rdev->ops->set_pmksa(&rdev->wiphy, dev, &cfg_pmksa);
1427
1428 case IW_PMKSA_REMOVE:
1429 if (!rdev->ops->del_pmksa)
1430 return -EOPNOTSUPP;
1431
1432 return rdev->ops->del_pmksa(&rdev->wiphy, dev, &cfg_pmksa);
1433
1434 case IW_PMKSA_FLUSH:
1435 if (!rdev->ops->flush_pmksa)
1436 return -EOPNOTSUPP;
1437
1438 return rdev->ops->flush_pmksa(&rdev->wiphy, dev);
1439
1440 default:
1441 return -EOPNOTSUPP;
1442 }
1443}
1444
1404static const iw_handler cfg80211_handlers[] = { 1445static const iw_handler cfg80211_handlers[] = {
1405 [IW_IOCTL_IDX(SIOCGIWNAME)] = (iw_handler) cfg80211_wext_giwname, 1446 [IW_IOCTL_IDX(SIOCGIWNAME)] = (iw_handler) cfg80211_wext_giwname,
1406 [IW_IOCTL_IDX(SIOCSIWFREQ)] = (iw_handler) cfg80211_wext_siwfreq, 1447 [IW_IOCTL_IDX(SIOCSIWFREQ)] = (iw_handler) cfg80211_wext_siwfreq,
@@ -1433,6 +1474,7 @@ static const iw_handler cfg80211_handlers[] = {
1433 [IW_IOCTL_IDX(SIOCSIWAUTH)] = (iw_handler) cfg80211_wext_siwauth, 1474 [IW_IOCTL_IDX(SIOCSIWAUTH)] = (iw_handler) cfg80211_wext_siwauth,
1434 [IW_IOCTL_IDX(SIOCGIWAUTH)] = (iw_handler) cfg80211_wext_giwauth, 1475 [IW_IOCTL_IDX(SIOCGIWAUTH)] = (iw_handler) cfg80211_wext_giwauth,
1435 [IW_IOCTL_IDX(SIOCSIWENCODEEXT)]= (iw_handler) cfg80211_wext_siwencodeext, 1476 [IW_IOCTL_IDX(SIOCSIWENCODEEXT)]= (iw_handler) cfg80211_wext_siwencodeext,
1477 [IW_IOCTL_IDX(SIOCSIWPMKSA)] = (iw_handler) cfg80211_wext_siwpmksa,
1436}; 1478};
1437 1479
1438const struct iw_handler_def cfg80211_wext_handler = { 1480const struct iw_handler_def cfg80211_wext_handler = {
diff --git a/net/wireless/wext-core.c b/net/wireless/wext-core.c
index 58dfb954974a..5e1656bdf23b 100644
--- a/net/wireless/wext-core.c
+++ b/net/wireless/wext-core.c
@@ -802,7 +802,8 @@ static int ioctl_standard_iw_point(struct iw_point *iwp, unsigned int cmd,
802 } 802 }
803 803
804 /* Generate an event to notify listeners of the change */ 804 /* Generate an event to notify listeners of the change */
805 if ((descr->flags & IW_DESCR_FLAG_EVENT) && err == -EIWCOMMIT) { 805 if ((descr->flags & IW_DESCR_FLAG_EVENT) &&
806 ((err == 0) || (err == -EIWCOMMIT))) {
806 union iwreq_data *data = (union iwreq_data *) iwp; 807 union iwreq_data *data = (union iwreq_data *) iwp;
807 808
808 if (descr->flags & IW_DESCR_FLAG_RESTRICT) 809 if (descr->flags & IW_DESCR_FLAG_RESTRICT)