mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-12-01 19:26:45 +07:00
wlcore/wl12xx: implement better beacon loss handling
Make use of REGAINED_BSS_EVENT and instead of reporting connection loss immediately on each BEACON_LOSE event, try if not regained in reasonable period of time. Signed-off-by: bartosz.markowski <bartosz.markowski@tieto.com> Signed-off-by: Luciano Coelho <coelho@ti.com>
This commit is contained in:
parent
161f17b530
commit
5f561f686b
@ -413,6 +413,7 @@ int wlcore_boot_run_firmware(struct wl1271 *wl)
|
||||
|
||||
/* unmask required mbox events */
|
||||
wl->event_mask = BSS_LOSE_EVENT_ID |
|
||||
REGAINED_BSS_EVENT_ID |
|
||||
SCAN_COMPLETE_EVENT_ID |
|
||||
ROLE_STOP_COMPLETE_EVENT_ID |
|
||||
RSSI_SNR_TRIGGER_0_EVENT_ID |
|
||||
|
@ -103,7 +103,6 @@ static int wl1271_event_process(struct wl1271 *wl)
|
||||
struct ieee80211_vif *vif;
|
||||
struct wl12xx_vif *wlvif;
|
||||
u32 vector;
|
||||
bool beacon_loss = false;
|
||||
bool disconnect_sta = false;
|
||||
unsigned long sta_bitmap = 0;
|
||||
|
||||
@ -141,20 +140,23 @@ static int wl1271_event_process(struct wl1271 *wl)
|
||||
mbox->soft_gemini_sense_info);
|
||||
|
||||
/*
|
||||
* The BSS_LOSE_EVENT_ID is only needed while psm (and hence beacon
|
||||
* filtering) is enabled. Without PSM, the stack will receive all
|
||||
* beacons and can detect beacon loss by itself.
|
||||
*
|
||||
* As there's possibility that the driver disables PSM before receiving
|
||||
* BSS_LOSE_EVENT, beacon loss has to be reported to the stack.
|
||||
*
|
||||
* We are HW_MONITOR device. On beacon loss - queue
|
||||
* connection loss work. Cancel it on REGAINED event.
|
||||
*/
|
||||
if (vector & BSS_LOSE_EVENT_ID) {
|
||||
/* TODO: check for multi-role */
|
||||
int delay = wl->conf.conn.synch_fail_thold *
|
||||
wl->conf.conn.bss_lose_timeout;
|
||||
wl1271_info("Beacon loss detected.");
|
||||
cancel_delayed_work_sync(&wl->connection_loss_work);
|
||||
ieee80211_queue_delayed_work(wl->hw, &wl->connection_loss_work,
|
||||
msecs_to_jiffies(delay));
|
||||
}
|
||||
|
||||
/* indicate to the stack, that beacons have been lost */
|
||||
beacon_loss = true;
|
||||
if (vector & REGAINED_BSS_EVENT_ID) {
|
||||
/* TODO: check for multi-role */
|
||||
wl1271_info("Beacon regained.");
|
||||
cancel_delayed_work_sync(&wl->connection_loss_work);
|
||||
}
|
||||
|
||||
if (vector & RSSI_SNR_TRIGGER_0_EVENT_ID) {
|
||||
@ -257,13 +259,6 @@ static int wl1271_event_process(struct wl1271 *wl)
|
||||
rcu_read_unlock();
|
||||
}
|
||||
}
|
||||
|
||||
if (beacon_loss)
|
||||
wl12xx_for_each_wlvif_sta(wl, wlvif) {
|
||||
vif = wl12xx_wlvif_to_vif(wlvif);
|
||||
ieee80211_connection_loss(vif);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1120,6 +1120,7 @@ int wl1271_plt_stop(struct wl1271 *wl)
|
||||
cancel_work_sync(&wl->recovery_work);
|
||||
cancel_delayed_work_sync(&wl->elp_work);
|
||||
cancel_delayed_work_sync(&wl->tx_watchdog_work);
|
||||
cancel_delayed_work_sync(&wl->connection_loss_work);
|
||||
|
||||
mutex_lock(&wl->mutex);
|
||||
wl1271_power_off(wl);
|
||||
@ -1753,6 +1754,7 @@ static void wl1271_op_stop(struct ieee80211_hw *hw)
|
||||
cancel_work_sync(&wl->tx_work);
|
||||
cancel_delayed_work_sync(&wl->elp_work);
|
||||
cancel_delayed_work_sync(&wl->tx_watchdog_work);
|
||||
cancel_delayed_work_sync(&wl->connection_loss_work);
|
||||
|
||||
/* let's notify MAC80211 about the remaining pending TX frames */
|
||||
wl12xx_tx_reset(wl, true);
|
||||
@ -3705,6 +3707,9 @@ static void wl1271_bss_info_changed_sta(struct wl1271 *wl,
|
||||
do_join = true;
|
||||
set_assoc = true;
|
||||
|
||||
/* Cancel connection_loss_work */
|
||||
cancel_delayed_work_sync(&wl->connection_loss_work);
|
||||
|
||||
/*
|
||||
* use basic rates from AP, and determine lowest rate
|
||||
* to use with control frames.
|
||||
@ -4815,6 +4820,34 @@ static struct bin_attribute fwlog_attr = {
|
||||
.read = wl1271_sysfs_read_fwlog,
|
||||
};
|
||||
|
||||
void wl1271_connection_loss_work(struct work_struct *work)
|
||||
{
|
||||
struct delayed_work *dwork;
|
||||
struct wl1271 *wl;
|
||||
struct ieee80211_vif *vif;
|
||||
struct wl12xx_vif *wlvif;
|
||||
|
||||
dwork = container_of(work, struct delayed_work, work);
|
||||
wl = container_of(dwork, struct wl1271, connection_loss_work);
|
||||
|
||||
wl1271_info("Connection loss work.");
|
||||
|
||||
mutex_lock(&wl->mutex);
|
||||
|
||||
if (unlikely(wl->state == WL1271_STATE_OFF))
|
||||
goto out;
|
||||
|
||||
/* Call mac80211 connection loss */
|
||||
wl12xx_for_each_wlvif_sta(wl, wlvif) {
|
||||
if (!test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags))
|
||||
goto out;
|
||||
vif = wl12xx_wlvif_to_vif(wlvif);
|
||||
ieee80211_connection_loss(vif);
|
||||
}
|
||||
out:
|
||||
mutex_unlock(&wl->mutex);
|
||||
}
|
||||
|
||||
static void wl12xx_derive_mac_addresses(struct wl1271 *wl,
|
||||
u32 oui, u32 nic, int n)
|
||||
{
|
||||
@ -5070,6 +5103,8 @@ struct ieee80211_hw *wlcore_alloc_hw(size_t priv_size)
|
||||
INIT_WORK(&wl->recovery_work, wl1271_recovery_work);
|
||||
INIT_DELAYED_WORK(&wl->scan_complete_work, wl1271_scan_complete_work);
|
||||
INIT_DELAYED_WORK(&wl->tx_watchdog_work, wl12xx_tx_watchdog_work);
|
||||
INIT_DELAYED_WORK(&wl->connection_loss_work,
|
||||
wl1271_connection_loss_work);
|
||||
|
||||
wl->freezable_wq = create_freezable_workqueue("wl12xx_wq");
|
||||
if (!wl->freezable_wq) {
|
||||
|
@ -243,6 +243,9 @@ struct wl1271 {
|
||||
struct wl1271_scan scan;
|
||||
struct delayed_work scan_complete_work;
|
||||
|
||||
/* Connection loss work */
|
||||
struct delayed_work connection_loss_work;
|
||||
|
||||
bool sched_scanning;
|
||||
|
||||
/* The current band */
|
||||
|
Loading…
Reference in New Issue
Block a user