Skip to content

Commit 5a6b06f

Browse files
tohojoKalle Valo
authored andcommitted
ath9k: Fix usage of driver-private space in tx_info
The ieee80211_tx_info_clear_status() helper also clears the rate counts and the driver-private part of struct ieee80211_tx_info, so using it breaks quite a few other things. So back out of using it, and instead define a ath-internal helper that only clears the area between the status_driver_data and the rates info. Combined with moving the ath_frame_info struct to status_driver_data, this avoids clearing anything we shouldn't be, and so we can keep the existing code for handling the rate information. While fixing this I also noticed that the setting of tx_info->status.rates[tx_rateindex].count on hardware underrun errors was always immediately overridden by the normal setting of the same fields, so rearrange the code so that the underrun detection actually takes effect. The new helper could be generalised to a 'memset_between()' helper, but leave it as a driver-internal helper for now since this needs to go to stable. Cc: stable@vger.kernel.org Reported-by: Peter Seiderer <ps.report@gmx.net> Fixes: 037250f ("ath9k: Properly clear TX status area before reporting to mac80211") Signed-off-by: Toke Høiland-Jørgensen <toke@redhat.com> Reviewed-by: Peter Seiderer <ps.report@gmx.net> Tested-by: Peter Seiderer <ps.report@gmx.net> Signed-off-by: Kalle Valo <kvalo@kernel.org> Link: https://lore.kernel.org/r/20220404204800.2681133-1-toke@toke.dk
1 parent 6fb3a58 commit 5a6b06f

2 files changed

Lines changed: 21 additions & 11 deletions

File tree

drivers/net/wireless/ath/ath9k/main.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -839,7 +839,7 @@ static bool ath9k_txq_list_has_key(struct list_head *txq_list, u32 keyix)
839839
continue;
840840

841841
txinfo = IEEE80211_SKB_CB(bf->bf_mpdu);
842-
fi = (struct ath_frame_info *)&txinfo->rate_driver_data[0];
842+
fi = (struct ath_frame_info *)&txinfo->status.status_driver_data[0];
843843
if (fi->keyix == keyix)
844844
return true;
845845
}

drivers/net/wireless/ath/ath9k/xmit.c

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -141,8 +141,8 @@ static struct ath_frame_info *get_frame_info(struct sk_buff *skb)
141141
{
142142
struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
143143
BUILD_BUG_ON(sizeof(struct ath_frame_info) >
144-
sizeof(tx_info->rate_driver_data));
145-
return (struct ath_frame_info *) &tx_info->rate_driver_data[0];
144+
sizeof(tx_info->status.status_driver_data));
145+
return (struct ath_frame_info *) &tx_info->status.status_driver_data[0];
146146
}
147147

148148
static void ath_send_bar(struct ath_atx_tid *tid, u16 seqno)
@@ -2542,6 +2542,16 @@ static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf,
25422542
spin_unlock_irqrestore(&sc->tx.txbuflock, flags);
25432543
}
25442544

2545+
static void ath_clear_tx_status(struct ieee80211_tx_info *tx_info)
2546+
{
2547+
void *ptr = &tx_info->status;
2548+
2549+
memset(ptr + sizeof(tx_info->status.rates), 0,
2550+
sizeof(tx_info->status) -
2551+
sizeof(tx_info->status.rates) -
2552+
sizeof(tx_info->status.status_driver_data));
2553+
}
2554+
25452555
static void ath_tx_rc_status(struct ath_softc *sc, struct ath_buf *bf,
25462556
struct ath_tx_status *ts, int nframes, int nbad,
25472557
int txok)
@@ -2553,7 +2563,7 @@ static void ath_tx_rc_status(struct ath_softc *sc, struct ath_buf *bf,
25532563
struct ath_hw *ah = sc->sc_ah;
25542564
u8 i, tx_rateindex;
25552565

2556-
ieee80211_tx_info_clear_status(tx_info);
2566+
ath_clear_tx_status(tx_info);
25572567

25582568
if (txok)
25592569
tx_info->status.ack_signal = ts->ts_rssi;
@@ -2569,6 +2579,13 @@ static void ath_tx_rc_status(struct ath_softc *sc, struct ath_buf *bf,
25692579
tx_info->status.ampdu_len = nframes;
25702580
tx_info->status.ampdu_ack_len = nframes - nbad;
25712581

2582+
tx_info->status.rates[tx_rateindex].count = ts->ts_longretry + 1;
2583+
2584+
for (i = tx_rateindex + 1; i < hw->max_rates; i++) {
2585+
tx_info->status.rates[i].count = 0;
2586+
tx_info->status.rates[i].idx = -1;
2587+
}
2588+
25722589
if ((ts->ts_status & ATH9K_TXERR_FILT) == 0 &&
25732590
(tx_info->flags & IEEE80211_TX_CTL_NO_ACK) == 0) {
25742591
/*
@@ -2590,13 +2607,6 @@ static void ath_tx_rc_status(struct ath_softc *sc, struct ath_buf *bf,
25902607
tx_info->status.rates[tx_rateindex].count =
25912608
hw->max_rate_tries;
25922609
}
2593-
2594-
for (i = tx_rateindex + 1; i < hw->max_rates; i++) {
2595-
tx_info->status.rates[i].count = 0;
2596-
tx_info->status.rates[i].idx = -1;
2597-
}
2598-
2599-
tx_info->status.rates[tx_rateindex].count = ts->ts_longretry + 1;
26002610
}
26012611

26022612
static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)

0 commit comments

Comments
 (0)