Skip to content

Commit

Permalink
iwlwifi: don't mess up QoS counters with non-QoS frames
Browse files Browse the repository at this point in the history
In my AMPDU rework, I rely on the sequence numbers of frames. But
I didn't check that the frame has a valid tid before updating the
tracking counters. As a result, the Tx queues were stalled. People
who hit this bug saw that we simply didn't let any data out.

This bug was introduced in 3.3.

This patch fixes that and checks that the frame is a QoS frame before
looking at its tid and changing the counters.

Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
  • Loading branch information
Emmanuel Grumbach authored and John W. Linville committed Feb 1, 2012
1 parent a6c8462 commit 3d29dd9
Show file tree
Hide file tree
Showing 3 changed files with 11 additions and 3 deletions.
12 changes: 9 additions & 3 deletions drivers/net/wireless/iwlwifi/iwl-agn-tx.c
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ static void iwlagn_tx_cmd_build_basic(struct iwl_priv *priv,
tx_cmd->tid_tspec = qc[0] & 0xf;
tx_flags &= ~TX_CMD_FLG_SEQ_CTL_MSK;
} else {
tx_cmd->tid_tspec = IWL_TID_NON_QOS;
if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ)
tx_flags |= TX_CMD_FLG_SEQ_CTL_MSK;
else
Expand Down Expand Up @@ -808,6 +809,8 @@ static void iwl_rx_reply_tx_agg(struct iwl_priv *priv,
u32 status = le16_to_cpu(tx_resp->status.status);
int i;

WARN_ON(tid == IWL_TID_NON_QOS);

if (agg->wait_for_ba)
IWL_DEBUG_TX_REPLY(priv,
"got tx response w/o block-ack\n");
Expand Down Expand Up @@ -1035,10 +1038,13 @@ int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb,
}

__skb_queue_head_init(&skbs);
priv->tid_data[sta_id][tid].next_reclaimed = next_reclaimed;

IWL_DEBUG_TX_REPLY(priv, "Next reclaimed packet:%d",
next_reclaimed);
if (tid != IWL_TID_NON_QOS) {
priv->tid_data[sta_id][tid].next_reclaimed =
next_reclaimed;
IWL_DEBUG_TX_REPLY(priv, "Next reclaimed packet:%d",
next_reclaimed);
}

/*we can free until ssn % q.n_bd not inclusive */
WARN_ON(iwl_trans_reclaim(trans(priv), sta_id, tid, txq_id,
Expand Down
1 change: 1 addition & 0 deletions drivers/net/wireless/iwlwifi/iwl-commands.h
Original file line number Diff line number Diff line change
Expand Up @@ -815,6 +815,7 @@ struct iwl_qosparam_cmd {

#define IWL_INVALID_STATION 255
#define IWL_MAX_TID_COUNT 8
#define IWL_TID_NON_QOS IWL_MAX_TID_COUNT

#define STA_FLG_TX_RATE_MSK cpu_to_le32(1 << 2)
#define STA_FLG_PWR_SAVE_MSK cpu_to_le32(1 << 8)
Expand Down
1 change: 1 addition & 0 deletions drivers/net/wireless/iwlwifi/iwl-trans-pcie.c
Original file line number Diff line number Diff line change
Expand Up @@ -1262,6 +1262,7 @@ static int iwl_trans_pcie_reclaim(struct iwl_trans *trans, int sta_id, int tid,
txq->time_stamp = jiffies;

if (unlikely(txq_id >= IWLAGN_FIRST_AMPDU_QUEUE &&
tid != IWL_TID_NON_QOS &&
txq_id != trans_pcie->agg_txq[sta_id][tid])) {
/*
* FIXME: this is a uCode bug which need to be addressed,
Expand Down

0 comments on commit 3d29dd9

Please sign in to comment.