Commit 0e759f36 authored by Bartosz Markowski's avatar Bartosz Markowski Committed by Kalle Valo

ath10k: track number of existing peers

To not exceed number of allowed clients (AP mode), make sure to
check how many of them are already on the peers list.

10.X firmware support up to 127 peers, non-AP centric firmwares 16.
Signed-off-by: default avatarBartosz Markowski <bartosz.markowski@tieto.com>
Signed-off-by: default avatarKalle Valo <kvalo@qca.qualcomm.com>
parent cdf07409
......@@ -432,6 +432,9 @@ struct ath10k {
struct list_head peers;
wait_queue_head_t peer_mapping_wq;
/* number of created peers; protected by data_lock */
int num_peers;
struct work_struct offchan_tx_work;
struct sk_buff_head offchan_tx_queue;
struct completion offchan_tx_completed;
......
......@@ -115,6 +115,7 @@ enum ath10k_mcast2ucast_mode {
#define TARGET_10X_MAC_AGGR_DELIM 0
#define TARGET_10X_AST_SKID_LIMIT 16
#define TARGET_10X_NUM_PEERS (128 + (TARGET_10X_NUM_VDEVS))
#define TARGET_10X_NUM_PEERS_MAX 128
#define TARGET_10X_NUM_OFFLOAD_PEERS 0
#define TARGET_10X_NUM_OFFLOAD_REORDER_BUFS 0
#define TARGET_10X_NUM_PEER_KEYS 2
......
......@@ -332,6 +332,9 @@ static int ath10k_peer_create(struct ath10k *ar, u32 vdev_id, const u8 *addr)
ath10k_warn("Failed to wait for created wmi peer: %i\n", ret);
return ret;
}
spin_lock_bh(&ar->data_lock);
ar->num_peers++;
spin_unlock_bh(&ar->data_lock);
return 0;
}
......@@ -377,6 +380,10 @@ static int ath10k_peer_delete(struct ath10k *ar, u32 vdev_id, const u8 *addr)
if (ret)
return ret;
spin_lock_bh(&ar->data_lock);
ar->num_peers--;
spin_unlock_bh(&ar->data_lock);
return 0;
}
......@@ -396,6 +403,7 @@ static void ath10k_peer_cleanup(struct ath10k *ar, u32 vdev_id)
list_del(&peer->list);
kfree(peer);
ar->num_peers--;
}
spin_unlock_bh(&ar->data_lock);
}
......@@ -411,6 +419,7 @@ static void ath10k_peer_cleanup_all(struct ath10k *ar)
list_del(&peer->list);
kfree(peer);
}
ar->num_peers = 0;
spin_unlock_bh(&ar->data_lock);
}
......@@ -2849,6 +2858,7 @@ static int ath10k_sta_state(struct ieee80211_hw *hw,
{
struct ath10k *ar = hw->priv;
struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
int max_num_peers;
int ret = 0;
mutex_lock(&ar->conf_mutex);
......@@ -2859,9 +2869,21 @@ static int ath10k_sta_state(struct ieee80211_hw *hw,
/*
* New station addition.
*/
if (test_bit(ATH10K_FW_FEATURE_WMI_10X, ar->fw_features))
max_num_peers = TARGET_10X_NUM_PEERS_MAX - 1;
else
max_num_peers = TARGET_NUM_PEERS;
if (ar->num_peers >= max_num_peers) {
ath10k_warn("Number of peers exceeded: peers number %d (max peers %d)\n",
ar->num_peers, max_num_peers);
ret = -ENOBUFS;
goto exit;
}
ath10k_dbg(ATH10K_DBG_MAC,
"mac vdev %d peer create %pM (new sta)\n",
arvif->vdev_id, sta->addr);
"mac vdev %d peer create %pM (new sta) num_peers %d\n",
arvif->vdev_id, sta->addr, ar->num_peers);
ret = ath10k_peer_create(ar, arvif->vdev_id, sta->addr);
if (ret)
......@@ -2911,7 +2933,7 @@ static int ath10k_sta_state(struct ieee80211_hw *hw,
ath10k_warn("Failed to disassociate station: %pM\n",
sta->addr);
}
exit:
mutex_unlock(&ar->conf_mutex);
return ret;
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment