|
|
@@ -981,7 +981,7 @@ static int sta_apply_auth_flags(struct ieee80211_local *local,
|
|
|
* well. Some drivers require rate control initialized
|
|
|
* before drv_sta_state() is called.
|
|
|
*/
|
|
|
- if (test_sta_flag(sta, WLAN_STA_TDLS_PEER))
|
|
|
+ if (!test_sta_flag(sta, WLAN_STA_RATE_CONTROL))
|
|
|
rate_control_rate_init(sta);
|
|
|
|
|
|
ret = sta_info_move_state(sta, IEEE80211_STA_ASSOC);
|
|
|
@@ -1120,8 +1120,11 @@ static int sta_apply_parameters(struct ieee80211_local *local,
|
|
|
local->hw.queues >= IEEE80211_NUM_ACS)
|
|
|
sta->sta.wme = set & BIT(NL80211_STA_FLAG_WME);
|
|
|
|
|
|
- /* auth flags will be set later for TDLS stations */
|
|
|
- if (!test_sta_flag(sta, WLAN_STA_TDLS_PEER)) {
|
|
|
+ /* auth flags will be set later for TDLS,
|
|
|
+ * and for unassociated stations that move to assocaited */
|
|
|
+ if (!test_sta_flag(sta, WLAN_STA_TDLS_PEER) &&
|
|
|
+ !((mask & BIT(NL80211_STA_FLAG_ASSOCIATED)) &&
|
|
|
+ (set & BIT(NL80211_STA_FLAG_ASSOCIATED)))) {
|
|
|
ret = sta_apply_auth_flags(local, sta, mask, set);
|
|
|
if (ret)
|
|
|
return ret;
|
|
|
@@ -1213,7 +1216,8 @@ static int sta_apply_parameters(struct ieee80211_local *local,
|
|
|
sta_apply_mesh_params(local, sta, params);
|
|
|
|
|
|
/* set the STA state after all sta info from usermode has been set */
|
|
|
- if (test_sta_flag(sta, WLAN_STA_TDLS_PEER)) {
|
|
|
+ if (test_sta_flag(sta, WLAN_STA_TDLS_PEER) ||
|
|
|
+ set & BIT(NL80211_STA_FLAG_ASSOCIATED)) {
|
|
|
ret = sta_apply_auth_flags(local, sta, mask, set);
|
|
|
if (ret)
|
|
|
return ret;
|
|
|
@@ -1255,12 +1259,14 @@ static int ieee80211_add_station(struct wiphy *wiphy, struct net_device *dev,
|
|
|
* defaults -- if userspace wants something else we'll
|
|
|
* change it accordingly in sta_apply_parameters()
|
|
|
*/
|
|
|
- if (!(params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER))) {
|
|
|
+ if (!(params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) &&
|
|
|
+ !(params->sta_flags_set & (BIT(NL80211_STA_FLAG_AUTHENTICATED) |
|
|
|
+ BIT(NL80211_STA_FLAG_ASSOCIATED)))) {
|
|
|
sta_info_pre_move_state(sta, IEEE80211_STA_AUTH);
|
|
|
sta_info_pre_move_state(sta, IEEE80211_STA_ASSOC);
|
|
|
- } else {
|
|
|
- sta->sta.tdls = true;
|
|
|
}
|
|
|
+ if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER))
|
|
|
+ sta->sta.tdls = true;
|
|
|
|
|
|
err = sta_apply_parameters(local, sta, params);
|
|
|
if (err) {
|
|
|
@@ -1269,10 +1275,12 @@ static int ieee80211_add_station(struct wiphy *wiphy, struct net_device *dev,
|
|
|
}
|
|
|
|
|
|
/*
|
|
|
- * for TDLS, rate control should be initialized only when
|
|
|
- * rates are known and station is marked authorized
|
|
|
+ * for TDLS and for unassociated station, rate control should be
|
|
|
+ * initialized only when rates are known and station is marked
|
|
|
+ * authorized/associated
|
|
|
*/
|
|
|
- if (!test_sta_flag(sta, WLAN_STA_TDLS_PEER))
|
|
|
+ if (!test_sta_flag(sta, WLAN_STA_TDLS_PEER) &&
|
|
|
+ test_sta_flag(sta, WLAN_STA_ASSOC))
|
|
|
rate_control_rate_init(sta);
|
|
|
|
|
|
layer2_update = sdata->vif.type == NL80211_IFTYPE_AP_VLAN ||
|
|
|
@@ -1347,7 +1355,10 @@ static int ieee80211_change_station(struct wiphy *wiphy,
|
|
|
break;
|
|
|
case NL80211_IFTYPE_AP:
|
|
|
case NL80211_IFTYPE_AP_VLAN:
|
|
|
- statype = CFG80211_STA_AP_CLIENT;
|
|
|
+ if (test_sta_flag(sta, WLAN_STA_ASSOC))
|
|
|
+ statype = CFG80211_STA_AP_CLIENT;
|
|
|
+ else
|
|
|
+ statype = CFG80211_STA_AP_CLIENT_UNASSOC;
|
|
|
break;
|
|
|
default:
|
|
|
err = -EOPNOTSUPP;
|