diff options
author | David S. Miller <davem@davemloft.net> | 2009-06-20 04:16:40 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-06-20 04:16:40 -0400 |
commit | c3da63f35773b04e885c5659e560d5c521d2682e (patch) | |
tree | 5e876e7587f299cadce0b53bfaf912fb28d8283d /net | |
parent | 73e42897e8e5619eacb787d2ce69be12f47cfc21 (diff) | |
parent | a97f4424fb4cddecf9b13c9b0e3f79924b624a7f (diff) |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6
Diffstat (limited to 'net')
-rw-r--r-- | net/rfkill/core.c | 56 | ||||
-rw-r--r-- | net/wireless/nl80211.c | 95 |
2 files changed, 118 insertions, 33 deletions
diff --git a/net/rfkill/core.c b/net/rfkill/core.c index 4e68ab439d5d..79693fe2001e 100644 --- a/net/rfkill/core.c +++ b/net/rfkill/core.c | |||
@@ -56,7 +56,6 @@ struct rfkill { | |||
56 | u32 idx; | 56 | u32 idx; |
57 | 57 | ||
58 | bool registered; | 58 | bool registered; |
59 | bool suspended; | ||
60 | bool persistent; | 59 | bool persistent; |
61 | 60 | ||
62 | const struct rfkill_ops *ops; | 61 | const struct rfkill_ops *ops; |
@@ -224,7 +223,7 @@ static void rfkill_send_events(struct rfkill *rfkill, enum rfkill_operation op) | |||
224 | 223 | ||
225 | static void rfkill_event(struct rfkill *rfkill) | 224 | static void rfkill_event(struct rfkill *rfkill) |
226 | { | 225 | { |
227 | if (!rfkill->registered || rfkill->suspended) | 226 | if (!rfkill->registered) |
228 | return; | 227 | return; |
229 | 228 | ||
230 | kobject_uevent(&rfkill->dev.kobj, KOBJ_CHANGE); | 229 | kobject_uevent(&rfkill->dev.kobj, KOBJ_CHANGE); |
@@ -270,6 +269,9 @@ static void rfkill_set_block(struct rfkill *rfkill, bool blocked) | |||
270 | unsigned long flags; | 269 | unsigned long flags; |
271 | int err; | 270 | int err; |
272 | 271 | ||
272 | if (unlikely(rfkill->dev.power.power_state.event & PM_EVENT_SLEEP)) | ||
273 | return; | ||
274 | |||
273 | /* | 275 | /* |
274 | * Some platforms (...!) generate input events which affect the | 276 | * Some platforms (...!) generate input events which affect the |
275 | * _hard_ kill state -- whenever something tries to change the | 277 | * _hard_ kill state -- whenever something tries to change the |
@@ -292,9 +294,6 @@ static void rfkill_set_block(struct rfkill *rfkill, bool blocked) | |||
292 | rfkill->state |= RFKILL_BLOCK_SW_SETCALL; | 294 | rfkill->state |= RFKILL_BLOCK_SW_SETCALL; |
293 | spin_unlock_irqrestore(&rfkill->lock, flags); | 295 | spin_unlock_irqrestore(&rfkill->lock, flags); |
294 | 296 | ||
295 | if (unlikely(rfkill->dev.power.power_state.event & PM_EVENT_SLEEP)) | ||
296 | return; | ||
297 | |||
298 | err = rfkill->ops->set_block(rfkill->data, blocked); | 297 | err = rfkill->ops->set_block(rfkill->data, blocked); |
299 | 298 | ||
300 | spin_lock_irqsave(&rfkill->lock, flags); | 299 | spin_lock_irqsave(&rfkill->lock, flags); |
@@ -508,19 +507,32 @@ bool rfkill_set_sw_state(struct rfkill *rfkill, bool blocked) | |||
508 | blocked = blocked || hwblock; | 507 | blocked = blocked || hwblock; |
509 | spin_unlock_irqrestore(&rfkill->lock, flags); | 508 | spin_unlock_irqrestore(&rfkill->lock, flags); |
510 | 509 | ||
511 | if (!rfkill->registered) { | 510 | if (!rfkill->registered) |
512 | rfkill->persistent = true; | 511 | return blocked; |
513 | } else { | ||
514 | if (prev != blocked && !hwblock) | ||
515 | schedule_work(&rfkill->uevent_work); | ||
516 | 512 | ||
517 | rfkill_led_trigger_event(rfkill); | 513 | if (prev != blocked && !hwblock) |
518 | } | 514 | schedule_work(&rfkill->uevent_work); |
515 | |||
516 | rfkill_led_trigger_event(rfkill); | ||
519 | 517 | ||
520 | return blocked; | 518 | return blocked; |
521 | } | 519 | } |
522 | EXPORT_SYMBOL(rfkill_set_sw_state); | 520 | EXPORT_SYMBOL(rfkill_set_sw_state); |
523 | 521 | ||
522 | void rfkill_init_sw_state(struct rfkill *rfkill, bool blocked) | ||
523 | { | ||
524 | unsigned long flags; | ||
525 | |||
526 | BUG_ON(!rfkill); | ||
527 | BUG_ON(rfkill->registered); | ||
528 | |||
529 | spin_lock_irqsave(&rfkill->lock, flags); | ||
530 | __rfkill_set_sw_state(rfkill, blocked); | ||
531 | rfkill->persistent = true; | ||
532 | spin_unlock_irqrestore(&rfkill->lock, flags); | ||
533 | } | ||
534 | EXPORT_SYMBOL(rfkill_init_sw_state); | ||
535 | |||
524 | void rfkill_set_states(struct rfkill *rfkill, bool sw, bool hw) | 536 | void rfkill_set_states(struct rfkill *rfkill, bool sw, bool hw) |
525 | { | 537 | { |
526 | unsigned long flags; | 538 | unsigned long flags; |
@@ -598,6 +610,15 @@ static ssize_t rfkill_idx_show(struct device *dev, | |||
598 | return sprintf(buf, "%d\n", rfkill->idx); | 610 | return sprintf(buf, "%d\n", rfkill->idx); |
599 | } | 611 | } |
600 | 612 | ||
613 | static ssize_t rfkill_persistent_show(struct device *dev, | ||
614 | struct device_attribute *attr, | ||
615 | char *buf) | ||
616 | { | ||
617 | struct rfkill *rfkill = to_rfkill(dev); | ||
618 | |||
619 | return sprintf(buf, "%d\n", rfkill->persistent); | ||
620 | } | ||
621 | |||
601 | static u8 user_state_from_blocked(unsigned long state) | 622 | static u8 user_state_from_blocked(unsigned long state) |
602 | { | 623 | { |
603 | if (state & RFKILL_BLOCK_HW) | 624 | if (state & RFKILL_BLOCK_HW) |
@@ -656,6 +677,7 @@ static struct device_attribute rfkill_dev_attrs[] = { | |||
656 | __ATTR(name, S_IRUGO, rfkill_name_show, NULL), | 677 | __ATTR(name, S_IRUGO, rfkill_name_show, NULL), |
657 | __ATTR(type, S_IRUGO, rfkill_type_show, NULL), | 678 | __ATTR(type, S_IRUGO, rfkill_type_show, NULL), |
658 | __ATTR(index, S_IRUGO, rfkill_idx_show, NULL), | 679 | __ATTR(index, S_IRUGO, rfkill_idx_show, NULL), |
680 | __ATTR(persistent, S_IRUGO, rfkill_persistent_show, NULL), | ||
659 | __ATTR(state, S_IRUGO|S_IWUSR, rfkill_state_show, rfkill_state_store), | 681 | __ATTR(state, S_IRUGO|S_IWUSR, rfkill_state_show, rfkill_state_store), |
660 | __ATTR(claim, S_IRUGO|S_IWUSR, rfkill_claim_show, rfkill_claim_store), | 682 | __ATTR(claim, S_IRUGO|S_IWUSR, rfkill_claim_show, rfkill_claim_store), |
661 | __ATTR_NULL | 683 | __ATTR_NULL |
@@ -718,8 +740,6 @@ static int rfkill_suspend(struct device *dev, pm_message_t state) | |||
718 | 740 | ||
719 | rfkill_pause_polling(rfkill); | 741 | rfkill_pause_polling(rfkill); |
720 | 742 | ||
721 | rfkill->suspended = true; | ||
722 | |||
723 | return 0; | 743 | return 0; |
724 | } | 744 | } |
725 | 745 | ||
@@ -728,10 +748,10 @@ static int rfkill_resume(struct device *dev) | |||
728 | struct rfkill *rfkill = to_rfkill(dev); | 748 | struct rfkill *rfkill = to_rfkill(dev); |
729 | bool cur; | 749 | bool cur; |
730 | 750 | ||
731 | cur = !!(rfkill->state & RFKILL_BLOCK_SW); | 751 | if (!rfkill->persistent) { |
732 | rfkill_set_block(rfkill, cur); | 752 | cur = !!(rfkill->state & RFKILL_BLOCK_SW); |
733 | 753 | rfkill_set_block(rfkill, cur); | |
734 | rfkill->suspended = false; | 754 | } |
735 | 755 | ||
736 | rfkill_resume_polling(rfkill); | 756 | rfkill_resume_polling(rfkill); |
737 | 757 | ||
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 24168560ebae..241bddd0b4f1 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c | |||
@@ -1687,13 +1687,52 @@ static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info) | |||
1687 | if (err) | 1687 | if (err) |
1688 | goto out_rtnl; | 1688 | goto out_rtnl; |
1689 | 1689 | ||
1690 | if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP && | 1690 | err = get_vlan(info->attrs[NL80211_ATTR_STA_VLAN], drv, ¶ms.vlan); |
1691 | dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN) { | 1691 | if (err) |
1692 | err = -EINVAL; | ||
1693 | goto out; | 1692 | goto out; |
1693 | |||
1694 | /* validate settings */ | ||
1695 | err = 0; | ||
1696 | |||
1697 | switch (dev->ieee80211_ptr->iftype) { | ||
1698 | case NL80211_IFTYPE_AP: | ||
1699 | case NL80211_IFTYPE_AP_VLAN: | ||
1700 | /* disallow mesh-specific things */ | ||
1701 | if (params.plink_action) | ||
1702 | err = -EINVAL; | ||
1703 | break; | ||
1704 | case NL80211_IFTYPE_STATION: | ||
1705 | /* disallow everything but AUTHORIZED flag */ | ||
1706 | if (params.plink_action) | ||
1707 | err = -EINVAL; | ||
1708 | if (params.vlan) | ||
1709 | err = -EINVAL; | ||
1710 | if (params.supported_rates) | ||
1711 | err = -EINVAL; | ||
1712 | if (params.ht_capa) | ||
1713 | err = -EINVAL; | ||
1714 | if (params.listen_interval >= 0) | ||
1715 | err = -EINVAL; | ||
1716 | if (params.sta_flags_mask & ~BIT(NL80211_STA_FLAG_AUTHORIZED)) | ||
1717 | err = -EINVAL; | ||
1718 | break; | ||
1719 | case NL80211_IFTYPE_MESH_POINT: | ||
1720 | /* disallow things mesh doesn't support */ | ||
1721 | if (params.vlan) | ||
1722 | err = -EINVAL; | ||
1723 | if (params.ht_capa) | ||
1724 | err = -EINVAL; | ||
1725 | if (params.listen_interval >= 0) | ||
1726 | err = -EINVAL; | ||
1727 | if (params.supported_rates) | ||
1728 | err = -EINVAL; | ||
1729 | if (params.sta_flags_mask) | ||
1730 | err = -EINVAL; | ||
1731 | break; | ||
1732 | default: | ||
1733 | err = -EINVAL; | ||
1694 | } | 1734 | } |
1695 | 1735 | ||
1696 | err = get_vlan(info->attrs[NL80211_ATTR_STA_VLAN], drv, ¶ms.vlan); | ||
1697 | if (err) | 1736 | if (err) |
1698 | goto out; | 1737 | goto out; |
1699 | 1738 | ||
@@ -1728,9 +1767,6 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info) | |||
1728 | if (!info->attrs[NL80211_ATTR_MAC]) | 1767 | if (!info->attrs[NL80211_ATTR_MAC]) |
1729 | return -EINVAL; | 1768 | return -EINVAL; |
1730 | 1769 | ||
1731 | if (!info->attrs[NL80211_ATTR_STA_AID]) | ||
1732 | return -EINVAL; | ||
1733 | |||
1734 | if (!info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL]) | 1770 | if (!info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL]) |
1735 | return -EINVAL; | 1771 | return -EINVAL; |
1736 | 1772 | ||
@@ -1745,9 +1781,11 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info) | |||
1745 | params.listen_interval = | 1781 | params.listen_interval = |
1746 | nla_get_u16(info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL]); | 1782 | nla_get_u16(info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL]); |
1747 | 1783 | ||
1748 | params.aid = nla_get_u16(info->attrs[NL80211_ATTR_STA_AID]); | 1784 | if (info->attrs[NL80211_ATTR_STA_AID]) { |
1749 | if (!params.aid || params.aid > IEEE80211_MAX_AID) | 1785 | params.aid = nla_get_u16(info->attrs[NL80211_ATTR_STA_AID]); |
1750 | return -EINVAL; | 1786 | if (!params.aid || params.aid > IEEE80211_MAX_AID) |
1787 | return -EINVAL; | ||
1788 | } | ||
1751 | 1789 | ||
1752 | if (info->attrs[NL80211_ATTR_HT_CAPABILITY]) | 1790 | if (info->attrs[NL80211_ATTR_HT_CAPABILITY]) |
1753 | params.ht_capa = | 1791 | params.ht_capa = |
@@ -1762,13 +1800,39 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info) | |||
1762 | if (err) | 1800 | if (err) |
1763 | goto out_rtnl; | 1801 | goto out_rtnl; |
1764 | 1802 | ||
1765 | if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP && | 1803 | err = get_vlan(info->attrs[NL80211_ATTR_STA_VLAN], drv, ¶ms.vlan); |
1766 | dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN) { | 1804 | if (err) |
1767 | err = -EINVAL; | ||
1768 | goto out; | 1805 | goto out; |
1806 | |||
1807 | /* validate settings */ | ||
1808 | err = 0; | ||
1809 | |||
1810 | switch (dev->ieee80211_ptr->iftype) { | ||
1811 | case NL80211_IFTYPE_AP: | ||
1812 | case NL80211_IFTYPE_AP_VLAN: | ||
1813 | /* all ok but must have AID */ | ||
1814 | if (!params.aid) | ||
1815 | err = -EINVAL; | ||
1816 | break; | ||
1817 | case NL80211_IFTYPE_MESH_POINT: | ||
1818 | /* disallow things mesh doesn't support */ | ||
1819 | if (params.vlan) | ||
1820 | err = -EINVAL; | ||
1821 | if (params.aid) | ||
1822 | err = -EINVAL; | ||
1823 | if (params.ht_capa) | ||
1824 | err = -EINVAL; | ||
1825 | if (params.listen_interval >= 0) | ||
1826 | err = -EINVAL; | ||
1827 | if (params.supported_rates) | ||
1828 | err = -EINVAL; | ||
1829 | if (params.sta_flags_mask) | ||
1830 | err = -EINVAL; | ||
1831 | break; | ||
1832 | default: | ||
1833 | err = -EINVAL; | ||
1769 | } | 1834 | } |
1770 | 1835 | ||
1771 | err = get_vlan(info->attrs[NL80211_ATTR_STA_VLAN], drv, ¶ms.vlan); | ||
1772 | if (err) | 1836 | if (err) |
1773 | goto out; | 1837 | goto out; |
1774 | 1838 | ||
@@ -1812,7 +1876,8 @@ static int nl80211_del_station(struct sk_buff *skb, struct genl_info *info) | |||
1812 | goto out_rtnl; | 1876 | goto out_rtnl; |
1813 | 1877 | ||
1814 | if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP && | 1878 | if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP && |
1815 | dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN) { | 1879 | dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN && |
1880 | dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT) { | ||
1816 | err = -EINVAL; | 1881 | err = -EINVAL; |
1817 | goto out; | 1882 | goto out; |
1818 | } | 1883 | } |