iwlwifi: mvm: disallow new TDLS stations when appropriate
HW/FW constraints dictate that TDLS should only be used when a single phy ctx is active. We also support at most 4 TDLS peers. We don't support TDLS on a P2P vif. Unify and move a phy-ctx counting implementation from the power-mgmt code in order to simplify implementation. Signed-off-by: Arik Nemtsov <arikx.nemtsov@intel.com> Reviewed-by: Johannes Berg <johannes.berg@intel.com> Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
This commit is contained in:
parent
003e5236a1
commit
cf7b491dbb
@ -86,6 +86,8 @@ enum {
|
||||
|
||||
#define IWL_MVM_STATION_COUNT 16
|
||||
|
||||
#define IWL_MVM_TDLS_STA_COUNT 4
|
||||
|
||||
/* commands */
|
||||
enum {
|
||||
MVM_ALIVE = 0x1,
|
||||
|
@ -1843,6 +1843,26 @@ static void iwl_mvm_sta_pre_rcu_remove(struct ieee80211_hw *hw,
|
||||
mutex_unlock(&mvm->mutex);
|
||||
}
|
||||
|
||||
static int iwl_mvm_tdls_sta_count(struct iwl_mvm *mvm)
|
||||
{
|
||||
struct ieee80211_sta *sta;
|
||||
int count = 0;
|
||||
int i;
|
||||
|
||||
lockdep_assert_held(&mvm->mutex);
|
||||
|
||||
for (i = 0; i < IWL_MVM_STATION_COUNT; i++) {
|
||||
sta = rcu_dereference_protected(mvm->fw_id_to_mac_id[i],
|
||||
lockdep_is_held(&mvm->mutex));
|
||||
if (!sta || IS_ERR(sta) || !sta->tdls)
|
||||
continue;
|
||||
|
||||
count++;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static int iwl_mvm_mac_sta_state(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif,
|
||||
struct ieee80211_sta *sta,
|
||||
@ -1881,6 +1901,16 @@ static int iwl_mvm_mac_sta_state(struct ieee80211_hw *hw,
|
||||
ret = -EINVAL;
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
if (sta->tdls &&
|
||||
(vif->p2p ||
|
||||
iwl_mvm_tdls_sta_count(mvm) == IWL_MVM_TDLS_STA_COUNT ||
|
||||
iwl_mvm_phy_ctx_count(mvm) > 1)) {
|
||||
IWL_DEBUG_MAC80211(mvm, "refusing TDLS sta\n");
|
||||
ret = -EBUSY;
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
ret = iwl_mvm_add_sta(mvm, vif, sta);
|
||||
} else if (old_state == IEEE80211_STA_NONE &&
|
||||
new_state == IEEE80211_STA_AUTH) {
|
||||
|
@ -838,6 +838,7 @@ void iwl_mvm_phy_ctxt_ref(struct iwl_mvm *mvm,
|
||||
struct iwl_mvm_phy_ctxt *ctxt);
|
||||
void iwl_mvm_phy_ctxt_unref(struct iwl_mvm *mvm,
|
||||
struct iwl_mvm_phy_ctxt *ctxt);
|
||||
int iwl_mvm_phy_ctx_count(struct iwl_mvm *mvm);
|
||||
|
||||
/* MAC (virtual interface) programming */
|
||||
int iwl_mvm_mac_ctxt_init(struct iwl_mvm *mvm, struct ieee80211_vif *vif);
|
||||
|
@ -261,3 +261,29 @@ void iwl_mvm_phy_ctxt_unref(struct iwl_mvm *mvm, struct iwl_mvm_phy_ctxt *ctxt)
|
||||
|
||||
ctxt->ref--;
|
||||
}
|
||||
|
||||
static void iwl_mvm_binding_iterator(void *_data, u8 *mac,
|
||||
struct ieee80211_vif *vif)
|
||||
{
|
||||
unsigned long *data = _data;
|
||||
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
|
||||
|
||||
if (!mvmvif->phy_ctxt)
|
||||
return;
|
||||
|
||||
if (vif->type == NL80211_IFTYPE_STATION ||
|
||||
vif->type == NL80211_IFTYPE_AP)
|
||||
__set_bit(mvmvif->phy_ctxt->id, data);
|
||||
}
|
||||
|
||||
int iwl_mvm_phy_ctx_count(struct iwl_mvm *mvm)
|
||||
{
|
||||
unsigned long phy_ctxt_counter = 0;
|
||||
|
||||
ieee80211_iterate_active_interfaces_atomic(mvm->hw,
|
||||
IEEE80211_IFACE_ITER_NORMAL,
|
||||
iwl_mvm_binding_iterator,
|
||||
&phy_ctxt_counter);
|
||||
|
||||
return hweight8(phy_ctxt_counter);
|
||||
}
|
||||
|
@ -246,30 +246,10 @@ static void iwl_mvm_power_configure_uapsd(struct iwl_mvm *mvm,
|
||||
IWL_MVM_PS_HEAVY_RX_THLD_PERCENT;
|
||||
}
|
||||
|
||||
static void iwl_mvm_binding_iterator(void *_data, u8 *mac,
|
||||
struct ieee80211_vif *vif)
|
||||
{
|
||||
unsigned long *data = _data;
|
||||
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
|
||||
|
||||
if (!mvmvif->phy_ctxt)
|
||||
return;
|
||||
|
||||
if (vif->type == NL80211_IFTYPE_STATION ||
|
||||
vif->type == NL80211_IFTYPE_AP)
|
||||
__set_bit(mvmvif->phy_ctxt->id, data);
|
||||
}
|
||||
|
||||
static bool iwl_mvm_power_allow_uapsd(struct iwl_mvm *mvm,
|
||||
struct ieee80211_vif *vif)
|
||||
{
|
||||
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
|
||||
unsigned long phy_ctxt_counter = 0;
|
||||
|
||||
ieee80211_iterate_active_interfaces_atomic(mvm->hw,
|
||||
IEEE80211_IFACE_ITER_NORMAL,
|
||||
iwl_mvm_binding_iterator,
|
||||
&phy_ctxt_counter);
|
||||
|
||||
if (!memcmp(mvmvif->uapsd_misbehaving_bssid, vif->bss_conf.bssid,
|
||||
ETH_ALEN))
|
||||
@ -291,7 +271,7 @@ static bool iwl_mvm_power_allow_uapsd(struct iwl_mvm *mvm,
|
||||
* Avoid using uAPSD if client is in DCM -
|
||||
* low latency issue in Miracast
|
||||
*/
|
||||
if (hweight8(phy_ctxt_counter) >= 2)
|
||||
if (iwl_mvm_phy_ctx_count(mvm) >= 2)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
|
Loading…
Reference in New Issue
Block a user