aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/cfg.c
diff options
context:
space:
mode:
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