aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/cfg.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2011-12-14 06:35:30 -0500
committerJohn W. Linville <linville@tuxdriver.com>2011-12-15 14:46:34 -0500
commitd9a7ddb05e5419ca5e4b54f57074dc33c7ea991c (patch)
tree3de3213e7e79a64254ea778374aeaaffa61b5bab /net/mac80211/cfg.c
parent87be1e1e00f870567780dec111193426b4c085e8 (diff)
mac80211: refactor station state transitions
Station entries can have various states, the most important ones being auth, assoc and authorized. This patch prepares us for telling the driver about these states, we don't want to confuse drivers with strange transitions, so with this we enforce that they move in the right order between them (back and forth); some transitions might happen before the driver even knows about the station, but at least runtime transitions will be ordered correctly. As a consequence, IBSS and MESH stations will now have the ASSOC flag set (so they can transition to AUTHORIZED), and we can get rid of a special case in TX processing. When freeing a station, unwind the state so that other parts of the code (or drivers later) can rely on the transitions. Signed-off-by: Johannes Berg <johannes.berg@intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211/cfg.c')
-rw-r--r--net/mac80211/cfg.c76
1 files changed, 61 insertions, 15 deletions
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 3acda35df5cb..66ad9d9af87f 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -746,10 +746,11 @@ static void ieee80211_send_layer2_update(struct sta_info *sta)
746 netif_rx_ni(skb); 746 netif_rx_ni(skb);
747} 747}
748 748
749static void sta_apply_parameters(struct ieee80211_local *local, 749static int sta_apply_parameters(struct ieee80211_local *local,
750 struct sta_info *sta, 750 struct sta_info *sta,
751 struct station_parameters *params) 751 struct station_parameters *params)
752{ 752{
753 int ret = 0;
753 u32 rates; 754 u32 rates;
754 int i, j; 755 int i, j;
755 struct ieee80211_supported_band *sband; 756 struct ieee80211_supported_band *sband;
@@ -761,13 +762,59 @@ static void sta_apply_parameters(struct ieee80211_local *local,
761 mask = params->sta_flags_mask; 762 mask = params->sta_flags_mask;
762 set = params->sta_flags_set; 763 set = params->sta_flags_set;
763 764
765 /*
766 * In mesh mode, we can clear AUTHENTICATED flag but must
767 * also make ASSOCIATED follow appropriately for the driver
768 * API. See also below, after AUTHORIZED changes.
769 */
770 if (mask & BIT(NL80211_STA_FLAG_AUTHENTICATED)) {
771 /* cfg80211 should not allow this in non-mesh modes */
772 if (WARN_ON(!ieee80211_vif_is_mesh(&sdata->vif)))
773 return -EINVAL;
774
775 if (set & BIT(NL80211_STA_FLAG_AUTHENTICATED) &&
776 !test_sta_flag(sta, WLAN_STA_AUTH)) {
777 ret = sta_info_move_state_checked(sta,
778 IEEE80211_STA_AUTH);
779 if (ret)
780 return ret;
781 ret = sta_info_move_state_checked(sta,
782 IEEE80211_STA_ASSOC);
783 if (ret)
784 return ret;
785 }
786 }
787
764 if (mask & BIT(NL80211_STA_FLAG_AUTHORIZED)) { 788 if (mask & BIT(NL80211_STA_FLAG_AUTHORIZED)) {
765 if (set & BIT(NL80211_STA_FLAG_AUTHORIZED)) 789 if (set & BIT(NL80211_STA_FLAG_AUTHORIZED))
766 set_sta_flag(sta, WLAN_STA_AUTHORIZED); 790 ret = sta_info_move_state_checked(sta,
791 IEEE80211_STA_AUTHORIZED);
767 else 792 else
768 clear_sta_flag(sta, WLAN_STA_AUTHORIZED); 793 ret = sta_info_move_state_checked(sta,
794 IEEE80211_STA_ASSOC);
795 if (ret)
796 return ret;
769 } 797 }
770 798
799 if (mask & BIT(NL80211_STA_FLAG_AUTHENTICATED)) {
800 /* cfg80211 should not allow this in non-mesh modes */
801 if (WARN_ON(!ieee80211_vif_is_mesh(&sdata->vif)))
802 return -EINVAL;
803
804 if (!(set & BIT(NL80211_STA_FLAG_AUTHENTICATED)) &&
805 test_sta_flag(sta, WLAN_STA_AUTH)) {
806 ret = sta_info_move_state_checked(sta,
807 IEEE80211_STA_AUTH);
808 if (ret)
809 return ret;
810 ret = sta_info_move_state_checked(sta,
811 IEEE80211_STA_NONE);
812 if (ret)
813 return ret;
814 }
815 }
816
817
771 if (mask & BIT(NL80211_STA_FLAG_SHORT_PREAMBLE)) { 818 if (mask & BIT(NL80211_STA_FLAG_SHORT_PREAMBLE)) {
772 if (set & BIT(NL80211_STA_FLAG_SHORT_PREAMBLE)) 819 if (set & BIT(NL80211_STA_FLAG_SHORT_PREAMBLE))
773 set_sta_flag(sta, WLAN_STA_SHORT_PREAMBLE); 820 set_sta_flag(sta, WLAN_STA_SHORT_PREAMBLE);
@@ -792,13 +839,6 @@ static void sta_apply_parameters(struct ieee80211_local *local,
792 clear_sta_flag(sta, WLAN_STA_MFP); 839 clear_sta_flag(sta, WLAN_STA_MFP);
793 } 840 }
794 841
795 if (mask & BIT(NL80211_STA_FLAG_AUTHENTICATED)) {
796 if (set & BIT(NL80211_STA_FLAG_AUTHENTICATED))
797 set_sta_flag(sta, WLAN_STA_AUTH);
798 else
799 clear_sta_flag(sta, WLAN_STA_AUTH);
800 }
801
802 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) { 842 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
803 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) 843 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER))
804 set_sta_flag(sta, WLAN_STA_TDLS_PEER); 844 set_sta_flag(sta, WLAN_STA_TDLS_PEER);
@@ -870,6 +910,8 @@ static void sta_apply_parameters(struct ieee80211_local *local,
870 } 910 }
871#endif 911#endif
872 } 912 }
913
914 return 0;
873} 915}
874 916
875static int ieee80211_add_station(struct wiphy *wiphy, struct net_device *dev, 917static int ieee80211_add_station(struct wiphy *wiphy, struct net_device *dev,
@@ -900,10 +942,14 @@ static int ieee80211_add_station(struct wiphy *wiphy, struct net_device *dev,
900 if (!sta) 942 if (!sta)
901 return -ENOMEM; 943 return -ENOMEM;
902 944
903 set_sta_flag(sta, WLAN_STA_AUTH); 945 sta_info_move_state(sta, IEEE80211_STA_AUTH);
904 set_sta_flag(sta, WLAN_STA_ASSOC); 946 sta_info_move_state(sta, IEEE80211_STA_ASSOC);
905 947
906 sta_apply_parameters(local, sta, params); 948 err = sta_apply_parameters(local, sta, params);
949 if (err) {
950 sta_info_free(local, sta);
951 return err;
952 }
907 953
908 /* 954 /*
909 * for TDLS, rate control should be initialized only when supported 955 * for TDLS, rate control should be initialized only when supported