ath10k: enable firmware STA quick kickout
Firmware has a feature to track if the associated STA is not acking the frames. When that happens, the firmware sends WMI_PEER_STA_KICKOUT_EVENTID event to the host. Enable that to faster detect when a STA has left BSS without sending a deauth frame. Also set huge keepalive timeouts to avoid using the keepalive functionality in the firmware. Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
This commit is contained in:
parent
542fb17400
commit
5a13e76eca
|
@ -46,6 +46,18 @@
|
||||||
|
|
||||||
#define ATH10K_MAX_NUM_MGMT_PENDING 128
|
#define ATH10K_MAX_NUM_MGMT_PENDING 128
|
||||||
|
|
||||||
|
/* number of failed packets */
|
||||||
|
#define ATH10K_KICKOUT_THRESHOLD 50
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Use insanely high numbers to make sure that the firmware implementation
|
||||||
|
* won't start, we have the same functionality already in hostapd. Unit
|
||||||
|
* is seconds.
|
||||||
|
*/
|
||||||
|
#define ATH10K_KEEPALIVE_MIN_IDLE 3747
|
||||||
|
#define ATH10K_KEEPALIVE_MAX_IDLE 3895
|
||||||
|
#define ATH10K_KEEPALIVE_MAX_UNRESPONSIVE 3900
|
||||||
|
|
||||||
struct ath10k;
|
struct ath10k;
|
||||||
|
|
||||||
struct ath10k_skb_cb {
|
struct ath10k_skb_cb {
|
||||||
|
|
|
@ -339,6 +339,50 @@ static int ath10k_peer_create(struct ath10k *ar, u32 vdev_id, const u8 *addr)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int ath10k_mac_set_kickout(struct ath10k_vif *arvif)
|
||||||
|
{
|
||||||
|
struct ath10k *ar = arvif->ar;
|
||||||
|
u32 param;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
param = ar->wmi.pdev_param->sta_kickout_th;
|
||||||
|
ret = ath10k_wmi_pdev_set_param(ar, param,
|
||||||
|
ATH10K_KICKOUT_THRESHOLD);
|
||||||
|
if (ret) {
|
||||||
|
ath10k_warn("Failed to set kickout threshold: %d\n", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
param = ar->wmi.vdev_param->ap_keepalive_min_idle_inactive_time_secs;
|
||||||
|
ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, param,
|
||||||
|
ATH10K_KEEPALIVE_MIN_IDLE);
|
||||||
|
if (ret) {
|
||||||
|
ath10k_warn("Failed to set keepalive minimum idle time : %d\n",
|
||||||
|
ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
param = ar->wmi.vdev_param->ap_keepalive_max_idle_inactive_time_secs;
|
||||||
|
ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, param,
|
||||||
|
ATH10K_KEEPALIVE_MAX_IDLE);
|
||||||
|
if (ret) {
|
||||||
|
ath10k_warn("Failed to set keepalive maximum idle time: %d\n",
|
||||||
|
ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
param = ar->wmi.vdev_param->ap_keepalive_max_unresponsive_time_secs;
|
||||||
|
ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, param,
|
||||||
|
ATH10K_KEEPALIVE_MAX_UNRESPONSIVE);
|
||||||
|
if (ret) {
|
||||||
|
ath10k_warn("Failed to set keepalive maximum unresponsive time: %d\n",
|
||||||
|
ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int ath10k_mac_set_rts(struct ath10k_vif *arvif, u32 value)
|
static int ath10k_mac_set_rts(struct ath10k_vif *arvif, u32 value)
|
||||||
{
|
{
|
||||||
struct ath10k *ar = arvif->ar;
|
struct ath10k *ar = arvif->ar;
|
||||||
|
@ -2214,7 +2258,7 @@ static int ath10k_add_interface(struct ieee80211_hw *hw,
|
||||||
struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
|
struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
|
||||||
enum wmi_sta_powersave_param param;
|
enum wmi_sta_powersave_param param;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
u32 value, param_id;
|
u32 value;
|
||||||
int bit;
|
int bit;
|
||||||
u32 vdev_param;
|
u32 vdev_param;
|
||||||
|
|
||||||
|
@ -2307,12 +2351,12 @@ static int ath10k_add_interface(struct ieee80211_hw *hw,
|
||||||
goto err_vdev_delete;
|
goto err_vdev_delete;
|
||||||
}
|
}
|
||||||
|
|
||||||
param_id = ar->wmi.pdev_param->sta_kickout_th;
|
ret = ath10k_mac_set_kickout(arvif);
|
||||||
|
if (ret) {
|
||||||
/* Disable STA KICKOUT functionality in FW */
|
ath10k_warn("Failed to set kickout parameters: %d\n",
|
||||||
ret = ath10k_wmi_pdev_set_param(ar, param_id, 0);
|
ret);
|
||||||
if (ret)
|
goto err_peer_delete;
|
||||||
ath10k_warn("Failed to disable STA KICKOUT\n");
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (arvif->vdev_type == WMI_VDEV_TYPE_STA) {
|
if (arvif->vdev_type == WMI_VDEV_TYPE_STA) {
|
||||||
|
|
|
@ -1116,7 +1116,27 @@ static void ath10k_wmi_event_vdev_stopped(struct ath10k *ar,
|
||||||
static void ath10k_wmi_event_peer_sta_kickout(struct ath10k *ar,
|
static void ath10k_wmi_event_peer_sta_kickout(struct ath10k *ar,
|
||||||
struct sk_buff *skb)
|
struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
ath10k_dbg(ATH10K_DBG_WMI, "WMI_PEER_STA_KICKOUT_EVENTID\n");
|
struct wmi_peer_sta_kickout_event *ev;
|
||||||
|
struct ieee80211_sta *sta;
|
||||||
|
|
||||||
|
ev = (struct wmi_peer_sta_kickout_event *)skb->data;
|
||||||
|
|
||||||
|
ath10k_dbg(ATH10K_DBG_WMI, "wmi event peer sta kickout %pM\n",
|
||||||
|
ev->peer_macaddr.addr);
|
||||||
|
|
||||||
|
rcu_read_lock();
|
||||||
|
|
||||||
|
sta = ieee80211_find_sta_by_ifaddr(ar->hw, ev->peer_macaddr.addr, NULL);
|
||||||
|
if (!sta) {
|
||||||
|
ath10k_warn("Spurious quick kickout for STA %pM\n",
|
||||||
|
ev->peer_macaddr.addr);
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
ieee80211_report_low_ack(sta, 10);
|
||||||
|
|
||||||
|
exit:
|
||||||
|
rcu_read_unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -4039,6 +4039,10 @@ struct wmi_chan_info_event {
|
||||||
__le32 cycle_count;
|
__le32 cycle_count;
|
||||||
} __packed;
|
} __packed;
|
||||||
|
|
||||||
|
struct wmi_peer_sta_kickout_event {
|
||||||
|
struct wmi_mac_addr peer_macaddr;
|
||||||
|
} __packed;
|
||||||
|
|
||||||
#define WMI_CHAN_INFO_FLAG_COMPLETE BIT(0)
|
#define WMI_CHAN_INFO_FLAG_COMPLETE BIT(0)
|
||||||
|
|
||||||
/* FIXME: empirically extrapolated */
|
/* FIXME: empirically extrapolated */
|
||||||
|
|
Loading…
Reference in New Issue