bes2600: Patch D — atomicize ba_lock counters, drop the spinlock (#7)

This commit was merged in pull request #7.
This commit is contained in:
2026-05-07 22:19:53 +00:00
5 changed files with 85 additions and 56 deletions
+46 -31
View File
@@ -2342,14 +2342,19 @@ void bes2600_join_work(struct work_struct *work)
//WARN_ON(wsm_reset(hw_priv, &reset, priv->if_id));
WARN_ON(wsm_set_block_ack_policy(hw_priv,
0, hw_priv->ba_tid_mask, priv->if_id));
spin_lock_bh(&hw_priv->ba_lock);
hw_priv->ba_ena = false;
hw_priv->ba_cnt = 0;
hw_priv->ba_acc = 0;
/*
* Patch D: ba_lock removed. Disconnect-reset clears the
* counters and the arm flag; producers racing here cannot
* cause harm — at worst they re-arm the timer and bump
* counters that will be cleared on the next timer tick.
*/
atomic_set(&hw_priv->ba_ena, 0);
atomic_set(&hw_priv->ba_cnt, 0);
atomic_set(&hw_priv->ba_acc, 0);
hw_priv->ba_hist = 0;
hw_priv->ba_cnt_rx = 0;
hw_priv->ba_acc_rx = 0;
spin_unlock_bh(&hw_priv->ba_lock);
atomic_set(&hw_priv->ba_cnt_rx, 0);
atomic_set(&hw_priv->ba_acc_rx, 0);
atomic_set(&hw_priv->ba_armed, 0);
mgmt_policy.protectedMgmtEnable = 0;
mgmt_policy.unprotectedMgmtFramesAllowed = 1;
@@ -2629,10 +2634,11 @@ void bes2600_ba_work(struct work_struct *work)
return;*/
bes_devel("BA work****\n");
spin_lock_bh(&hw_priv->ba_lock);
// tx_ba_tid_mask = hw_priv->ba_ena ? hw_priv->ba_tid_mask : 0;
/*
* Patch D: ba_lock removed. ba_tid_mask is u8 set once at init
* (main.c); reading it without a lock is fine.
*/
tx_ba_tid_mask = hw_priv->ba_tid_mask;
spin_unlock_bh(&hw_priv->ba_lock);
wsm_lock_tx(hw_priv);
@@ -2645,37 +2651,49 @@ void bes2600_ba_work(struct work_struct *work)
void bes2600_ba_timer(struct timer_list *t)
{
bool ba_ena;
int cnt, acc, cnt_rx, acc_rx;
struct bes2600_common *hw_priv = from_timer(hw_priv, t, ba_timer);
spin_lock_bh(&hw_priv->ba_lock);
bes2600_debug_ba(hw_priv, hw_priv->ba_cnt, hw_priv->ba_acc,
hw_priv->ba_cnt_rx, hw_priv->ba_acc_rx);
/*
* Patch D: ba_lock removed. Snapshot atomic counters into locals
* for the predicate evaluation; producers may race incrementing
* after the snapshot but the resulting decision is approximate
* which the policy already tolerates (next timer tick re-evaluates).
*/
cnt = atomic_read(&hw_priv->ba_cnt);
acc = atomic_read(&hw_priv->ba_acc);
cnt_rx = atomic_read(&hw_priv->ba_cnt_rx);
acc_rx = atomic_read(&hw_priv->ba_acc_rx);
bes2600_debug_ba(hw_priv, cnt, acc, cnt_rx, acc_rx);
if (atomic_read(&hw_priv->scan.in_progress)) {
hw_priv->ba_cnt = 0;
hw_priv->ba_acc = 0;
hw_priv->ba_cnt_rx = 0;
hw_priv->ba_acc_rx = 0;
goto skip_statistic_update;
atomic_set(&hw_priv->ba_cnt, 0);
atomic_set(&hw_priv->ba_acc, 0);
atomic_set(&hw_priv->ba_cnt_rx, 0);
atomic_set(&hw_priv->ba_acc_rx, 0);
atomic_set(&hw_priv->ba_armed, 0);
return;
}
if (hw_priv->ba_cnt >= BES2600_BLOCK_ACK_CNT &&
(hw_priv->ba_acc / hw_priv->ba_cnt >= BES2600_BLOCK_ACK_THLD ||
(hw_priv->ba_cnt_rx >= BES2600_BLOCK_ACK_CNT &&
hw_priv->ba_acc_rx / hw_priv->ba_cnt_rx >=
if (cnt >= BES2600_BLOCK_ACK_CNT &&
(acc / cnt >= BES2600_BLOCK_ACK_THLD ||
(cnt_rx >= BES2600_BLOCK_ACK_CNT &&
acc_rx / cnt_rx >=
BES2600_BLOCK_ACK_THLD)))
ba_ena = true;
else
ba_ena = false;
hw_priv->ba_cnt = 0;
hw_priv->ba_acc = 0;
hw_priv->ba_cnt_rx = 0;
hw_priv->ba_acc_rx = 0;
atomic_set(&hw_priv->ba_cnt, 0);
atomic_set(&hw_priv->ba_acc, 0);
atomic_set(&hw_priv->ba_cnt_rx, 0);
atomic_set(&hw_priv->ba_acc_rx, 0);
atomic_set(&hw_priv->ba_armed, 0);
if (ba_ena != hw_priv->ba_ena) {
if (ba_ena != !!atomic_read(&hw_priv->ba_ena)) {
if (ba_ena || ++hw_priv->ba_hist >= BES2600_BLOCK_ACK_HIST) {
hw_priv->ba_ena = ba_ena;
atomic_set(&hw_priv->ba_ena, ba_ena ? 1 : 0);
hw_priv->ba_hist = 0;
#if 0
bes_devel("[STA] %s block ACK:\n",
@@ -2685,9 +2703,6 @@ void bes2600_ba_timer(struct timer_list *t)
}
} else if (hw_priv->ba_hist)
--hw_priv->ba_hist;
skip_statistic_update:
spin_unlock_bh(&hw_priv->ba_lock);
}
int bes2600_vif_setup(struct bes2600_vif *priv)