Skip to content

Commit 143582c

Browse files
jmberg-intelegrumbach
authored andcommitted
iwlwifi: fix TX status for aggregated packets
Only the first packet is currently handled correctly, but then all others are assumed to have failed which is problematic. Fix this, marking them all successful instead (since if they're not then the firmware will have transmitted them as single frames.) This fixes the lost packet reporting. Also do a tiny variable scoping cleanup. Cc: <[email protected]> Signed-off-by: Johannes Berg <[email protected]> [Add the dvm part] Signed-off-by: Emmanuel Grumbach <[email protected]>
1 parent e7eb65c commit 143582c

File tree

2 files changed

+18
-14
lines changed
  • drivers/net/wireless/iwlwifi

2 files changed

+18
-14
lines changed

drivers/net/wireless/iwlwifi/dvm/tx.c

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1291,8 +1291,6 @@ int iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv,
12911291
struct iwl_compressed_ba_resp *ba_resp = (void *)pkt->data;
12921292
struct iwl_ht_agg *agg;
12931293
struct sk_buff_head reclaimed_skbs;
1294-
struct ieee80211_tx_info *info;
1295-
struct ieee80211_hdr *hdr;
12961294
struct sk_buff *skb;
12971295
int sta_id;
12981296
int tid;
@@ -1379,22 +1377,28 @@ int iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv,
13791377
freed = 0;
13801378

13811379
skb_queue_walk(&reclaimed_skbs, skb) {
1382-
hdr = (struct ieee80211_hdr *)skb->data;
1380+
struct ieee80211_hdr *hdr = (void *)skb->data;
1381+
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
13831382

13841383
if (ieee80211_is_data_qos(hdr->frame_control))
13851384
freed++;
13861385
else
13871386
WARN_ON_ONCE(1);
13881387

1389-
info = IEEE80211_SKB_CB(skb);
13901388
iwl_trans_free_tx_cmd(priv->trans, info->driver_data[1]);
13911389

1390+
memset(&info->status, 0, sizeof(info->status));
1391+
/* Packet was transmitted successfully, failures come as single
1392+
* frames because before failing a frame the firmware transmits
1393+
* it without aggregation at least once.
1394+
*/
1395+
info->flags |= IEEE80211_TX_STAT_ACK;
1396+
13921397
if (freed == 1) {
13931398
/* this is the first skb we deliver in this batch */
13941399
/* put the rate scaling data there */
13951400
info = IEEE80211_SKB_CB(skb);
13961401
memset(&info->status, 0, sizeof(info->status));
1397-
info->flags |= IEEE80211_TX_STAT_ACK;
13981402
info->flags |= IEEE80211_TX_STAT_AMPDU;
13991403
info->status.ampdu_ack_len = ba_resp->txed_2_done;
14001404
info->status.ampdu_len = ba_resp->txed;

drivers/net/wireless/iwlwifi/mvm/tx.c

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -822,16 +822,12 @@ int iwl_mvm_rx_ba_notif(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
822822
struct iwl_mvm_ba_notif *ba_notif = (void *)pkt->data;
823823
struct sk_buff_head reclaimed_skbs;
824824
struct iwl_mvm_tid_data *tid_data;
825-
struct ieee80211_tx_info *info;
826825
struct ieee80211_sta *sta;
827826
struct iwl_mvm_sta *mvmsta;
828-
struct ieee80211_hdr *hdr;
829827
struct sk_buff *skb;
830828
int sta_id, tid, freed;
831-
832829
/* "flow" corresponds to Tx queue */
833830
u16 scd_flow = le16_to_cpu(ba_notif->scd_flow);
834-
835831
/* "ssn" is start of block-ack Tx window, corresponds to index
836832
* (in Tx queue's circular buffer) of first TFD/frame in window */
837833
u16 ba_resp_scd_ssn = le16_to_cpu(ba_notif->scd_ssn);
@@ -888,22 +884,26 @@ int iwl_mvm_rx_ba_notif(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
888884
freed = 0;
889885

890886
skb_queue_walk(&reclaimed_skbs, skb) {
891-
hdr = (struct ieee80211_hdr *)skb->data;
887+
struct ieee80211_hdr *hdr = (void *)skb->data;
888+
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
892889

893890
if (ieee80211_is_data_qos(hdr->frame_control))
894891
freed++;
895892
else
896893
WARN_ON_ONCE(1);
897894

898-
info = IEEE80211_SKB_CB(skb);
899895
iwl_trans_free_tx_cmd(mvm->trans, info->driver_data[1]);
900896

897+
memset(&info->status, 0, sizeof(info->status));
898+
/* Packet was transmitted successfully, failures come as single
899+
* frames because before failing a frame the firmware transmits
900+
* it without aggregation at least once.
901+
*/
902+
info->flags |= IEEE80211_TX_STAT_ACK;
903+
901904
if (freed == 1) {
902905
/* this is the first skb we deliver in this batch */
903906
/* put the rate scaling data there */
904-
info = IEEE80211_SKB_CB(skb);
905-
memset(&info->status, 0, sizeof(info->status));
906-
info->flags |= IEEE80211_TX_STAT_ACK;
907907
info->flags |= IEEE80211_TX_STAT_AMPDU;
908908
info->status.ampdu_ack_len = ba_notif->txed_2_done;
909909
info->status.ampdu_len = ba_notif->txed;

0 commit comments

Comments
 (0)