From: Greg Kroah-Hartman Date: Mon, 22 Nov 2010 23:23:11 +0000 (-0800) Subject: .36 patches X-Git-Tag: v2.6.27.57~73 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=c06f7f46ce7296551a3afc8d6e5792ae60c9273d;p=thirdparty%2Fkernel%2Fstable-queue.git .36 patches --- diff --git a/queue-2.6.36/ath9k-a-mpdu-rate-control-info-fix.patch b/queue-2.6.36/ath9k-a-mpdu-rate-control-info-fix.patch new file mode 100644 index 00000000000..657837f6cf4 --- /dev/null +++ b/queue-2.6.36/ath9k-a-mpdu-rate-control-info-fix.patch @@ -0,0 +1,121 @@ +From ebd022873aa61937603d2c4dfea19ce63ea1a3c8 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Bj=C3=B6rn=20Smedman?= +Date: Sun, 10 Oct 2010 22:44:39 +0200 +Subject: ath9k: A-MPDU rate control info fix +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: =?UTF-8?q?Bj=C3=B6rn=20Smedman?= + +commit ebd022873aa61937603d2c4dfea19ce63ea1a3c8 upstream. + +This patch fixes the following problems with the rate control feedback +generated by ath9k for A-MPDU frames: + +1. Rate control feedback is carried on the first frame of an aggregate +that is either ACKed, or has execeeded the software retry count and is +considered failed. However, ath9k would incorrectly assume the aggregate +had the length 1 if one of these conditions did not apply to the first +frame of the aggregate, but instead a later frame. This fix therefor +copies the bf_nframes field of the buffer in the same manner as the rates +field of the tx status. + +2. Sometimes the ampdu_len and ampdu_ack_len fields of the tx status was +left uninitialized eventhough the IEEE80211_TX_STAT_AMPDU flag was set. +This is now avoid by setting flag and fields in the same place. + +3. Even if a frame has been selected for aggregation by mac80211 and +marked with the IEEE80211_TX_CTL_AMPDU flag it can sometimes happen that +ath9k transmits the frame without aggregation. In these cases the +ampdu_ack_len field could be incorrectly computed because the nbad +parameter to ath_tx_rc_status was incorrect. + +Signed-off-by: Björn Smedman +Acked-by: Felix Fietkau +Signed-off-by: John W. Linville +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/wireless/ath/ath9k/xmit.c | 19 +++++++++++++------ + 1 file changed, 13 insertions(+), 6 deletions(-) + +--- a/drivers/net/wireless/ath/ath9k/xmit.c ++++ b/drivers/net/wireless/ath/ath9k/xmit.c +@@ -312,6 +312,7 @@ static void ath_tx_complete_aggr(struct + int isaggr, txfail, txpending, sendbar = 0, needreset = 0, nbad = 0; + bool rc_update = true; + struct ieee80211_tx_rate rates[4]; ++ int nframes; + + skb = bf->bf_mpdu; + hdr = (struct ieee80211_hdr *)skb->data; +@@ -320,6 +321,7 @@ static void ath_tx_complete_aggr(struct + hw = bf->aphy->hw; + + memcpy(rates, tx_info->control.rates, sizeof(rates)); ++ nframes = bf->bf_nframes; + + rcu_read_lock(); + +@@ -337,7 +339,7 @@ static void ath_tx_complete_aggr(struct + !bf->bf_stale || bf_next != NULL) + list_move_tail(&bf->list, &bf_head); + +- ath_tx_rc_status(bf, ts, 0, 0, false); ++ ath_tx_rc_status(bf, ts, 1, 0, false); + ath_tx_complete_buf(sc, bf, txq, &bf_head, ts, + 0, 0); + +@@ -442,6 +444,7 @@ static void ath_tx_complete_aggr(struct + + if (rc_update && (acked_cnt == 1 || txfail_cnt == 1)) { + memcpy(tx_info->control.rates, rates, sizeof(rates)); ++ bf->bf_nframes = nframes; + ath_tx_rc_status(bf, ts, nbad, txok, true); + rc_update = false; + } else { +@@ -2024,9 +2027,15 @@ static void ath_tx_rc_status(struct ath_ + + if (ts->ts_status & ATH9K_TXERR_FILT) + tx_info->flags |= IEEE80211_TX_STAT_TX_FILTERED; +- if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) && update_rc) ++ if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) && update_rc) { + tx_info->flags |= IEEE80211_TX_STAT_AMPDU; + ++ BUG_ON(nbad > bf->bf_nframes); ++ ++ tx_info->status.ampdu_len = bf->bf_nframes; ++ tx_info->status.ampdu_ack_len = bf->bf_nframes - nbad; ++ } ++ + if ((ts->ts_status & ATH9K_TXERR_FILT) == 0 && + (bf->bf_flags & ATH9K_TXDESC_NOACK) == 0 && update_rc) { + if (ieee80211_is_data(hdr->frame_control)) { +@@ -2036,8 +2045,6 @@ static void ath_tx_rc_status(struct ath_ + if ((ts->ts_status & ATH9K_TXERR_XRETRY) || + (ts->ts_status & ATH9K_TXERR_FIFO)) + tx_info->pad[0] |= ATH_TX_INFO_XRETRY; +- tx_info->status.ampdu_len = bf->bf_nframes; +- tx_info->status.ampdu_ack_len = bf->bf_nframes - nbad; + } + } + +@@ -2159,7 +2166,7 @@ static void ath_tx_processq(struct ath_s + */ + if (ts.ts_status & ATH9K_TXERR_XRETRY) + bf->bf_state.bf_type |= BUF_XRETRY; +- ath_tx_rc_status(bf, &ts, 0, txok, true); ++ ath_tx_rc_status(bf, &ts, txok ? 0 : 1, txok, true); + } + + if (bf_isampdu(bf)) +@@ -2288,7 +2295,7 @@ void ath_tx_edma_tasklet(struct ath_soft + if (!bf_isampdu(bf)) { + if (txs.ts_status & ATH9K_TXERR_XRETRY) + bf->bf_state.bf_type |= BUF_XRETRY; +- ath_tx_rc_status(bf, &txs, 0, txok, true); ++ ath_tx_rc_status(bf, &txs, txok ? 0 : 1, txok, true); + } + + if (bf_isampdu(bf)) diff --git a/queue-2.6.36/ath9k-add-locking-for-starting-the-pcu-on-rx.patch b/queue-2.6.36/ath9k-add-locking-for-starting-the-pcu-on-rx.patch new file mode 100644 index 00000000000..918fd053131 --- /dev/null +++ b/queue-2.6.36/ath9k-add-locking-for-starting-the-pcu-on-rx.patch @@ -0,0 +1,66 @@ +From 7583c550c3e635dcc61ab127c36ecefd59fb8dc8 Mon Sep 17 00:00:00 2001 +From: Luis R. Rodriguez +Date: Wed, 20 Oct 2010 16:07:04 -0700 +Subject: ath9k: add locking for starting the PCU on RX + +From: Luis R. Rodriguez + +commit 7583c550c3e635dcc61ab127c36ecefd59fb8dc8 upstream. + +There was some locking for starting some parts of +RX but not for starting the PCU. Include this otherwise +we can content against stopping the PCU. + +This can potentially lead to races against different +buffers on the PCU which can lead to to the DMA RX +engine writing to buffers which are already freed. + +This is part of a series that will help resolve the bug: + +https://bugzilla.kernel.org/show_bug.cgi?id=14624 + +For more details about this issue refer to: + +http://marc.info/?l=linux-wireless&m=128629803703756&w=2 + +Cc: Ben Greear +Cc: Kyungwan Nam +Signed-off-by: Luis R. Rodriguez +Tested-by: Ben Greear +Signed-off-by: John W. Linville +Signed-off-by: Greg Kroah-Hartman + +index e581b1f..b3c9baf 100644 +--- + drivers/net/wireless/ath/ath9k/recv.c | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +--- a/drivers/net/wireless/ath/ath9k/recv.c ++++ b/drivers/net/wireless/ath/ath9k/recv.c +@@ -288,11 +288,11 @@ static void ath_edma_start_recv(struct a + ath_rx_addbuffer_edma(sc, ATH9K_RX_QUEUE_LP, + sc->rx.rx_edma[ATH9K_RX_QUEUE_LP].rx_fifo_hwsize); + +- spin_unlock_bh(&sc->rx.rxbuflock); +- + ath_opmode_init(sc); + + ath9k_hw_startpcureceive(sc->sc_ah, (sc->sc_flags & SC_OP_OFFCHANNEL)); ++ ++ spin_unlock_bh(&sc->rx.rxbuflock); + } + + static void ath_edma_stop_recv(struct ath_softc *sc) +@@ -494,10 +494,11 @@ int ath_startrecv(struct ath_softc *sc) + ath9k_hw_rxena(ah); + + start_recv: +- spin_unlock_bh(&sc->rx.rxbuflock); + ath_opmode_init(sc); + ath9k_hw_startpcureceive(ah, (sc->sc_flags & SC_OP_OFFCHANNEL)); + ++ spin_unlock_bh(&sc->rx.rxbuflock); ++ + return 0; + } + diff --git a/queue-2.6.36/ath9k-add-locking-for-stopping-rx.patch b/queue-2.6.36/ath9k-add-locking-for-stopping-rx.patch new file mode 100644 index 00000000000..327867554b2 --- /dev/null +++ b/queue-2.6.36/ath9k-add-locking-for-stopping-rx.patch @@ -0,0 +1,67 @@ +From 1e450285281bdf766272c181ecd43d4f2f0711ce Mon Sep 17 00:00:00 2001 +From: Luis R. Rodriguez +Date: Wed, 20 Oct 2010 16:07:03 -0700 +Subject: ath9k: add locking for stopping RX + +From: Luis R. Rodriguez + +commit 1e450285281bdf766272c181ecd43d4f2f0711ce upstream. + +ath9k locks for starting RX but not for stopping RX. We could +potentially run into a situation where tried to stop RX +but immediately started RX. This allows for races on the +the RX engine deciding what buffer we last left off on +and could potentially cause ath9k to DMA into already +free'd memory or in the worst case at a later time to +already given memory to other drivers. + +Fix this by locking stopping RX. + +This is part of a series that will help resolve the bug: + +https://bugzilla.kernel.org/show_bug.cgi?id=14624 + +For more details about this issue refer to: + +http://marc.info/?l=linux-wireless&m=128629803703756&w=2 + +Cc: Ben Greear +Cc: Kyungwan Nam +Signed-off-by: Luis R. Rodriguez +Tested-by: Ben Greear +Signed-off-by: John W. Linville +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/wireless/ath/ath9k/recv.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/net/wireless/ath/ath9k/recv.c ++++ b/drivers/net/wireless/ath/ath9k/recv.c +@@ -297,10 +297,8 @@ static void ath_edma_start_recv(struct a + + static void ath_edma_stop_recv(struct ath_softc *sc) + { +- spin_lock_bh(&sc->rx.rxbuflock); + ath_rx_remove_buffer(sc, ATH9K_RX_QUEUE_HP); + ath_rx_remove_buffer(sc, ATH9K_RX_QUEUE_LP); +- spin_unlock_bh(&sc->rx.rxbuflock); + } + + int ath_rx_init(struct ath_softc *sc, int nbufs) +@@ -508,6 +506,7 @@ bool ath_stoprecv(struct ath_softc *sc) + struct ath_hw *ah = sc->sc_ah; + bool stopped; + ++ spin_lock_bh(&sc->rx.rxbuflock); + ath9k_hw_stoppcurecv(ah); + ath9k_hw_setrxfilter(ah, 0); + stopped = ath9k_hw_stopdmarecv(ah); +@@ -516,6 +515,7 @@ bool ath_stoprecv(struct ath_softc *sc) + ath_edma_stop_recv(sc); + else + sc->rx.rxlink = NULL; ++ spin_unlock_bh(&sc->rx.rxbuflock); + + return stopped; + } diff --git a/queue-2.6.36/ath9k-built-in-rate-control-a-mpdu-fix.patch b/queue-2.6.36/ath9k-built-in-rate-control-a-mpdu-fix.patch new file mode 100644 index 00000000000..ac498c75235 --- /dev/null +++ b/queue-2.6.36/ath9k-built-in-rate-control-a-mpdu-fix.patch @@ -0,0 +1,42 @@ +From a8909cfb1832ac623142898df2a9374722cfe68f Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Bj=C3=B6rn=20Smedman?= +Date: Sun, 10 Oct 2010 22:51:54 +0200 +Subject: ath9k: built-in rate control A-MPDU fix +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: =?UTF-8?q?Bj=C3=B6rn=20Smedman?= + +commit a8909cfb1832ac623142898df2a9374722cfe68f upstream. + +This patch attempts to ensure that ath9k's built-in rate control algorithm +does not rely on the value of the ampdu_len and ampdu_ack_len tx status +fields unless the IEEE80211_TX_STAT_AMPDU flag is set. + +This patch has not been tested. + +Signed-off-by: Björn Smedman +Acked-by: Felix Fietkau +Signed-off-by: John W. Linville +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/wireless/ath/ath9k/rc.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +--- a/drivers/net/wireless/ath/ath9k/rc.c ++++ b/drivers/net/wireless/ath/ath9k/rc.c +@@ -1359,6 +1359,12 @@ static void ath_tx_status(void *priv, st + if (tx_info->flags & IEEE80211_TX_STAT_TX_FILTERED) + return; + ++ if (!(tx_info->flags & IEEE80211_TX_STAT_AMPDU)) { ++ tx_info->status.ampdu_ack_len = ++ (tx_info->flags & IEEE80211_TX_STAT_ACK ? 1 : 0); ++ tx_info->status.ampdu_len = 1; ++ } ++ + /* + * If an underrun error is seen assume it as an excessive retry only + * if max frame trigger level has been reached (2 KB for singel stream, diff --git a/queue-2.6.36/ath9k-clean-up-fix-aggregation-session-flush.patch b/queue-2.6.36/ath9k-clean-up-fix-aggregation-session-flush.patch new file mode 100644 index 00000000000..e1dfd0ec224 --- /dev/null +++ b/queue-2.6.36/ath9k-clean-up-fix-aggregation-session-flush.patch @@ -0,0 +1,154 @@ +From 90fa539ca3f07323da5a90f5c8f4e5cd952875e7 Mon Sep 17 00:00:00 2001 +From: Felix Fietkau +Date: Mon, 20 Sep 2010 13:45:38 +0200 +Subject: ath9k: clean up / fix aggregation session flush + +From: Felix Fietkau + +commit 90fa539ca3f07323da5a90f5c8f4e5cd952875e7 upstream. + +The tid aggregation cleanup is a bit fragile, as it discards failed +subframes in some places, and retransmits them in others. This could +block the cleanup of an existing aggregation session, if a retransmission +for a tid is issued, yet the tid is never scheduled again because of +the cleanup state. + +Fix this by getting rid of as many subframes as possible, as early +as possible, and immediately transmitting pending subframes as regular +HT frames instead of waiting for the cleanup to complete. + +Drop all pending subframes while keeping track of the Block ACK window +during aggregate tx completion to prevent sending out stale subframes, +which could confuse the receiver side. + +Signed-off-by: Felix Fietkau +Signed-off-by: John W. Linville +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/wireless/ath/ath9k/xmit.c | 63 ++++++++++++++-------------------- + 1 file changed, 26 insertions(+), 37 deletions(-) + +--- a/drivers/net/wireless/ath/ath9k/xmit.c ++++ b/drivers/net/wireless/ath/ath9k/xmit.c +@@ -61,6 +61,8 @@ static int ath_tx_num_badfrms(struct ath + struct ath_tx_status *ts, int txok); + static void ath_tx_rc_status(struct ath_buf *bf, struct ath_tx_status *ts, + int nbad, int txok, bool update_rc); ++static void ath_tx_update_baw(struct ath_softc *sc, struct ath_atx_tid *tid, ++ int seqno); + + enum { + MCS_HT20, +@@ -143,18 +145,23 @@ static void ath_tx_flush_tid(struct ath_ + struct ath_txq *txq = &sc->tx.txq[tid->ac->qnum]; + struct ath_buf *bf; + struct list_head bf_head; +- INIT_LIST_HEAD(&bf_head); ++ struct ath_tx_status ts; + +- WARN_ON(!tid->paused); ++ INIT_LIST_HEAD(&bf_head); + ++ memset(&ts, 0, sizeof(ts)); + spin_lock_bh(&txq->axq_lock); +- tid->paused = false; + + while (!list_empty(&tid->buf_q)) { + bf = list_first_entry(&tid->buf_q, struct ath_buf, list); +- BUG_ON(bf_isretried(bf)); + list_move_tail(&bf->list, &bf_head); +- ath_tx_send_ht_normal(sc, txq, tid, &bf_head); ++ ++ if (bf_isretried(bf)) { ++ ath_tx_update_baw(sc, tid, bf->bf_seqno); ++ ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0, 0); ++ } else { ++ ath_tx_send_ht_normal(sc, txq, tid, &bf_head); ++ } + } + + spin_unlock_bh(&txq->axq_lock); +@@ -433,7 +440,7 @@ static void ath_tx_complete_aggr(struct + list_move_tail(&bf->list, &bf_head); + } + +- if (!txpending) { ++ if (!txpending || (tid->state & AGGR_CLEANUP)) { + /* + * complete the acked-ones/xretried ones; update + * block-ack window +@@ -513,15 +520,12 @@ static void ath_tx_complete_aggr(struct + } + + if (tid->state & AGGR_CLEANUP) { ++ ath_tx_flush_tid(sc, tid); ++ + if (tid->baw_head == tid->baw_tail) { + tid->state &= ~AGGR_ADDBA_COMPLETE; + tid->state &= ~AGGR_CLEANUP; +- +- /* send buffered frames as singles */ +- ath_tx_flush_tid(sc, tid); + } +- rcu_read_unlock(); +- return; + } + + rcu_read_unlock(); +@@ -806,12 +810,6 @@ void ath_tx_aggr_stop(struct ath_softc * + struct ath_node *an = (struct ath_node *)sta->drv_priv; + struct ath_atx_tid *txtid = ATH_AN_2_TID(an, tid); + struct ath_txq *txq = &sc->tx.txq[txtid->ac->qnum]; +- struct ath_tx_status ts; +- struct ath_buf *bf; +- struct list_head bf_head; +- +- memset(&ts, 0, sizeof(ts)); +- INIT_LIST_HEAD(&bf_head); + + if (txtid->state & AGGR_CLEANUP) + return; +@@ -821,31 +819,22 @@ void ath_tx_aggr_stop(struct ath_softc * + return; + } + +- /* drop all software retried frames and mark this TID */ + spin_lock_bh(&txq->axq_lock); + txtid->paused = true; +- while (!list_empty(&txtid->buf_q)) { +- bf = list_first_entry(&txtid->buf_q, struct ath_buf, list); +- if (!bf_isretried(bf)) { +- /* +- * NB: it's based on the assumption that +- * software retried frame will always stay +- * at the head of software queue. +- */ +- break; +- } +- list_move_tail(&bf->list, &bf_head); +- ath_tx_update_baw(sc, txtid, bf->bf_seqno); +- ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0, 0); +- } +- spin_unlock_bh(&txq->axq_lock); + +- if (txtid->baw_head != txtid->baw_tail) { ++ /* ++ * If frames are still being transmitted for this TID, they will be ++ * cleaned up during tx completion. To prevent race conditions, this ++ * TID can only be reused after all in-progress subframes have been ++ * completed. ++ */ ++ if (txtid->baw_head != txtid->baw_tail) + txtid->state |= AGGR_CLEANUP; +- } else { ++ else + txtid->state &= ~AGGR_ADDBA_COMPLETE; +- ath_tx_flush_tid(sc, txtid); +- } ++ spin_unlock_bh(&txq->axq_lock); ++ ++ ath_tx_flush_tid(sc, txtid); + } + + void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid) diff --git a/queue-2.6.36/ath9k-fix-an-aggregation-start-related-race-condition.patch b/queue-2.6.36/ath9k-fix-an-aggregation-start-related-race-condition.patch new file mode 100644 index 00000000000..74e35638ba9 --- /dev/null +++ b/queue-2.6.36/ath9k-fix-an-aggregation-start-related-race-condition.patch @@ -0,0 +1,80 @@ +From 231c3a1f0630c07a584905507a1cb7b705a56ab7 Mon Sep 17 00:00:00 2001 +From: Felix Fietkau +Date: Mon, 20 Sep 2010 19:35:28 +0200 +Subject: ath9k: fix an aggregation start related race condition + +From: Felix Fietkau + +commit 231c3a1f0630c07a584905507a1cb7b705a56ab7 upstream. + +A new aggregation session start can be issued by mac80211, even when the +cleanup of the previous session has not completed yet. Since the data structure +for the session is not recreated, this could corrupt the block ack window +and lock up the aggregation session. Fix this by delaying the new session +until the old one has been cleaned up. + +Signed-off-by: Felix Fietkau +Signed-off-by: John W. Linville +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/wireless/ath/ath9k/ath9k.h | 4 ++-- + drivers/net/wireless/ath/ath9k/main.c | 5 +++-- + drivers/net/wireless/ath/ath9k/xmit.c | 10 ++++++++-- + 3 files changed, 13 insertions(+), 6 deletions(-) + +--- a/drivers/net/wireless/ath/ath9k/ath9k.h ++++ b/drivers/net/wireless/ath/ath9k/ath9k.h +@@ -346,8 +346,8 @@ void ath_tx_tasklet(struct ath_softc *sc + void ath_tx_edma_tasklet(struct ath_softc *sc); + void ath_tx_cabq(struct ieee80211_hw *hw, struct sk_buff *skb); + bool ath_tx_aggr_check(struct ath_softc *sc, struct ath_node *an, u8 tidno); +-void ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta, +- u16 tid, u16 *ssn); ++int ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta, ++ u16 tid, u16 *ssn); + void ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid); + void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid); + void ath9k_enable_ps(struct ath_softc *sc); +--- a/drivers/net/wireless/ath/ath9k/main.c ++++ b/drivers/net/wireless/ath/ath9k/main.c +@@ -1973,8 +1973,9 @@ static int ath9k_ampdu_action(struct iee + break; + case IEEE80211_AMPDU_TX_START: + ath9k_ps_wakeup(sc); +- ath_tx_aggr_start(sc, sta, tid, ssn); +- ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid); ++ ret = ath_tx_aggr_start(sc, sta, tid, ssn); ++ if (!ret) ++ ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid); + ath9k_ps_restore(sc); + break; + case IEEE80211_AMPDU_TX_STOP: +--- a/drivers/net/wireless/ath/ath9k/xmit.c ++++ b/drivers/net/wireless/ath/ath9k/xmit.c +@@ -792,17 +792,23 @@ static void ath_tx_sched_aggr(struct ath + status != ATH_AGGR_BAW_CLOSED); + } + +-void ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta, +- u16 tid, u16 *ssn) ++int ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta, ++ u16 tid, u16 *ssn) + { + struct ath_atx_tid *txtid; + struct ath_node *an; + + an = (struct ath_node *)sta->drv_priv; + txtid = ATH_AN_2_TID(an, tid); ++ ++ if (txtid->state & (AGGR_CLEANUP | AGGR_ADDBA_COMPLETE)) ++ return -EAGAIN; ++ + txtid->state |= AGGR_ADDBA_PROGRESS; + txtid->paused = true; + *ssn = txtid->seq_start; ++ ++ return 0; + } + + void ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid) diff --git a/queue-2.6.36/ath9k-fix-channel-flag-regd-issues-with-multiple-cards.patch b/queue-2.6.36/ath9k-fix-channel-flag-regd-issues-with-multiple-cards.patch new file mode 100644 index 00000000000..0db21a14830 --- /dev/null +++ b/queue-2.6.36/ath9k-fix-channel-flag-regd-issues-with-multiple-cards.patch @@ -0,0 +1,112 @@ +From f209f5298217cf54cd5a9163e18b08d093faf8d9 Mon Sep 17 00:00:00 2001 +From: Felix Fietkau +Date: Fri, 1 Oct 2010 01:06:53 +0200 +Subject: ath9k: fix channel flag / regd issues with multiple cards + +From: Felix Fietkau + +commit f209f5298217cf54cd5a9163e18b08d093faf8d9 upstream. + +Since the regulatory code touches the channel array, it needs to be +copied for each device instance. That way the original channel array +can also be made const. + +Signed-off-by: Felix Fietkau +Signed-off-by: John W. Linville +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/wireless/ath/ath9k/init.c | 37 ++++++++++++++++++++++++++++------ + 1 file changed, 31 insertions(+), 6 deletions(-) + +--- a/drivers/net/wireless/ath/ath9k/init.c ++++ b/drivers/net/wireless/ath/ath9k/init.c +@@ -56,7 +56,7 @@ MODULE_PARM_DESC(blink, "Enable LED blin + * on 5 MHz steps, we support the channels which we know + * we have calibration data for all cards though to make + * this static */ +-static struct ieee80211_channel ath9k_2ghz_chantable[] = { ++static const struct ieee80211_channel ath9k_2ghz_chantable[] = { + CHAN2G(2412, 0), /* Channel 1 */ + CHAN2G(2417, 1), /* Channel 2 */ + CHAN2G(2422, 2), /* Channel 3 */ +@@ -77,7 +77,7 @@ static struct ieee80211_channel ath9k_2g + * on 5 MHz steps, we support the channels which we know + * we have calibration data for all cards though to make + * this static */ +-static struct ieee80211_channel ath9k_5ghz_chantable[] = { ++static const struct ieee80211_channel ath9k_5ghz_chantable[] = { + /* _We_ call this UNII 1 */ + CHAN5G(5180, 14), /* Channel 36 */ + CHAN5G(5200, 15), /* Channel 40 */ +@@ -477,10 +477,17 @@ err: + return -EIO; + } + +-static void ath9k_init_channels_rates(struct ath_softc *sc) ++static int ath9k_init_channels_rates(struct ath_softc *sc) + { ++ void *channels; ++ + if (test_bit(ATH9K_MODE_11G, sc->sc_ah->caps.wireless_modes)) { +- sc->sbands[IEEE80211_BAND_2GHZ].channels = ath9k_2ghz_chantable; ++ channels = kmemdup(ath9k_2ghz_chantable, ++ sizeof(ath9k_2ghz_chantable), GFP_KERNEL); ++ if (!channels) ++ return -ENOMEM; ++ ++ sc->sbands[IEEE80211_BAND_2GHZ].channels = channels; + sc->sbands[IEEE80211_BAND_2GHZ].band = IEEE80211_BAND_2GHZ; + sc->sbands[IEEE80211_BAND_2GHZ].n_channels = + ARRAY_SIZE(ath9k_2ghz_chantable); +@@ -490,7 +497,15 @@ static void ath9k_init_channels_rates(st + } + + if (test_bit(ATH9K_MODE_11A, sc->sc_ah->caps.wireless_modes)) { +- sc->sbands[IEEE80211_BAND_5GHZ].channels = ath9k_5ghz_chantable; ++ channels = kmemdup(ath9k_5ghz_chantable, ++ sizeof(ath9k_5ghz_chantable), GFP_KERNEL); ++ if (!channels) { ++ if (sc->sbands[IEEE80211_BAND_2GHZ].channels) ++ kfree(sc->sbands[IEEE80211_BAND_2GHZ].channels); ++ return -ENOMEM; ++ } ++ ++ sc->sbands[IEEE80211_BAND_5GHZ].channels = channels; + sc->sbands[IEEE80211_BAND_5GHZ].band = IEEE80211_BAND_5GHZ; + sc->sbands[IEEE80211_BAND_5GHZ].n_channels = + ARRAY_SIZE(ath9k_5ghz_chantable); +@@ -499,6 +514,7 @@ static void ath9k_init_channels_rates(st + sc->sbands[IEEE80211_BAND_5GHZ].n_bitrates = + ARRAY_SIZE(ath9k_legacy_rates) - 4; + } ++ return 0; + } + + static void ath9k_init_misc(struct ath_softc *sc) +@@ -593,8 +609,11 @@ static int ath9k_init_softc(u16 devid, s + if (ret) + goto err_btcoex; + ++ ret = ath9k_init_channels_rates(sc); ++ if (ret) ++ goto err_btcoex; ++ + ath9k_init_crypto(sc); +- ath9k_init_channels_rates(sc); + ath9k_init_misc(sc); + + return 0; +@@ -751,6 +770,12 @@ static void ath9k_deinit_softc(struct at + { + int i = 0; + ++ if (sc->sbands[IEEE80211_BAND_2GHZ].channels) ++ kfree(sc->sbands[IEEE80211_BAND_2GHZ].channels); ++ ++ if (sc->sbands[IEEE80211_BAND_5GHZ].channels) ++ kfree(sc->sbands[IEEE80211_BAND_5GHZ].channels); ++ + if ((sc->btcoex.no_stomp_timer) && + sc->sc_ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE) + ath_gen_timer_free(sc->sc_ah, sc->btcoex.no_stomp_timer); diff --git a/queue-2.6.36/ath9k-fix-enabling-ani-tx-monitor-after-bg-scan.patch b/queue-2.6.36/ath9k-fix-enabling-ani-tx-monitor-after-bg-scan.patch new file mode 100644 index 00000000000..a8fa68fdbb3 --- /dev/null +++ b/queue-2.6.36/ath9k-fix-enabling-ani-tx-monitor-after-bg-scan.patch @@ -0,0 +1,108 @@ +From 48a6a468198aadb54bc5d3fdd065364d43ff5197 Mon Sep 17 00:00:00 2001 +From: Luis R. Rodriguez +Date: Thu, 16 Sep 2010 15:12:28 -0400 +Subject: ath9k: fix enabling ANI / tx monitor after bg scan + +From: Luis R. Rodriguez + +commit 48a6a468198aadb54bc5d3fdd065364d43ff5197 upstream. + +ath9k's entire logic with SC_OP_SCANNING is incorrect due to the +way mac80211 currently implements the scan complete callback and +we handle it in ath9k. This patch removes the flag completely in +preference for the SC_OP_OFFCHANNEL which is really what we wanted. + +The scanning flag was used to ensure we reset ANI to the old values +when we go back to the home channel, but if we are offchannel we +use some defaults. The flag was also used to re-enable the TX monitor. + +Without this patch we simply never re-enabled ANI and the TX monitor +after going offchannel. This means that after one background +scan we are prone to noise issues and if we had a TX hang we would +not recover. To get this to work properly we must enable ANI after +we have configured the beacon timers, otherwise hardware acts really +oddly. + +This patch has stable fixes which apply down to [2.6.36+], there +*may* be a to fix this on older kernels but requires a bit of +work since this patch relies on the new mac80211 flag +IEEE80211_CONF_OFFCHANNEL which was introduced as of 2.6.36. + +Cc: Paul Stewart +Cc: Amod Bodas +Signed-off-by: Luis R. Rodriguez +Signed-off-by: John W. Linville +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/wireless/ath/ath9k/ath9k.h | 1 - + drivers/net/wireless/ath/ath9k/main.c | 10 +++------- + drivers/net/wireless/ath/ath9k/recv.c | 4 ++-- + 3 files changed, 5 insertions(+), 10 deletions(-) + +--- a/drivers/net/wireless/ath/ath9k/ath9k.h ++++ b/drivers/net/wireless/ath/ath9k/ath9k.h +@@ -516,7 +516,6 @@ void ath_deinit_leds(struct ath_softc *s + #define SC_OP_RXFLUSH BIT(7) + #define SC_OP_LED_ASSOCIATED BIT(8) + #define SC_OP_LED_ON BIT(9) +-#define SC_OP_SCANNING BIT(10) + #define SC_OP_TSF_RESET BIT(11) + #define SC_OP_BT_PRIORITY_DETECTED BIT(12) + #define SC_OP_BT_SCAN BIT(13) +--- a/drivers/net/wireless/ath/ath9k/main.c ++++ b/drivers/net/wireless/ath/ath9k/main.c +@@ -254,14 +254,12 @@ int ath_set_channel(struct ath_softc *sc + ath_update_txpow(sc); + ath9k_hw_set_interrupts(ah, ah->imask); + +- if (!(sc->sc_flags & (SC_OP_OFFCHANNEL | SC_OP_SCANNING))) { +- ath_start_ani(common); ++ if (!(sc->sc_flags & (SC_OP_OFFCHANNEL))) { ++ ath_beacon_config(sc, NULL); + ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, 0); ++ ath_start_ani(common); + } + +- if (!(sc->sc_flags & (SC_OP_OFFCHANNEL))) +- ath_beacon_config(sc, NULL); +- + ps_restore: + ath9k_ps_restore(sc); + return r; +@@ -2040,7 +2038,6 @@ static void ath9k_sw_scan_start(struct i + + aphy->state = ATH_WIPHY_SCAN; + ath9k_wiphy_pause_all_forced(sc, aphy); +- sc->sc_flags |= SC_OP_SCANNING; + mutex_unlock(&sc->mutex); + } + +@@ -2055,7 +2052,6 @@ static void ath9k_sw_scan_complete(struc + + mutex_lock(&sc->mutex); + aphy->state = ATH_WIPHY_ACTIVE; +- sc->sc_flags &= ~SC_OP_SCANNING; + mutex_unlock(&sc->mutex); + } + +--- a/drivers/net/wireless/ath/ath9k/recv.c ++++ b/drivers/net/wireless/ath/ath9k/recv.c +@@ -292,7 +292,7 @@ static void ath_edma_start_recv(struct a + + ath_opmode_init(sc); + +- ath9k_hw_startpcureceive(sc->sc_ah, (sc->sc_flags & SC_OP_SCANNING)); ++ ath9k_hw_startpcureceive(sc->sc_ah, (sc->sc_flags & SC_OP_OFFCHANNEL)); + } + + static void ath_edma_stop_recv(struct ath_softc *sc) +@@ -496,7 +496,7 @@ int ath_startrecv(struct ath_softc *sc) + start_recv: + spin_unlock_bh(&sc->rx.rxbuflock); + ath_opmode_init(sc); +- ath9k_hw_startpcureceive(ah, (sc->sc_flags & SC_OP_SCANNING)); ++ ath9k_hw_startpcureceive(ah, (sc->sc_flags & SC_OP_OFFCHANNEL)); + + return 0; + } diff --git a/queue-2.6.36/ath9k-fix-incorrect-access-of-rate-flags-in-rc.patch b/queue-2.6.36/ath9k-fix-incorrect-access-of-rate-flags-in-rc.patch new file mode 100644 index 00000000000..f5e827792ca --- /dev/null +++ b/queue-2.6.36/ath9k-fix-incorrect-access-of-rate-flags-in-rc.patch @@ -0,0 +1,84 @@ +From 4fc4fbd1d9a05fa4f348b499aca3a6f8d3c9bbe6 Mon Sep 17 00:00:00 2001 +From: Mohammed Shafi Shajakhan +Date: Thu, 28 Oct 2010 19:51:47 +0530 +Subject: ath9k: Fix incorrect access of rate flags in RC + +From: Mohammed Shafi Shajakhan + +commit 4fc4fbd1d9a05fa4f348b499aca3a6f8d3c9bbe6 upstream. + +The index variable to access the rate flags should be obtained from the +inner loop counter which corresponds to the rate table structure.This +fixes the invalid rate selection i.e when the supported basic rate is +invalid on a particular band and also the following warning message. +Thanks to Raj for finding this out. + +Call Trace: + + [] warn_slowpath_common+0x7a/0xb0 + + [] warn_slowpath_null+0x15/0x20 + + [] ath_get_rate+0x595/0x5b0 [ath9k] + + [] ? cpumask_next_and+0x36/0x50 + + [] rate_control_get_rate+0x86/0x160 [mac80211] + + [] invoke_tx_handlers+0x81c/0x12d0 [mac80211] + + [] ieee80211_tx+0x89/0x2b0 [mac80211] + + [] ? pskb_expand_head+0x1cc/0x1f0 + + [] ieee80211_xmit+0xb5/0x1c0 [mac80211] + + [] ieee80211_tx_skb+0x4f/0x60 [mac80211] + + [] ieee80211_send_nullfunc+0x46/0x60 [mac80211] + + [] ieee80211_offchannel_stop_station+0x107/0x150 +[mac80211] + + [] ? pskb_expand_head+0x1cc/0x1f0 + + [] ieee80211_xmit+0xb5/0x1c0 [mac80211] + + [] ieee80211_tx_skb+0x4f/0x60 [mac80211] + + [] ieee80211_send_nullfunc+0x46/0x60 [mac80211] + + [] ieee80211_offchannel_stop_station+0x107/0x150 +[mac80211] + + [] ieee80211_scan_work+0x146/0x600 [mac80211] + + [] ? schedule+0x2f5/0x8e0 + + [] ? ieee80211_scan_work+0x0/0x600 [mac80211] + + [] process_one_work+0x10f/0x380 + + [] worker_thread+0x162/0x340 + + [] ? worker_thread+0x0/0x340 + +Signed-off-by: Mohammed Shafi Shajakhan +Signed-off-by: John W. Linville +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/wireless/ath/ath9k/rc.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/net/wireless/ath/ath9k/rc.c ++++ b/drivers/net/wireless/ath/ath9k/rc.c +@@ -538,7 +538,7 @@ static u8 ath_rc_setvalid_rates(struct a + for (i = 0; i < rateset->rs_nrates; i++) { + for (j = 0; j < rate_table->rate_cnt; j++) { + u32 phy = rate_table->info[j].phy; +- u16 rate_flags = rate_table->info[i].rate_flags; ++ u16 rate_flags = rate_table->info[j].rate_flags; + u8 rate = rateset->rs_rates[i]; + u8 dot11rate = rate_table->info[j].dot11rate; + diff --git a/queue-2.6.36/ath9k-fix-power-save-race-conditions.patch b/queue-2.6.36/ath9k-fix-power-save-race-conditions.patch new file mode 100644 index 00000000000..87875a76dcc --- /dev/null +++ b/queue-2.6.36/ath9k-fix-power-save-race-conditions.patch @@ -0,0 +1,102 @@ +From 8ab2cd09fecc8819bbaee2d0fd8f3a092d866ce3 Mon Sep 17 00:00:00 2001 +From: Luis R. Rodriguez +Date: Thu, 16 Sep 2010 15:12:26 -0400 +Subject: ath9k: fix power save race conditions + +From: Luis R. Rodriguez + +commit 8ab2cd09fecc8819bbaee2d0fd8f3a092d866ce3 upstream. + +ath9k has a race on putting the chip into network sleep and +having registers read from hardware. The race occurs because +although ath9k_ps_restore() locks its own callers it makes use +of some variables which get altered in the driver at different +code paths. The variables are the ps_enabled and ps_flags. + +This is easily reprodicible in large network environments when +roaming with the wpa_supplicant simple bgscan. You'd get some +0xdeadbeef read out on certain registers such as: + +ath: timeout (100000 us) on reg 0x806c: 0xdeadbeef & 0x01f00000 != 0x00000000 +ath: RX failed to go idle in 10 ms RXSM=0xdeadbeef + +ath: timeout (100000 us) on reg 0x7000: 0xdeadbeef & 0x00000003 != 0x00000000 +ath: Chip reset failed + +The fix is to protect the ath9k_config(hw, IEEE80211_CONF_CHANGE_PS) +calls with a spin_lock_irqsave() which will disable contendors for +these variables from interrupt context, timers, re-entry from mac80211 +on the same callback, and most importantly from ath9k_ps_restore() +which is the only call which will put the device into network sleep. + +There are quite a few threads and bug reports on these a few of them are: + +https://bugs.launchpad.net/ubuntu/karmic/+source/linux/+bug/407040 +http://code.google.com/p/chromium-os/issues/detail?id=5709 +http://code.google.com/p/chromium-os/issues/detail?id=5943 + +Stable fixes apply to [2.6.32+] + +Cc: Paul Stewart +Cc: Amod Bodas +Signed-off-by: Luis R. Rodriguez +Signed-off-by: John W. Linville +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/wireless/ath/ath9k/main.c | 5 ++++- + drivers/net/wireless/ath/ath9k/recv.c | 3 +++ + 2 files changed, 7 insertions(+), 1 deletion(-) + +--- a/drivers/net/wireless/ath/ath9k/main.c ++++ b/drivers/net/wireless/ath/ath9k/main.c +@@ -1558,6 +1558,8 @@ static int ath9k_config(struct ieee80211 + * IEEE80211_CONF_CHANGE_PS is only passed by mac80211 for STA mode. + */ + if (changed & IEEE80211_CONF_CHANGE_PS) { ++ unsigned long flags; ++ spin_lock_irqsave(&sc->sc_pm_lock, flags); + if (conf->flags & IEEE80211_CONF_PS) { + sc->ps_flags |= PS_ENABLED; + /* +@@ -1572,7 +1574,7 @@ static int ath9k_config(struct ieee80211 + sc->ps_enabled = false; + sc->ps_flags &= ~(PS_ENABLED | + PS_NULLFUNC_COMPLETED); +- ath9k_setpower(sc, ATH9K_PM_AWAKE); ++ ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_AWAKE); + if (!(ah->caps.hw_caps & + ATH9K_HW_CAP_AUTOSLEEP)) { + ath9k_hw_setrxabort(sc->sc_ah, 0); +@@ -1587,6 +1589,7 @@ static int ath9k_config(struct ieee80211 + } + } + } ++ spin_unlock_irqrestore(&sc->sc_pm_lock, flags); + } + + if (changed & IEEE80211_CONF_CHANGE_MONITOR) { +--- a/drivers/net/wireless/ath/ath9k/recv.c ++++ b/drivers/net/wireless/ath/ath9k/recv.c +@@ -1096,6 +1096,7 @@ int ath_rx_tasklet(struct ath_softc *sc, + u8 rx_status_len = ah->caps.rx_status_len; + u64 tsf = 0; + u32 tsf_lower = 0; ++ unsigned long flags; + + if (edma) + dma_type = DMA_BIDIRECTIONAL; +@@ -1204,11 +1205,13 @@ int ath_rx_tasklet(struct ath_softc *sc, + sc->rx.rxotherant = 0; + } + ++ spin_lock_irqsave(&sc->sc_pm_lock, flags); + if (unlikely(ath9k_check_auto_sleep(sc) || + (sc->ps_flags & (PS_WAIT_FOR_BEACON | + PS_WAIT_FOR_CAB | + PS_WAIT_FOR_PSPOLL_DATA)))) + ath_rx_ps(sc, skb); ++ spin_unlock_irqrestore(&sc->sc_pm_lock, flags); + + ath_rx_send_to_mac80211(hw, sc, skb, rxs); + diff --git a/queue-2.6.36/ath9k-fix-regression-on-beacon-loss-after-bgscan.patch b/queue-2.6.36/ath9k-fix-regression-on-beacon-loss-after-bgscan.patch new file mode 100644 index 00000000000..3803abb038a --- /dev/null +++ b/queue-2.6.36/ath9k-fix-regression-on-beacon-loss-after-bgscan.patch @@ -0,0 +1,85 @@ +From 52b8ac92496e03d6b5619204d7f3bae6ce6eae45 Mon Sep 17 00:00:00 2001 +From: Luis R. Rodriguez +Date: Thu, 16 Sep 2010 15:12:27 -0400 +Subject: ath9k: fix regression on beacon loss after bgscan + +From: Luis R. Rodriguez + +commit 52b8ac92496e03d6b5619204d7f3bae6ce6eae45 upstream. + +When we return to the home channel we were never reseting our beacon +timers, this was casued by the fact that the scanning flag was still +on even after we returned to our home channel. There are also other +reasons why we would get a reset and if we are not off channel +we always need to resynch our beacon timers, because a reset will +clear them. + +This bug is a regression introduced on 2.6.36. The order of the +changes are as follows: + +5ee08656 - Sat Jul 31 - ath9k: prevent calibration during off-channel activity +a0daa0e7 - Tue Jul 27 - Revert "mac80211: fix sw scan bracketing" +543708be - Fri Jun 18 - mac80211: fix sw scan bracketing + +mcgrof@tux ~/linux-2.6-allstable (git::master)$ git describe \ + --contains 5ee0865615f65f84e6ee9174771a6716c29e08e1 +v2.6.36-rc1~43^2~34^2~22 + +mcgrof@tux ~/linux-2.6-allstable (git::master)$ git describe \ + --contains a0daa0e7592ada797d6835f11529097aabc27ad2 +v2.6.36-rc1~571^2~64^2~13 + +mcgrof@tux ~/linux-2.6-allstable (git::master)$ git describe \ + --contains 543708be320d7df692d24b349ca01a947b340764 +v2.6.36-rc1~571^2~107^2~187 + +So 5ee08656 would have worked if a0daa0e7 was not committed but +it was so this means 5ee08656 was broken since it assumed that +when we were in the channel change routine the scan flag would +be lifted. As it turns out the scan flag will be set when we +are already on the home channel. + +For more details refer to: + +http://code.google.com/p/chromium-os/issues/detail?id=5715 + +These issues will need to be considered for our solution on +reshifting the scan complete callback location on mac80211 on +current development kernel work. + +This patch has stable fixes which apply down to [2.6.36+] + +Cc: Paul Stewart +Cc: Amod Bodas +Signed-off-by: Luis R. Rodriguez +Signed-off-by: John W. Linville +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/wireless/ath/ath9k/main.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +--- a/drivers/net/wireless/ath/ath9k/main.c ++++ b/drivers/net/wireless/ath/ath9k/main.c +@@ -257,9 +257,11 @@ int ath_set_channel(struct ath_softc *sc + if (!(sc->sc_flags & (SC_OP_OFFCHANNEL | SC_OP_SCANNING))) { + ath_start_ani(common); + ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, 0); +- ath_beacon_config(sc, NULL); + } + ++ if (!(sc->sc_flags & (SC_OP_OFFCHANNEL))) ++ ath_beacon_config(sc, NULL); ++ + ps_restore: + ath9k_ps_restore(sc); + return r; +@@ -953,7 +955,7 @@ int ath_reset(struct ath_softc *sc, bool + + ath_update_txpow(sc); + +- if (sc->sc_flags & SC_OP_BEACONS) ++ if ((sc->sc_flags & SC_OP_BEACONS) || !(sc->sc_flags & (SC_OP_OFFCHANNEL))) + ath_beacon_config(sc, NULL); /* restart beacons */ + + ath9k_hw_set_interrupts(ah, ah->imask); diff --git a/queue-2.6.36/ath9k-fix-regression-which-disabled-ps-on-ath9k.patch b/queue-2.6.36/ath9k-fix-regression-which-disabled-ps-on-ath9k.patch new file mode 100644 index 00000000000..0a65f61edd4 --- /dev/null +++ b/queue-2.6.36/ath9k-fix-regression-which-disabled-ps-on-ath9k.patch @@ -0,0 +1,42 @@ +From 008443def34db1dcc8016763587a288254ea5735 Mon Sep 17 00:00:00 2001 +From: Luis R. Rodriguez +Date: Thu, 16 Sep 2010 15:12:36 -0400 +Subject: ath9k: fix regression which disabled ps on ath9k + +From: Luis R. Rodriguez + +commit 008443def34db1dcc8016763587a288254ea5735 upstream. + +The patch titled "ath9k: Add new file init.c" shuffled some code +around but in dong so for some reason also removed the revision +check for disablign power save. Add this revision check again +so we can get power save re-enabled again by default on cards +newer than AR5416 and AR5418. + +$ git describe --contains 556242049cc3992d0ee625e9f15c4b00ea4baac8 +v2.6.34-rc1~233^2~49^2~343 + +This patch has fixes for stable kernels [2.6.34+]. + +Cc: Paul Stewart +Cc: Amod Bodas +Signed-off-by: Luis R. Rodriguez +Signed-off-by: John W. Linville +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/wireless/ath/ath9k/init.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/net/wireless/ath/ath9k/init.c ++++ b/drivers/net/wireless/ath/ath9k/init.c +@@ -660,7 +660,8 @@ void ath9k_set_hw_capab(struct ath_softc + BIT(NL80211_IFTYPE_ADHOC) | + BIT(NL80211_IFTYPE_MESH_POINT); + +- hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; ++ if (AR_SREV_5416(sc->sc_ah)) ++ hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; + + hw->queues = 4; + hw->max_rates = 4; diff --git a/queue-2.6.36/ath9k-fix-regression-which-prevents-chip-sleep-after-cab-data.patch b/queue-2.6.36/ath9k-fix-regression-which-prevents-chip-sleep-after-cab-data.patch new file mode 100644 index 00000000000..7850068effb --- /dev/null +++ b/queue-2.6.36/ath9k-fix-regression-which-prevents-chip-sleep-after-cab-data.patch @@ -0,0 +1,56 @@ +From 3fac6dfdcd2b893c22b20a03dd1bf1af8b627c4b Mon Sep 17 00:00:00 2001 +From: Senthil Balasubramanian +Date: Thu, 16 Sep 2010 15:12:35 -0400 +Subject: ath9k: fix regression which prevents chip sleep after CAB data + +From: Senthil Balasubramanian + +commit 3fac6dfdcd2b893c22b20a03dd1bf1af8b627c4b upstream. + +The patch: + +commit 293dc5dfdbcc16cde06e40a688394cc8ab083e48 +Author: Gabor Juhos +Date: Fri Jun 19 12:17:48 2009 +0200 + + ath9k: remove ath_rx_ps_back_to_sleep helper + + This helper only clears the SC_OP_WAIT_FOR_{BEACON,CAB} flags. + Remove it and clear these flags directly in the approptiate + places instead. + + Changes-licensed-under: ISC + Signed-off-by: Gabor Juhos + Signed-off-by: John W. Linville + +introduced a regression which forgot to lift the beacon flag +after we received all broadcast and multicast data. This meant +we never went to sleep consuming about ~650mW on idle. This pretty +much broke power save completely. + +This patch has fixes for stable kernels [2.6.32+]. + +Cc: Paul Stewart +Cc: Sameer Nanda +Cc: Gabor Juhos +Cc: Amod Bodas +Signed-off-by: Senthil Balasubramanian +Signed-off-by: Luis R. Rodriguez +Signed-off-by: John W. Linville +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/wireless/ath/ath9k/recv.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/net/wireless/ath/ath9k/recv.c ++++ b/drivers/net/wireless/ath/ath9k/recv.c +@@ -631,7 +631,7 @@ static void ath_rx_ps(struct ath_softc * + * No more broadcast/multicast frames to be received at this + * point. + */ +- sc->ps_flags &= ~PS_WAIT_FOR_CAB; ++ sc->ps_flags &= ~(PS_WAIT_FOR_CAB | PS_WAIT_FOR_BEACON); + ath_print(common, ATH_DBG_PS, + "All PS CAB frames received, back to sleep\n"); + } else if ((sc->ps_flags & PS_WAIT_FOR_PSPOLL_DATA) && diff --git a/queue-2.6.36/ath9k-fix-spurious-mic-failure-reports.patch b/queue-2.6.36/ath9k-fix-spurious-mic-failure-reports.patch new file mode 100644 index 00000000000..369afaf240d --- /dev/null +++ b/queue-2.6.36/ath9k-fix-spurious-mic-failure-reports.patch @@ -0,0 +1,112 @@ +From 56363ddeeed3afc5277ca227209773bc1042cc7b Mon Sep 17 00:00:00 2001 +From: Felix Fietkau +Date: Sat, 28 Aug 2010 18:21:21 +0200 +Subject: ath9k: fix spurious MIC failure reports + +From: Felix Fietkau + +commit 56363ddeeed3afc5277ca227209773bc1042cc7b upstream. + +According to the hardware documentation, the MIC failure bit is only +valid if the frame was decrypted using a valid TKIP key and is not a +fragment. +In some setups I've seen hardware-reported MIC failures on an AP that +was configured for CCMP only, so it's clear that additional checks are +necessary. + +Signed-off-by: Felix Fietkau +Signed-off-by: John W. Linville +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/wireless/ath/ath.h | 1 + + drivers/net/wireless/ath/ath9k/common.c | 11 +++++++++++ + drivers/net/wireless/ath/ath9k/mac.c | 3 ++- + drivers/net/wireless/ath/ath9k/recv.c | 19 +++++++++++-------- + 4 files changed, 25 insertions(+), 9 deletions(-) + +--- a/drivers/net/wireless/ath/ath.h ++++ b/drivers/net/wireless/ath/ath.h +@@ -119,6 +119,7 @@ struct ath_common { + + u32 keymax; + DECLARE_BITMAP(keymap, ATH_KEYMAX); ++ DECLARE_BITMAP(tkip_keymap, ATH_KEYMAX); + u8 splitmic; + + struct ath_regulatory regulatory; +--- a/drivers/net/wireless/ath/ath9k/common.c ++++ b/drivers/net/wireless/ath/ath9k/common.c +@@ -366,9 +366,13 @@ int ath9k_cmn_key_config(struct ath_comm + set_bit(idx, common->keymap); + if (key->alg == ALG_TKIP) { + set_bit(idx + 64, common->keymap); ++ set_bit(idx, common->tkip_keymap); ++ set_bit(idx + 64, common->tkip_keymap); + if (common->splitmic) { + set_bit(idx + 32, common->keymap); + set_bit(idx + 64 + 32, common->keymap); ++ set_bit(idx + 32, common->tkip_keymap); ++ set_bit(idx + 64 + 32, common->tkip_keymap); + } + } + +@@ -393,10 +397,17 @@ void ath9k_cmn_key_delete(struct ath_com + return; + + clear_bit(key->hw_key_idx + 64, common->keymap); ++ ++ clear_bit(key->hw_key_idx, common->tkip_keymap); ++ clear_bit(key->hw_key_idx + 64, common->tkip_keymap); ++ + if (common->splitmic) { + ath9k_hw_keyreset(ah, key->hw_key_idx + 32); + clear_bit(key->hw_key_idx + 32, common->keymap); + clear_bit(key->hw_key_idx + 64 + 32, common->keymap); ++ ++ clear_bit(key->hw_key_idx + 32, common->tkip_keymap); ++ clear_bit(key->hw_key_idx + 64 + 32, common->tkip_keymap); + } + } + EXPORT_SYMBOL(ath9k_cmn_key_delete); +--- a/drivers/net/wireless/ath/ath9k/mac.c ++++ b/drivers/net/wireless/ath/ath9k/mac.c +@@ -711,7 +711,8 @@ int ath9k_hw_rxprocdesc(struct ath_hw *a + rs->rs_phyerr = phyerr; + } else if (ads.ds_rxstatus8 & AR_DecryptCRCErr) + rs->rs_status |= ATH9K_RXERR_DECRYPT; +- else if (ads.ds_rxstatus8 & AR_MichaelErr) ++ else if ((ads.ds_rxstatus8 & AR_MichaelErr) && ++ rs->rs_keyix != ATH9K_RXKEYIX_INVALID) + rs->rs_status |= ATH9K_RXERR_MIC; + else if (ads.ds_rxstatus8 & AR_KeyMiss) + rs->rs_status |= ATH9K_RXERR_DECRYPT; +--- a/drivers/net/wireless/ath/ath9k/recv.c ++++ b/drivers/net/wireless/ath/ath9k/recv.c +@@ -870,15 +870,18 @@ static bool ath9k_rx_accept(struct ath_c + if (rx_stats->rs_status & ATH9K_RXERR_DECRYPT) { + *decrypt_error = true; + } else if (rx_stats->rs_status & ATH9K_RXERR_MIC) { +- if (ieee80211_is_ctl(fc)) +- /* +- * Sometimes, we get invalid +- * MIC failures on valid control frames. +- * Remove these mic errors. +- */ +- rx_stats->rs_status &= ~ATH9K_RXERR_MIC; +- else ++ /* ++ * The MIC error bit is only valid if the frame ++ * is not a control frame or fragment, and it was ++ * decrypted using a valid TKIP key. ++ */ ++ if (!ieee80211_is_ctl(fc) && ++ !ieee80211_has_morefrags(fc) && ++ !(le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG) && ++ test_bit(rx_stats->rs_keyix, common->tkip_keymap)) + rxs->flag |= RX_FLAG_MMIC_ERROR; ++ else ++ rx_stats->rs_status &= ~ATH9K_RXERR_MIC; + } + /* + * Reject error frames with the exception of diff --git a/queue-2.6.36/ath9k-fix-tx-aggregation-flush-on-ar9003.patch b/queue-2.6.36/ath9k-fix-tx-aggregation-flush-on-ar9003.patch new file mode 100644 index 00000000000..70d6254cdb5 --- /dev/null +++ b/queue-2.6.36/ath9k-fix-tx-aggregation-flush-on-ar9003.patch @@ -0,0 +1,57 @@ +From e609e2ea2cdb3448e7849703179cd792a28dcc55 Mon Sep 17 00:00:00 2001 +From: Felix Fietkau +Date: Wed, 27 Oct 2010 02:15:05 +0200 +Subject: ath9k: fix tx aggregation flush on AR9003 + +From: Felix Fietkau + +commit e609e2ea2cdb3448e7849703179cd792a28dcc55 upstream. + +Completing aggregate frames can lead to new buffers being pushed into +the tid queues due to software retransmission. +When the tx queues are being drained, all pending aggregates must be +completed before the tid queues get drained, otherwise buffers might be +leaked. + +Signed-off-by: Felix Fietkau +Signed-off-by: John W. Linville +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/wireless/ath/ath9k/xmit.c | 18 +++++++++--------- + 1 file changed, 9 insertions(+), 9 deletions(-) + +--- a/drivers/net/wireless/ath/ath9k/xmit.c ++++ b/drivers/net/wireless/ath/ath9k/xmit.c +@@ -1101,15 +1101,6 @@ void ath_draintxq(struct ath_softc *sc, + txq->axq_tx_inprogress = false; + spin_unlock_bh(&txq->axq_lock); + +- /* flush any pending frames if aggregation is enabled */ +- if (sc->sc_flags & SC_OP_TXAGGR) { +- if (!retry_tx) { +- spin_lock_bh(&txq->axq_lock); +- ath_txq_drain_pending_buffers(sc, txq); +- spin_unlock_bh(&txq->axq_lock); +- } +- } +- + if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) { + spin_lock_bh(&txq->axq_lock); + while (!list_empty(&txq->txq_fifo_pending)) { +@@ -1130,6 +1121,15 @@ void ath_draintxq(struct ath_softc *sc, + } + spin_unlock_bh(&txq->axq_lock); + } ++ ++ /* flush any pending frames if aggregation is enabled */ ++ if (sc->sc_flags & SC_OP_TXAGGR) { ++ if (!retry_tx) { ++ spin_lock_bh(&txq->axq_lock); ++ ath_txq_drain_pending_buffers(sc, txq); ++ spin_unlock_bh(&txq->axq_lock); ++ } ++ } + } + + void ath_drain_all_txq(struct ath_softc *sc, bool retry_tx) diff --git a/queue-2.6.36/ath9k-fix-tx-struck-state-with-paprd.patch b/queue-2.6.36/ath9k-fix-tx-struck-state-with-paprd.patch new file mode 100644 index 00000000000..8971fa33c70 --- /dev/null +++ b/queue-2.6.36/ath9k-fix-tx-struck-state-with-paprd.patch @@ -0,0 +1,59 @@ +From 9094537c3a9ef9e127e844254a74186735c9a90b Mon Sep 17 00:00:00 2001 +From: Vasanthakumar Thiagarajan +Date: Mon, 20 Sep 2010 22:54:46 -0700 +Subject: ath9k: Fix tx struck state with paprd + +From: Vasanthakumar Thiagarajan + +commit 9094537c3a9ef9e127e844254a74186735c9a90b upstream. + +Paprd needs to be done only on active chains(not for all the chains +that hw can support). The paprd training frames which are sent +for inactive chains would be hanging on the hw queue without +getting transmitted and would make the connection so unstable. +This issue happens only with the hw which supports paprd cal(ar9003). + +Signed-off-by: Vasanthakumar Thiagarajan +Signed-off-by: John W. Linville +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/wireless/ath/ath9k/main.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +--- a/drivers/net/wireless/ath/ath9k/main.c ++++ b/drivers/net/wireless/ath/ath9k/main.c +@@ -269,6 +269,7 @@ static void ath_paprd_activate(struct at + { + struct ath_hw *ah = sc->sc_ah; + struct ath9k_hw_cal_data *caldata = ah->caldata; ++ struct ath_common *common = ath9k_hw_common(ah); + int chain; + + if (!caldata || !caldata->paprd_done) +@@ -277,7 +278,7 @@ static void ath_paprd_activate(struct at + ath9k_ps_wakeup(sc); + ar9003_paprd_enable(ah, false); + for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) { +- if (!(ah->caps.tx_chainmask & BIT(chain))) ++ if (!(common->tx_chainmask & BIT(chain))) + continue; + + ar9003_paprd_populate_single_table(ah, caldata, chain); +@@ -299,6 +300,7 @@ void ath_paprd_calibrate(struct work_str + struct ieee80211_supported_band *sband = &sc->sbands[band]; + struct ath_tx_control txctl; + struct ath9k_hw_cal_data *caldata = ah->caldata; ++ struct ath_common *common = ath9k_hw_common(ah); + int qnum, ftype; + int chain_ok = 0; + int chain; +@@ -332,7 +334,7 @@ void ath_paprd_calibrate(struct work_str + ath9k_ps_wakeup(sc); + ar9003_paprd_init_table(ah); + for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) { +- if (!(ah->caps.tx_chainmask & BIT(chain))) ++ if (!(common->tx_chainmask & BIT(chain))) + continue; + + chain_ok = 0; diff --git a/queue-2.6.36/ath9k-lock-reset-and-pcu-start-stopping.patch b/queue-2.6.36/ath9k-lock-reset-and-pcu-start-stopping.patch new file mode 100644 index 00000000000..5f775b53055 --- /dev/null +++ b/queue-2.6.36/ath9k-lock-reset-and-pcu-start-stopping.patch @@ -0,0 +1,182 @@ +From 5e848f789d60000d39d9a5f26ab02dbdd963f6cd Mon Sep 17 00:00:00 2001 +From: Luis R. Rodriguez +Date: Wed, 20 Oct 2010 16:07:06 -0700 +Subject: ath9k: lock reset and PCU start/stopping + +From: Luis R. Rodriguez + +commit 5e848f789d60000d39d9a5f26ab02dbdd963f6cd upstream. + +Apart from locking the start and stop PCU we need +to ensure we also content starting and stopping the PCU +between hardware resets. + +This is part of a series that will help resolve the bug: + +https://bugzilla.kernel.org/show_bug.cgi?id=14624 + +For more details about this issue refer to: + +http://marc.info/?l=linux-wireless&m=128629803703756&w=2 + +Cc: Ben Greear +Cc: Kyungwan Nam +Signed-off-by: Luis R. Rodriguez +Tested-by: Ben Greear +Signed-off-by: John W. Linville +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/wireless/ath/ath9k/main.c | 27 +++++++++++++++++++++++++++ + drivers/net/wireless/ath/ath9k/recv.c | 2 -- + 2 files changed, 27 insertions(+), 2 deletions(-) + +--- a/drivers/net/wireless/ath/ath9k/main.c ++++ b/drivers/net/wireless/ath/ath9k/main.c +@@ -213,6 +213,9 @@ int ath_set_channel(struct ath_softc *sc + */ + ath9k_hw_set_interrupts(ah, 0); + ath_drain_all_txq(sc, false); ++ ++ spin_lock_bh(&sc->rx.pcu_lock); ++ + stopped = ath_stoprecv(sc); + + /* XXX: do not flush receive queue here. We don't want +@@ -239,6 +242,7 @@ int ath_set_channel(struct ath_softc *sc + "reset status %d\n", + channel->center_freq, r); + spin_unlock_bh(&sc->sc_resetlock); ++ spin_unlock_bh(&sc->rx.pcu_lock); + goto ps_restore; + } + spin_unlock_bh(&sc->sc_resetlock); +@@ -247,9 +251,12 @@ int ath_set_channel(struct ath_softc *sc + ath_print(common, ATH_DBG_FATAL, + "Unable to restart recv logic\n"); + r = -EIO; ++ spin_unlock_bh(&sc->rx.pcu_lock); + goto ps_restore; + } + ++ spin_unlock_bh(&sc->rx.pcu_lock); ++ + ath_cache_conf_rate(sc, &hw->conf); + ath_update_txpow(sc); + ath9k_hw_set_interrupts(ah, ah->imask); +@@ -840,6 +847,7 @@ void ath_radio_enable(struct ath_softc * + if (!ah->curchan) + ah->curchan = ath_get_curchannel(sc, sc->hw); + ++ spin_lock_bh(&sc->rx.pcu_lock); + spin_lock_bh(&sc->sc_resetlock); + r = ath9k_hw_reset(ah, ah->curchan, ah->caldata, false); + if (r) { +@@ -854,8 +862,10 @@ void ath_radio_enable(struct ath_softc * + if (ath_startrecv(sc) != 0) { + ath_print(common, ATH_DBG_FATAL, + "Unable to restart recv logic\n"); ++ spin_unlock_bh(&sc->rx.pcu_lock); + return; + } ++ spin_unlock_bh(&sc->rx.pcu_lock); + + if (sc->sc_flags & SC_OP_BEACONS) + ath_beacon_config(sc, NULL); /* restart beacons */ +@@ -894,6 +904,9 @@ void ath_radio_disable(struct ath_softc + ath9k_hw_set_interrupts(ah, 0); + + ath_drain_all_txq(sc, false); /* clear pending tx frames */ ++ ++ spin_lock_bh(&sc->rx.pcu_lock); ++ + ath_stoprecv(sc); /* turn off frame recv */ + ath_flushrecv(sc); /* flush recv queue */ + +@@ -911,6 +924,9 @@ void ath_radio_disable(struct ath_softc + spin_unlock_bh(&sc->sc_resetlock); + + ath9k_hw_phy_disable(ah); ++ ++ spin_unlock_bh(&sc->rx.pcu_lock); ++ + ath9k_hw_configpcipowersave(ah, 1, 1); + ath9k_ps_restore(sc); + ath9k_setpower(sc, ATH9K_PM_FULL_SLEEP); +@@ -930,6 +946,9 @@ int ath_reset(struct ath_softc *sc, bool + + ath9k_hw_set_interrupts(ah, 0); + ath_drain_all_txq(sc, retry_tx); ++ ++ spin_lock_bh(&sc->rx.pcu_lock); ++ + ath_stoprecv(sc); + ath_flushrecv(sc); + +@@ -944,6 +963,8 @@ int ath_reset(struct ath_softc *sc, bool + ath_print(common, ATH_DBG_FATAL, + "Unable to start recv logic\n"); + ++ spin_unlock_bh(&sc->rx.pcu_lock); ++ + /* + * We may be doing a reset in response to a request + * that changes the channel so update any state that +@@ -1108,6 +1129,7 @@ static int ath9k_start(struct ieee80211_ + * be followed by initialization of the appropriate bits + * and then setup of the interrupt mask. + */ ++ spin_lock_bh(&sc->rx.pcu_lock); + spin_lock_bh(&sc->sc_resetlock); + r = ath9k_hw_reset(ah, init_channel, ah->caldata, false); + if (r) { +@@ -1116,6 +1138,7 @@ static int ath9k_start(struct ieee80211_ + "(freq %u MHz)\n", r, + curchan->center_freq); + spin_unlock_bh(&sc->sc_resetlock); ++ spin_unlock_bh(&sc->rx.pcu_lock); + goto mutex_unlock; + } + spin_unlock_bh(&sc->sc_resetlock); +@@ -1137,8 +1160,10 @@ static int ath9k_start(struct ieee80211_ + ath_print(common, ATH_DBG_FATAL, + "Unable to start recv logic\n"); + r = -EIO; ++ spin_unlock_bh(&sc->rx.pcu_lock); + goto mutex_unlock; + } ++ spin_unlock_bh(&sc->rx.pcu_lock); + + /* Setup our intr mask. */ + ah->imask = ATH9K_INT_TX | ATH9K_INT_RXEOL | +@@ -1340,12 +1365,14 @@ static void ath9k_stop(struct ieee80211_ + * before setting the invalid flag. */ + ath9k_hw_set_interrupts(ah, 0); + ++ spin_lock_bh(&sc->rx.pcu_lock); + if (!(sc->sc_flags & SC_OP_INVALID)) { + ath_drain_all_txq(sc, false); + ath_stoprecv(sc); + ath9k_hw_phy_disable(ah); + } else + sc->rx.rxlink = NULL; ++ spin_unlock_bh(&sc->rx.pcu_lock); + + /* disable HAL and put h/w to sleep */ + ath9k_hw_disable(ah); +--- a/drivers/net/wireless/ath/ath9k/recv.c ++++ b/drivers/net/wireless/ath/ath9k/recv.c +@@ -523,13 +523,11 @@ bool ath_stoprecv(struct ath_softc *sc) + + void ath_flushrecv(struct ath_softc *sc) + { +- spin_lock_bh(&sc->rx.pcu_lock); + sc->sc_flags |= SC_OP_RXFLUSH; + if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) + ath_rx_tasklet(sc, 1, true); + ath_rx_tasklet(sc, 1, false); + sc->sc_flags &= ~SC_OP_RXFLUSH; +- spin_unlock_bh(&sc->rx.pcu_lock); + } + + static bool ath_beacon_dtim_pending_cab(struct sk_buff *skb) diff --git a/queue-2.6.36/ath9k-rename-rxflushlock-to-pcu_lock.patch b/queue-2.6.36/ath9k-rename-rxflushlock-to-pcu_lock.patch new file mode 100644 index 00000000000..891e4ca3f19 --- /dev/null +++ b/queue-2.6.36/ath9k-rename-rxflushlock-to-pcu_lock.patch @@ -0,0 +1,93 @@ +From b79b33c4baf2532aac2c0924dce5a738099b888c Mon Sep 17 00:00:00 2001 +From: Luis R. Rodriguez +Date: Wed, 20 Oct 2010 16:07:05 -0700 +Subject: ath9k: rename rxflushlock to pcu_lock + +From: Luis R. Rodriguez + +commit b79b33c4baf2532aac2c0924dce5a738099b888c upstream. + +The real way to lock RX is to contend on the PCU +and reset, this will be fixed in the next patch but for +now just do the renames so that the next patch which changes +the locking order is crystal clear. + +This is part of a series that will help resolve the bug: + +https://bugzilla.kernel.org/show_bug.cgi?id=14624 + +For more details about this issue refer to: + +http://marc.info/?l=linux-wireless&m=128629803703756&w=2 + +Cc: Ben Greear +Cc: Kyungwan Nam +Signed-off-by: Luis R. Rodriguez +Tested-by: Ben Greear +Signed-off-by: John W. Linville +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/wireless/ath/ath9k/ath9k.h | 2 +- + drivers/net/wireless/ath/ath9k/main.c | 4 ++-- + drivers/net/wireless/ath/ath9k/recv.c | 6 +++--- + 3 files changed, 6 insertions(+), 6 deletions(-) + +--- a/drivers/net/wireless/ath/ath9k/ath9k.h ++++ b/drivers/net/wireless/ath/ath9k/ath9k.h +@@ -312,7 +312,7 @@ struct ath_rx { + u8 rxotherant; + u32 *rxlink; + unsigned int rxfilter; +- spinlock_t rxflushlock; ++ spinlock_t pcu_lock; + spinlock_t rxbuflock; + struct list_head rxbuf; + struct ath_descdma rxdma; +--- a/drivers/net/wireless/ath/ath9k/main.c ++++ b/drivers/net/wireless/ath/ath9k/main.c +@@ -587,7 +587,7 @@ void ath9k_tasklet(unsigned long data) + rxmask = (ATH9K_INT_RX | ATH9K_INT_RXEOL | ATH9K_INT_RXORN); + + if (status & rxmask) { +- spin_lock_bh(&sc->rx.rxflushlock); ++ spin_lock_bh(&sc->rx.pcu_lock); + + /* Check for high priority Rx first */ + if ((ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) && +@@ -595,7 +595,7 @@ void ath9k_tasklet(unsigned long data) + ath_rx_tasklet(sc, 0, true); + + ath_rx_tasklet(sc, 0, false); +- spin_unlock_bh(&sc->rx.rxflushlock); ++ spin_unlock_bh(&sc->rx.pcu_lock); + } + + if (status & ATH9K_INT_TX) { +--- a/drivers/net/wireless/ath/ath9k/recv.c ++++ b/drivers/net/wireless/ath/ath9k/recv.c +@@ -310,7 +310,7 @@ int ath_rx_init(struct ath_softc *sc, in + struct ath_buf *bf; + int error = 0; + +- spin_lock_init(&sc->rx.rxflushlock); ++ spin_lock_init(&sc->rx.pcu_lock); + sc->sc_flags &= ~SC_OP_RXFLUSH; + spin_lock_init(&sc->rx.rxbuflock); + +@@ -522,13 +522,13 @@ bool ath_stoprecv(struct ath_softc *sc) + + void ath_flushrecv(struct ath_softc *sc) + { +- spin_lock_bh(&sc->rx.rxflushlock); ++ spin_lock_bh(&sc->rx.pcu_lock); + sc->sc_flags |= SC_OP_RXFLUSH; + if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) + ath_rx_tasklet(sc, 1, true); + ath_rx_tasklet(sc, 1, false); + sc->sc_flags &= ~SC_OP_RXFLUSH; +- spin_unlock_bh(&sc->rx.rxflushlock); ++ spin_unlock_bh(&sc->rx.pcu_lock); + } + + static bool ath_beacon_dtim_pending_cab(struct sk_buff *skb) diff --git a/queue-2.6.36/ath9k-resume-aggregation-immediately-after-a-hardware-reset.patch b/queue-2.6.36/ath9k-resume-aggregation-immediately-after-a-hardware-reset.patch new file mode 100644 index 00000000000..9fd7b19cada --- /dev/null +++ b/queue-2.6.36/ath9k-resume-aggregation-immediately-after-a-hardware-reset.patch @@ -0,0 +1,67 @@ +From fac6b6a065da42f826088c58bddad82e1b1ccb40 Mon Sep 17 00:00:00 2001 +From: Felix Fietkau +Date: Sat, 23 Oct 2010 17:45:38 +0200 +Subject: ath9k: resume aggregation immediately after a hardware reset + +From: Felix Fietkau + +commit fac6b6a065da42f826088c58bddad82e1b1ccb40 upstream. + +Since aggregation is usually triggered by tx completion, a hardware +reset (because of beacon stuck, tx hang or baseband hang) can +significantly delay the transmission of the next AMPDU (until the next +tx completion event). +Fix this by rescheduling aggregation after such a reset. + +Signed-off-by: Felix Fietkau +Signed-off-by: John W. Linville +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/wireless/ath/ath9k/beacon.c | 2 +- + drivers/net/wireless/ath/ath9k/main.c | 4 ++-- + drivers/net/wireless/ath/ath9k/xmit.c | 2 +- + 3 files changed, 4 insertions(+), 4 deletions(-) + +--- a/drivers/net/wireless/ath/ath9k/beacon.c ++++ b/drivers/net/wireless/ath/ath9k/beacon.c +@@ -366,7 +366,7 @@ void ath_beacon_tasklet(unsigned long da + ath_print(common, ATH_DBG_BEACON, + "beacon is officially stuck\n"); + sc->sc_flags |= SC_OP_TSF_RESET; +- ath_reset(sc, false); ++ ath_reset(sc, true); + } + + return; +--- a/drivers/net/wireless/ath/ath9k/main.c ++++ b/drivers/net/wireless/ath/ath9k/main.c +@@ -554,7 +554,7 @@ void ath_hw_check(struct work_struct *wo + + msleep(1); + } +- ath_reset(sc, false); ++ ath_reset(sc, true); + + out: + ath9k_ps_restore(sc); +@@ -572,7 +572,7 @@ void ath9k_tasklet(unsigned long data) + ath9k_ps_wakeup(sc); + + if (status & ATH9K_INT_FATAL) { +- ath_reset(sc, false); ++ ath_reset(sc, true); + ath9k_ps_restore(sc); + return; + } +--- a/drivers/net/wireless/ath/ath9k/xmit.c ++++ b/drivers/net/wireless/ath/ath9k/xmit.c +@@ -2206,7 +2206,7 @@ static void ath_tx_complete_poll_work(st + ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_RESET, + "tx hung, resetting the chip\n"); + ath9k_ps_wakeup(sc); +- ath_reset(sc, false); ++ ath_reset(sc, true); + ath9k_ps_restore(sc); + } + diff --git a/queue-2.6.36/ath9k_htc-add-new-devices-into-ar7010.patch b/queue-2.6.36/ath9k_htc-add-new-devices-into-ar7010.patch new file mode 100644 index 00000000000..94faa2a0408 --- /dev/null +++ b/queue-2.6.36/ath9k_htc-add-new-devices-into-ar7010.patch @@ -0,0 +1,65 @@ +From 7cbf2611dac8d5f76fe64795a9426b8c97e6c3f8 Mon Sep 17 00:00:00 2001 +From: Rajkumar Manoharan +Date: Wed, 10 Nov 2010 17:51:25 +0530 +Subject: ath9k_htc: Add new devices into AR7010 + +From: Rajkumar Manoharan + +commit 7cbf2611dac8d5f76fe64795a9426b8c97e6c3f8 upstream. + +Treat new PIDs (0xA704, 0x1200) as AR7010 devices. + +Signed-off-by: Rajkumar Manoharan +Signed-off-by: John W. Linville +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/wireless/ath/ath9k/hif_usb.c | 4 ++++ + drivers/net/wireless/ath/ath9k/htc_drv_init.c | 2 ++ + drivers/net/wireless/ath/ath9k/reg.h | 4 +++- + 3 files changed, 9 insertions(+), 1 deletion(-) + +--- a/drivers/net/wireless/ath/ath9k/hif_usb.c ++++ b/drivers/net/wireless/ath/ath9k/hif_usb.c +@@ -803,6 +803,8 @@ static int ath9k_hif_usb_download_fw(str + case 0x7010: + case 0x7015: + case 0x9018: ++ case 0xA704: ++ case 0x1200: + firm_offset = AR7010_FIRMWARE_TEXT; + break; + default: +@@ -909,6 +911,8 @@ static int ath9k_hif_usb_probe(struct us + case 0x7010: + case 0x7015: + case 0x9018: ++ case 0xA704: ++ case 0x1200: + if (le16_to_cpu(udev->descriptor.bcdDevice) == 0x0202) + hif_dev->fw_name = FIRMWARE_AR7010_1_1; + else +--- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c ++++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c +@@ -247,6 +247,8 @@ static int ath9k_init_htc_services(struc + case 0x7010: + case 0x7015: + case 0x9018: ++ case 0xA704: ++ case 0x1200: + priv->htc->credits = 45; + break; + default: +--- a/drivers/net/wireless/ath/ath9k/reg.h ++++ b/drivers/net/wireless/ath/ath9k/reg.h +@@ -901,7 +901,9 @@ + #define AR_DEVID_7010(_ah) \ + (((_ah)->hw_version.devid == 0x7010) || \ + ((_ah)->hw_version.devid == 0x7015) || \ +- ((_ah)->hw_version.devid == 0x9018)) ++ ((_ah)->hw_version.devid == 0x9018) || \ ++ ((_ah)->hw_version.devid == 0xA704) || \ ++ ((_ah)->hw_version.devid == 0x1200)) + + #define AR9287_HTC_DEVID(_ah) \ + (((_ah)->hw_version.devid == 0x7015) || \ diff --git a/queue-2.6.36/ath9k_htc-add-support-for-device-id-3346.patch b/queue-2.6.36/ath9k_htc-add-support-for-device-id-3346.patch new file mode 100644 index 00000000000..ff5dffa8ef9 --- /dev/null +++ b/queue-2.6.36/ath9k_htc-add-support-for-device-id-3346.patch @@ -0,0 +1,29 @@ +From ac618d70aeb681df7b77c1107fdf26f3249f855f Mon Sep 17 00:00:00 2001 +From: Haitao Zhang +Date: Sun, 7 Nov 2010 12:50:24 +0800 +Subject: ath9k_htc: Add support for device ID 3346 + +From: Haitao Zhang + +commit ac618d70aeb681df7b77c1107fdf26f3249f855f upstream. + +This patch adds support for USB dongle with device ID 3346 from IMC Networks. + +Signed-off-by: Haitao Zhang +Signed-off-by: John W. Linville +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/wireless/ath/ath9k/hif_usb.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/net/wireless/ath/ath9k/hif_usb.c ++++ b/drivers/net/wireless/ath/ath9k/hif_usb.c +@@ -35,6 +35,7 @@ static struct usb_device_id ath9k_hif_us + { USB_DEVICE(0x07D1, 0x3A10) }, /* Dlink Wireless 150 */ + { USB_DEVICE(0x13D3, 0x3327) }, /* Azurewave */ + { USB_DEVICE(0x13D3, 0x3328) }, /* Azurewave */ ++ { USB_DEVICE(0x13D3, 0x3346) }, /* IMC Networks */ + { USB_DEVICE(0x04CA, 0x4605) }, /* Liteon */ + { USB_DEVICE(0x083A, 0xA704) }, /* SMC Networks */ + { }, diff --git a/queue-2.6.36/ath9k_htc-avoid-setting-qos-control-for-non-qos-frames.patch b/queue-2.6.36/ath9k_htc-avoid-setting-qos-control-for-non-qos-frames.patch new file mode 100644 index 00000000000..0d94597a3f1 --- /dev/null +++ b/queue-2.6.36/ath9k_htc-avoid-setting-qos-control-for-non-qos-frames.patch @@ -0,0 +1,31 @@ +From 3bf30b56c4f0a1c4fae34050b7db4527c92891e8 Mon Sep 17 00:00:00 2001 +From: Rajkumar Manoharan +Date: Thu, 18 Nov 2010 12:19:52 +0530 +Subject: ath9k_htc: Avoid setting QoS control for non-QoS frames + +From: Rajkumar Manoharan + +commit 3bf30b56c4f0a1c4fae34050b7db4527c92891e8 upstream. + +Setting tid information in the TX header is required only for QoS +frames. Not handling this case causes severe data loss with some APs. + +Signed-off-by: Rajkumar Manoharan +Signed-off-by: John W. Linville +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/wireless/ath/ath9k/htc_drv_txrx.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c ++++ b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c +@@ -121,7 +121,7 @@ int ath9k_htc_tx_start(struct ath9k_htc_ + tx_hdr.data_type = ATH9K_HTC_NORMAL; + } + +- if (ieee80211_is_data(fc)) { ++ if (ieee80211_is_data_qos(fc)) { + qc = ieee80211_get_qos_ctl(hdr); + tx_hdr.tidno = qc[0] & IEEE80211_QOS_CTL_TID_MASK; + } diff --git a/queue-2.6.36/ath9k_htc-set-proper-firmware-offset-for-netgear-wnda3200.patch b/queue-2.6.36/ath9k_htc-set-proper-firmware-offset-for-netgear-wnda3200.patch new file mode 100644 index 00000000000..813b7f4b919 --- /dev/null +++ b/queue-2.6.36/ath9k_htc-set-proper-firmware-offset-for-netgear-wnda3200.patch @@ -0,0 +1,42 @@ +From d654567dec75782d6fd9add4b7b9c50e0926d369 Mon Sep 17 00:00:00 2001 +From: Rajkumar Manoharan +Date: Wed, 27 Oct 2010 12:02:54 +0530 +Subject: ath9k_htc: Set proper firmware offset for Netgear WNDA3200 + +From: Rajkumar Manoharan + +commit d654567dec75782d6fd9add4b7b9c50e0926d369 upstream. + +Netgear WNDA3200 device uses ar7010 firmware but it is failed to set +correct firmware offset on firmware download which causes device initialization +failure. + +Signed-off-by: Rajkumar Manoharan +Signed-off-by: John W. Linville +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/wireless/ath/ath9k/hif_usb.c | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) + +--- a/drivers/net/wireless/ath/ath9k/hif_usb.c ++++ b/drivers/net/wireless/ath/ath9k/hif_usb.c +@@ -799,10 +799,16 @@ static int ath9k_hif_usb_download_fw(str + } + kfree(buf); + +- if ((hif_dev->device_id == 0x7010) || (hif_dev->device_id == 0x7015)) ++ switch (hif_dev->device_id) { ++ case 0x7010: ++ case 0x7015: ++ case 0x9018: + firm_offset = AR7010_FIRMWARE_TEXT; +- else ++ break; ++ default: + firm_offset = AR9271_FIRMWARE_TEXT; ++ break; ++ } + + /* + * Issue FW download complete command to firmware. diff --git a/queue-2.6.36/ath9k_htc-update-usb-device-id-list.patch b/queue-2.6.36/ath9k_htc-update-usb-device-id-list.patch new file mode 100644 index 00000000000..1f801a490ce --- /dev/null +++ b/queue-2.6.36/ath9k_htc-update-usb-device-id-list.patch @@ -0,0 +1,35 @@ +From 32b089558c54792028f14ae830ca7c0a8d9ac9a3 Mon Sep 17 00:00:00 2001 +From: Rajkumar Manoharan +Date: Wed, 10 Nov 2010 17:51:24 +0530 +Subject: ath9k_htc: Update usb device ID list + +From: Rajkumar Manoharan + +commit 32b089558c54792028f14ae830ca7c0a8d9ac9a3 upstream. + +Added new VID/PIDs into supported devices list + +Signed-off-by: Rajkumar Manoharan +Signed-off-by: John W. Linville +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/wireless/ath/ath9k/hif_usb.c | 5 +++++ + 1 file changed, 5 insertions(+) + +--- a/drivers/net/wireless/ath/ath9k/hif_usb.c ++++ b/drivers/net/wireless/ath/ath9k/hif_usb.c +@@ -36,8 +36,13 @@ static struct usb_device_id ath9k_hif_us + { USB_DEVICE(0x13D3, 0x3327) }, /* Azurewave */ + { USB_DEVICE(0x13D3, 0x3328) }, /* Azurewave */ + { USB_DEVICE(0x13D3, 0x3346) }, /* IMC Networks */ ++ { USB_DEVICE(0x13D3, 0x3348) }, /* Azurewave */ ++ { USB_DEVICE(0x13D3, 0x3349) }, /* Azurewave */ ++ { USB_DEVICE(0x13D3, 0x3350) }, /* Azurewave */ + { USB_DEVICE(0x04CA, 0x4605) }, /* Liteon */ + { USB_DEVICE(0x083A, 0xA704) }, /* SMC Networks */ ++ { USB_DEVICE(0x040D, 0x3801) }, /* VIA */ ++ { USB_DEVICE(0x1668, 0x1200) }, /* Verizon */ + { }, + }; + diff --git a/queue-2.6.36/ath9k_hw-fix-ar9280-surprise-removal-during-frequent-idle-on-off.patch b/queue-2.6.36/ath9k_hw-fix-ar9280-surprise-removal-during-frequent-idle-on-off.patch new file mode 100644 index 00000000000..78615b02239 --- /dev/null +++ b/queue-2.6.36/ath9k_hw-fix-ar9280-surprise-removal-during-frequent-idle-on-off.patch @@ -0,0 +1,92 @@ +From f119da3015712dc32bdf1c311652479e02dcb49a Mon Sep 17 00:00:00 2001 +From: Vasanthakumar Thiagarajan +Date: Thu, 4 Nov 2010 17:41:25 -0700 +Subject: ath9k_hw: Fix AR9280 surprise removal during frequent idle on/off + +From: Vasanthakumar Thiagarajan + +commit f119da3015712dc32bdf1c311652479e02dcb49a upstream. + +Bit 22 of AR_WA should be set to fix the situation where chip reset +is asynchronous to clock of analog shift registers, such that when +reset is released, it could mess up the values of analog shift registers +and cause some hw issue on AR9280. + +This bit is write only, but the driver does a read-modify-write +on AR_WA without setting bit 22 in ar9002_hw_configpcipowersave() +during radio disable. This causes surprise removal of hw. It can +never recover from this state and the hw will become usable only +after a power on/off cycle, and sometimes only during a cold reboot. + +This issue can be triggered by doing frequent roaming with the +simple/test-roam script available from the wifi-test project [1] +when roaming between APs quickly. When roaming there is a is a high +possibility that the device being put into idle (radio disable) state +by mac80211 during AUTH->ASSOC. A device hardware reset would fail +and the kernel would output: + +[40251.363799] ath: AWAKE -> FULL-SLEEP +[40251.363815] ieee80211 phy17: device no longer idle - working +[40251.363817] ath: Marking phy17 as not-idle +[40251.363819] ath: FULL-SLEEP -> AWAKE +[40251.415978] pciehp 0000:00:1c.3:pcie04: Card not present on Slot(3) +[40251.419896] ath: ah->misc_mode 0x4 +[40251.428138] pciehp 0000:00:1c.3:pcie04: Card present on Slot(3) +[40251.532247] ath: timeout (100000 us) on reg 0x9860: 0xffffffff & 0x00000001 != 0x00000000 +[40251.532250] ath: Unable to reset channel (2462 MHz), reset status -5 +[40251.532422] ath: Set channel: 5745 MHz +[40251.540639] ath: Failed to stop TX DMA in 100 msec after killing last frame +[40251.548826] ath: Failed to stop TX DMA in 100 msec after killing last frame +[40251.557023] ath: Failed to stop TX DMA in 100 msec after killing last frame +[40251.565211] ath: Failed to stop TX DMA in 100 msec after killing last frame +[40251.573415] ath: Failed to stop TX DMA in 100 msec after killing last frame +[40251.581603] ath: Failed to stop TX DMA in 100 msec after killing last frame +[40251.581606] ath: Failed to stop TX DMA. Resetting hardware! +[40251.592679] ath: DMA failed to stop in 10 ms AR_CR=0xffffffff AR_DIAG_SW=0xffffffff +[40251.703330] ath: timeout (100000 us) on reg 0x7000: 0xffffffff & 0x00000003 != 0x00000000 +[40251.703333] ath: RTC stuck in MAC reset +[40251.703334] ath: Chip reset failed +[40251.703335] ath: Unable to reset hardware; reset status -22 + +This is currently only reproducible with some HB92 (Half Mini-PCIE) +cards but the fix applies to all AR9280 cards. This patch fixes this +issue by setting bit 22 during radio disable. + +This patch has fixes for all kernels that has ath9k. + +[1] http://wireless.kernel.org/en/developers/Testing/wifi-test + +Cc: kyungwan.nam@atheros.com +Cc: amod.bodas@atheros.com +Cc: david.quan@atheros.com +Signed-off-by: Vasanthakumar Thiagarajan +Signed-off-by: John W. Linville +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/wireless/ath/ath9k/ar9002_hw.c | 3 +++ + drivers/net/wireless/ath/ath9k/reg.h | 1 + + 2 files changed, 4 insertions(+) + +--- a/drivers/net/wireless/ath/ath9k/ar9002_hw.c ++++ b/drivers/net/wireless/ath/ath9k/ar9002_hw.c +@@ -411,6 +411,9 @@ static void ar9002_hw_configpcipowersave + val &= ~(AR_WA_BIT6 | AR_WA_BIT7); + } + ++ if (AR_SREV_9280(ah)) ++ val |= AR_WA_BIT22; ++ + if (AR_SREV_9285E_20(ah)) + val |= AR_WA_BIT23; + +--- a/drivers/net/wireless/ath/ath9k/reg.h ++++ b/drivers/net/wireless/ath/ath9k/reg.h +@@ -709,6 +709,7 @@ + #define AR_WA_RESET_EN (1 << 18) /* Sw Control to enable PCI-Reset to POR (bit 15) */ + #define AR_WA_ANALOG_SHIFT (1 << 20) + #define AR_WA_POR_SHORT (1 << 21) /* PCI-E Phy reset control */ ++#define AR_WA_BIT22 (1 << 22) + #define AR9285_WA_DEFAULT 0x004a050b + #define AR9280_WA_DEFAULT 0x0040073b + #define AR_WA_DEFAULT 0x0000073f diff --git a/queue-2.6.36/ath9k_hw-fix-divide-by-zero-cases-in-paprd.patch b/queue-2.6.36/ath9k_hw-fix-divide-by-zero-cases-in-paprd.patch new file mode 100644 index 00000000000..c832bb573e6 --- /dev/null +++ b/queue-2.6.36/ath9k_hw-fix-divide-by-zero-cases-in-paprd.patch @@ -0,0 +1,62 @@ +From 2d3fca180710c6832de22c44155ce6a3a4953c6b Mon Sep 17 00:00:00 2001 +From: Senthil Balasubramanian +Date: Tue, 19 Oct 2010 20:01:41 +0530 +Subject: ath9k_hw: Fix divide by zero cases in paprd. + +From: Senthil Balasubramanian + +commit 2d3fca180710c6832de22c44155ce6a3a4953c6b upstream. + +We are not handling all divide by zero cases in paprd. +Add additional checks for divide by zero cases in papard. + +This patch has fixes intended for kernel 2.6.36. + +Signed-off-by: Senthil Balasubramanian +Signed-off-by: John W. Linville +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/wireless/ath/ath9k/ar9003_paprd.c | 14 +++++++++----- + 1 file changed, 9 insertions(+), 5 deletions(-) + +--- a/drivers/net/wireless/ath/ath9k/ar9003_paprd.c ++++ b/drivers/net/wireless/ath/ath9k/ar9003_paprd.c +@@ -347,6 +347,10 @@ static bool create_pa_curve(u32 *data_L, + (((Y[6] - Y[3]) * 1 << scale_factor) + + (x_est[6] - x_est[3])) / (x_est[6] - x_est[3]); + ++ /* prevent division by zero */ ++ if (G_fxp == 0) ++ return false; ++ + Y_intercept = + (G_fxp * (x_est[0] - x_est[3]) + + (1 << scale_factor)) / (1 << scale_factor) + Y[3]; +@@ -356,14 +360,12 @@ static bool create_pa_curve(u32 *data_L, + + for (i = 0; i <= 3; i++) { + y_est[i] = i * 32; +- +- /* prevent division by zero */ +- if (G_fxp == 0) +- return false; +- + x_est[i] = ((y_est[i] * 1 << scale_factor) + G_fxp) / G_fxp; + } + ++ if (y_est[max_index] == 0) ++ return false; ++ + x_est_fxp1_nonlin = + x_est[max_index] - ((1 << scale_factor) * y_est[max_index] + + G_fxp) / G_fxp; +@@ -457,6 +459,8 @@ static bool create_pa_curve(u32 *data_L, + + Q_scale_B = find_proper_scale(find_expn(abs(scale_B)), 10); + scale_B = scale_B / (1 << Q_scale_B); ++ if (scale_B == 0) ++ return false; + Q_beta = find_proper_scale(find_expn(abs(beta_raw)), 10); + Q_alpha = find_proper_scale(find_expn(abs(alpha_raw)), 10); + beta_raw = beta_raw / (1 << Q_beta); diff --git a/queue-2.6.36/ath9k_hw-fix-memory-leak-on-ath9k_hw_rf_alloc_ext_banks-failure.patch b/queue-2.6.36/ath9k_hw-fix-memory-leak-on-ath9k_hw_rf_alloc_ext_banks-failure.patch new file mode 100644 index 00000000000..c76ac173a61 --- /dev/null +++ b/queue-2.6.36/ath9k_hw-fix-memory-leak-on-ath9k_hw_rf_alloc_ext_banks-failure.patch @@ -0,0 +1,30 @@ +From 48a7c3df14d0cda850337a9b3f9e667a0b12a996 Mon Sep 17 00:00:00 2001 +From: Rajkumar Manoharan +Date: Mon, 8 Nov 2010 20:40:53 +0530 +Subject: ath9k_hw: Fix memory leak on ath9k_hw_rf_alloc_ext_banks failure + +From: Rajkumar Manoharan + +commit 48a7c3df14d0cda850337a9b3f9e667a0b12a996 upstream. + +The allocated externel radio banks have to be freed in +case of ath9k_hw_rf_alloc_ext_banks failure. + +Signed-off-by: Rajkumar Manoharan +Signed-off-by: John W. Linville +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/wireless/ath/ath9k/hw.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/net/wireless/ath/ath9k/hw.c ++++ b/drivers/net/wireless/ath/ath9k/hw.c +@@ -486,6 +486,7 @@ static int ath9k_hw_post_init(struct ath + ath_print(ath9k_hw_common(ah), ATH_DBG_FATAL, + "Failed allocating banks for " + "external radio\n"); ++ ath9k_hw_rf_free_ext_banks(ah); + return ecode; + } + diff --git a/queue-2.6.36/ath9k_hw-fix-tx-carrier-leakage-for-ieee-compliance-on-ar9003-2.2.patch b/queue-2.6.36/ath9k_hw-fix-tx-carrier-leakage-for-ieee-compliance-on-ar9003-2.2.patch new file mode 100644 index 00000000000..23c2c9280c4 --- /dev/null +++ b/queue-2.6.36/ath9k_hw-fix-tx-carrier-leakage-for-ieee-compliance-on-ar9003-2.2.patch @@ -0,0 +1,452 @@ +From 0dfa6dbb7372e581d3beb38b11772152114796b8 Mon Sep 17 00:00:00 2001 +From: Luis R. Rodriguez +Date: Mon, 18 Oct 2010 22:47:54 -0700 +Subject: ath9k_hw: Fix TX carrier leakage for IEEE compliance on AR9003 2.2 + +From: Luis R. Rodriguez + +commit 0dfa6dbb7372e581d3beb38b11772152114796b8 upstream. + +This updates the initvals for the AR9003 2.2 chipsets. The initvals +are the initial register values we use for our registers upon hardware +reset. This synchs up the initvals to match what our latest recommendation +from our systems engineering team. + +The description of changes in this update: + + Improves ability to support very strong Rx conditions. + Enhances DFS support for AP-mode. + Improves performance of Tx carrier leak calibration. + Adds support for Japan channel 14 Tx filtering requirements. + Improves Tx power accuracy. + +Impact: + + Update required to address degraded throughput at very short range. + Update required for AP-mode DFS certification. + Update required to comply to IEEE Tx carrier leak specification. + May not meet expected +/- 2 dB Tx power accuracy without update. + +The most important fix here would be the TX carrier leakage required +to comply with IEEE 802.11 specifications. The group of changes have +been tested all together in one release. + +References: + + Osprey 2.2 header file ver #33 + +Checksums: + +$ ./initvals -f ar9003-2p2 +0x000000004a488fc7 ar9300_2p2_radio_postamble +0x0000000046cb1300 ar9300Modes_lowest_ob_db_tx_gain_table_2p2 +0x00000000e912711f ar9300Modes_fast_clock_2p2 +0x0000000037ac0ee8 ar9300_2p2_radio_core +0x00000000047a7700 ar9300Common_rx_gain_table_merlin_2p2 +0x0000000003f783bb ar9300_2p2_mac_postamble +0x00000000301fc841 ar9300_2p2_soc_postamble +0x000000005ec8075f ar9200_merlin_2p2_radio_core +0x0000000083372ffa ar9300_2p2_baseband_postamble +0x00000000c4f59974 ar9300_2p2_baseband_core +0x00000000e20d2e72 ar9300Modes_high_power_tx_gain_table_2p2 +0x000000007fd55c70 ar9300Modes_high_ob_db_tx_gain_table_2p2 +0x0000000029495000 ar9300Common_rx_gain_table_2p2 +0x0000000042cb1300 ar9300Modes_low_ob_db_tx_gain_table_2p2 +0x00000000c4739cd6 ar9300_2p2_mac_core +0x000000003521a300 ar9300Common_wo_xlna_rx_gain_table_2p2 +0x00000000a15ccf1b ar9300_2p2_soc_preamble +0x0000000029734396 ar9300PciePhy_pll_on_clkreq_disable_L1_2p2 +0x000000002d834396 ar9300PciePhy_clkreq_enable_L1_2p2 +0x0000000029834396 ar9300PciePhy_clkreq_disable_L1_2p2 + +$ ./initvals -f ar9003-2p2 | sha1sum +0ceddb5cf66737610fb51f04cf3e9ff71870c7b4 - + +Cc: Yixiang Li +Cc: Don Breslin +Signed-off-by: Luis R. Rodriguez +Signed-off-by: John W. Linville +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h | 191 +++++++++++++------ + 1 file changed, 135 insertions(+), 56 deletions(-) + +--- a/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h ++++ b/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h +@@ -34,6 +34,10 @@ static const u32 ar9300_2p2_radio_postam + + static const u32 ar9300Modes_lowest_ob_db_tx_gain_table_2p2[][5] = { + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ ++ {0x0000a2dc, 0x0380c7fc, 0x0380c7fc, 0x00637800, 0x00637800}, ++ {0x0000a2e0, 0x0000f800, 0x0000f800, 0x03838000, 0x03838000}, ++ {0x0000a2e4, 0x03ff0000, 0x03ff0000, 0x03fc0000, 0x03fc0000}, ++ {0x0000a2e8, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9}, + {0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a504, 0x06000003, 0x06000003, 0x04000002, 0x04000002}, +@@ -99,6 +103,30 @@ static const u32 ar9300Modes_lowest_ob_d + {0x0000a5f4, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec}, + {0x0000a5f8, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec}, + {0x0000a5fc, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec}, ++ {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, ++ {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, ++ {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, ++ {0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, ++ {0x0000a610, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, ++ {0x0000a614, 0x01404000, 0x01404000, 0x01404000, 0x01404000}, ++ {0x0000a618, 0x01404501, 0x01404501, 0x01404501, 0x01404501}, ++ {0x0000a61c, 0x02008802, 0x02008802, 0x02008501, 0x02008501}, ++ {0x0000a620, 0x0300cc03, 0x0300cc03, 0x0280ca03, 0x0280ca03}, ++ {0x0000a624, 0x0300cc03, 0x0300cc03, 0x03010c04, 0x03010c04}, ++ {0x0000a628, 0x0300cc03, 0x0300cc03, 0x04014c04, 0x04014c04}, ++ {0x0000a62c, 0x03810c03, 0x03810c03, 0x04015005, 0x04015005}, ++ {0x0000a630, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005}, ++ {0x0000a634, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005}, ++ {0x0000a638, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005}, ++ {0x0000a63c, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005}, ++ {0x0000b2dc, 0x0380c7fc, 0x0380c7fc, 0x00637800, 0x00637800}, ++ {0x0000b2e0, 0x0000f800, 0x0000f800, 0x03838000, 0x03838000}, ++ {0x0000b2e4, 0x03ff0000, 0x03ff0000, 0x03fc0000, 0x03fc0000}, ++ {0x0000b2e8, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, ++ {0x0000c2dc, 0x0380c7fc, 0x0380c7fc, 0x00637800, 0x00637800}, ++ {0x0000c2e0, 0x0000f800, 0x0000f800, 0x03838000, 0x03838000}, ++ {0x0000c2e4, 0x03ff0000, 0x03ff0000, 0x03fc0000, 0x03fc0000}, ++ {0x0000c2e8, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x00016044, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4}, + {0x00016048, 0x62480001, 0x62480001, 0x62480001, 0x62480001}, + {0x00016068, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, +@@ -118,7 +146,7 @@ static const u32 ar9300Modes_fast_clock_ + {0x00008014, 0x044c044c, 0x08980898}, + {0x0000801c, 0x148ec02b, 0x148ec057}, + {0x00008318, 0x000044c0, 0x00008980}, +- {0x00009e00, 0x03721821, 0x03721821}, ++ {0x00009e00, 0x0372131c, 0x0372131c}, + {0x0000a230, 0x0000000b, 0x00000016}, + {0x0000a254, 0x00000898, 0x00001130}, + }; +@@ -595,15 +623,16 @@ static const u32 ar9300_2p2_baseband_pos + {0x0000982c, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4}, + {0x00009830, 0x0000059c, 0x0000059c, 0x0000119c, 0x0000119c}, + {0x00009c00, 0x000000c4, 0x000000c4, 0x000000c4, 0x000000c4}, +- {0x00009e00, 0x0372161e, 0x0372161e, 0x037216a0, 0x037216a0}, +- {0x00009e04, 0x00802020, 0x00802020, 0x00802020, 0x00802020}, ++ {0x00009e00, 0x0372111a, 0x0372111a, 0x037216a0, 0x037216a0}, ++ {0x00009e04, 0x001c2020, 0x001c2020, 0x001c2020, 0x001c2020}, + {0x00009e0c, 0x6c4000e2, 0x6d4000e2, 0x6d4000e2, 0x6c4000e2}, + {0x00009e10, 0x7ec88d2e, 0x7ec88d2e, 0x7ec84d2e, 0x7ec84d2e}, +- {0x00009e14, 0x31395d5e, 0x3139605e, 0x3139605e, 0x31395d5e}, ++ {0x00009e14, 0x37b95d5e, 0x37b9605e, 0x3379605e, 0x33795d5e}, + {0x00009e18, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x00009e1c, 0x0001cf9c, 0x0001cf9c, 0x00021f9c, 0x00021f9c}, + {0x00009e20, 0x000003b5, 0x000003b5, 0x000003ce, 0x000003ce}, + {0x00009e2c, 0x0000001c, 0x0000001c, 0x00000021, 0x00000021}, ++ {0x00009e3c, 0xcf946220, 0xcf946220, 0xcf946222, 0xcf946222}, + {0x00009e44, 0x02321e27, 0x02321e27, 0x02291e27, 0x02291e27}, + {0x00009e48, 0x5030201a, 0x5030201a, 0x50302012, 0x50302012}, + {0x00009fc8, 0x0003f000, 0x0003f000, 0x0001a000, 0x0001a000}, +@@ -624,16 +653,16 @@ static const u32 ar9300_2p2_baseband_pos + {0x0000a28c, 0x00022222, 0x00022222, 0x00022222, 0x00022222}, + {0x0000a2c4, 0x00158d18, 0x00158d18, 0x00158d18, 0x00158d18}, + {0x0000a2d0, 0x00071981, 0x00071981, 0x00071981, 0x00071982}, +- {0x0000a2d8, 0xf999a83a, 0xf999a83a, 0xf999a83a, 0xf999a83a}, ++ {0x0000a2d8, 0x7999a83a, 0x7999a83a, 0x7999a83a, 0x7999a83a}, + {0x0000a358, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a830, 0x0000019c, 0x0000019c, 0x0000019c, 0x0000019c}, +- {0x0000ae04, 0x00800000, 0x00800000, 0x00800000, 0x00800000}, ++ {0x0000ae04, 0x001c0000, 0x001c0000, 0x001c0000, 0x001c0000}, + {0x0000ae18, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000ae1c, 0x0000019c, 0x0000019c, 0x0000019c, 0x0000019c}, + {0x0000ae20, 0x000001b5, 0x000001b5, 0x000001ce, 0x000001ce}, + {0x0000b284, 0x00000000, 0x00000000, 0x00000150, 0x00000150}, + {0x0000b830, 0x0000019c, 0x0000019c, 0x0000019c, 0x0000019c}, +- {0x0000be04, 0x00800000, 0x00800000, 0x00800000, 0x00800000}, ++ {0x0000be04, 0x001c0000, 0x001c0000, 0x001c0000, 0x001c0000}, + {0x0000be18, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000be1c, 0x0000019c, 0x0000019c, 0x0000019c, 0x0000019c}, + {0x0000be20, 0x000001b5, 0x000001b5, 0x000001ce, 0x000001ce}, +@@ -649,13 +678,13 @@ static const u32 ar9300_2p2_baseband_cor + {0x00009814, 0x9280c00a}, + {0x00009818, 0x00000000}, + {0x0000981c, 0x00020028}, +- {0x00009834, 0x5f3ca3de}, ++ {0x00009834, 0x6400a290}, + {0x00009838, 0x0108ecff}, + {0x0000983c, 0x14750600}, + {0x00009880, 0x201fff00}, + {0x00009884, 0x00001042}, + {0x000098a4, 0x00200400}, +- {0x000098b0, 0x52440bbe}, ++ {0x000098b0, 0x32840bbe}, + {0x000098d0, 0x004b6a8e}, + {0x000098d4, 0x00000820}, + {0x000098dc, 0x00000000}, +@@ -681,7 +710,6 @@ static const u32 ar9300_2p2_baseband_cor + {0x00009e30, 0x06336f77}, + {0x00009e34, 0x6af6532f}, + {0x00009e38, 0x0cc80c00}, +- {0x00009e3c, 0xcf946222}, + {0x00009e40, 0x0d261820}, + {0x00009e4c, 0x00001004}, + {0x00009e50, 0x00ff03f1}, +@@ -694,7 +722,7 @@ static const u32 ar9300_2p2_baseband_cor + {0x0000a220, 0x00000000}, + {0x0000a224, 0x00000000}, + {0x0000a228, 0x10002310}, +- {0x0000a22c, 0x01036a1e}, ++ {0x0000a22c, 0x01036a27}, + {0x0000a23c, 0x00000000}, + {0x0000a244, 0x0c000000}, + {0x0000a2a0, 0x00000001}, +@@ -702,10 +730,6 @@ static const u32 ar9300_2p2_baseband_cor + {0x0000a2c8, 0x00000000}, + {0x0000a2cc, 0x18c43433}, + {0x0000a2d4, 0x00000000}, +- {0x0000a2dc, 0x00000000}, +- {0x0000a2e0, 0x00000000}, +- {0x0000a2e4, 0x00000000}, +- {0x0000a2e8, 0x00000000}, + {0x0000a2ec, 0x00000000}, + {0x0000a2f0, 0x00000000}, + {0x0000a2f4, 0x00000000}, +@@ -753,33 +777,17 @@ static const u32 ar9300_2p2_baseband_cor + {0x0000a430, 0x1ce739ce}, + {0x0000a434, 0x00000000}, + {0x0000a438, 0x00001801}, +- {0x0000a43c, 0x00000000}, ++ {0x0000a43c, 0x00100000}, + {0x0000a440, 0x00000000}, + {0x0000a444, 0x00000000}, + {0x0000a448, 0x06000080}, + {0x0000a44c, 0x00000001}, + {0x0000a450, 0x00010000}, + {0x0000a458, 0x00000000}, +- {0x0000a600, 0x00000000}, +- {0x0000a604, 0x00000000}, +- {0x0000a608, 0x00000000}, +- {0x0000a60c, 0x00000000}, +- {0x0000a610, 0x00000000}, +- {0x0000a614, 0x00000000}, +- {0x0000a618, 0x00000000}, +- {0x0000a61c, 0x00000000}, +- {0x0000a620, 0x00000000}, +- {0x0000a624, 0x00000000}, +- {0x0000a628, 0x00000000}, +- {0x0000a62c, 0x00000000}, +- {0x0000a630, 0x00000000}, +- {0x0000a634, 0x00000000}, +- {0x0000a638, 0x00000000}, +- {0x0000a63c, 0x00000000}, + {0x0000a640, 0x00000000}, + {0x0000a644, 0x3fad9d74}, + {0x0000a648, 0x0048060a}, +- {0x0000a64c, 0x00000637}, ++ {0x0000a64c, 0x00003c37}, + {0x0000a670, 0x03020100}, + {0x0000a674, 0x09080504}, + {0x0000a678, 0x0d0c0b0a}, +@@ -802,10 +810,6 @@ static const u32 ar9300_2p2_baseband_cor + {0x0000a8f4, 0x00000000}, + {0x0000b2d0, 0x00000080}, + {0x0000b2d4, 0x00000000}, +- {0x0000b2dc, 0x00000000}, +- {0x0000b2e0, 0x00000000}, +- {0x0000b2e4, 0x00000000}, +- {0x0000b2e8, 0x00000000}, + {0x0000b2ec, 0x00000000}, + {0x0000b2f0, 0x00000000}, + {0x0000b2f4, 0x00000000}, +@@ -820,10 +824,6 @@ static const u32 ar9300_2p2_baseband_cor + {0x0000b8f4, 0x00000000}, + {0x0000c2d0, 0x00000080}, + {0x0000c2d4, 0x00000000}, +- {0x0000c2dc, 0x00000000}, +- {0x0000c2e0, 0x00000000}, +- {0x0000c2e4, 0x00000000}, +- {0x0000c2e8, 0x00000000}, + {0x0000c2ec, 0x00000000}, + {0x0000c2f0, 0x00000000}, + {0x0000c2f4, 0x00000000}, +@@ -835,6 +835,10 @@ static const u32 ar9300_2p2_baseband_cor + + static const u32 ar9300Modes_high_power_tx_gain_table_2p2[][5] = { + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ ++ {0x0000a2dc, 0x0380c7fc, 0x0380c7fc, 0x00637800, 0x00637800}, ++ {0x0000a2e0, 0x0000f800, 0x0000f800, 0x03838000, 0x03838000}, ++ {0x0000a2e4, 0x03ff0000, 0x03ff0000, 0x03fc0000, 0x03fc0000}, ++ {0x0000a2e8, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a410, 0x000050d8, 0x000050d8, 0x000050d9, 0x000050d9}, + {0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000}, + {0x0000a504, 0x04002222, 0x04002222, 0x04000002, 0x04000002}, +@@ -855,7 +859,7 @@ static const u32 ar9300Modes_high_power_ + {0x0000a540, 0x49005e72, 0x49005e72, 0x38001660, 0x38001660}, + {0x0000a544, 0x4e005eb2, 0x4e005eb2, 0x3b001861, 0x3b001861}, + {0x0000a548, 0x53005f12, 0x53005f12, 0x3e001a81, 0x3e001a81}, +- {0x0000a54c, 0x59025eb5, 0x59025eb5, 0x42001a83, 0x42001a83}, ++ {0x0000a54c, 0x59025eb2, 0x59025eb2, 0x42001a83, 0x42001a83}, + {0x0000a550, 0x5e025f12, 0x5e025f12, 0x44001c84, 0x44001c84}, + {0x0000a554, 0x61027f12, 0x61027f12, 0x48001ce3, 0x48001ce3}, + {0x0000a558, 0x6702bf12, 0x6702bf12, 0x4c001ce5, 0x4c001ce5}, +@@ -900,6 +904,30 @@ static const u32 ar9300Modes_high_power_ + {0x0000a5f4, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, + {0x0000a5f8, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, + {0x0000a5fc, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, ++ {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, ++ {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, ++ {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, ++ {0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, ++ {0x0000a610, 0x00804000, 0x00804000, 0x00000000, 0x00000000}, ++ {0x0000a614, 0x00804201, 0x00804201, 0x01404000, 0x01404000}, ++ {0x0000a618, 0x0280c802, 0x0280c802, 0x01404501, 0x01404501}, ++ {0x0000a61c, 0x0280ca03, 0x0280ca03, 0x02008501, 0x02008501}, ++ {0x0000a620, 0x04c15104, 0x04c15104, 0x0280ca03, 0x0280ca03}, ++ {0x0000a624, 0x04c15305, 0x04c15305, 0x03010c04, 0x03010c04}, ++ {0x0000a628, 0x04c15305, 0x04c15305, 0x04014c04, 0x04014c04}, ++ {0x0000a62c, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, ++ {0x0000a630, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, ++ {0x0000a634, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, ++ {0x0000a638, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, ++ {0x0000a63c, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, ++ {0x0000b2dc, 0x0380c7fc, 0x0380c7fc, 0x00637800, 0x00637800}, ++ {0x0000b2e0, 0x0000f800, 0x0000f800, 0x03838000, 0x03838000}, ++ {0x0000b2e4, 0x03ff0000, 0x03ff0000, 0x03fc0000, 0x03fc0000}, ++ {0x0000b2e8, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, ++ {0x0000c2dc, 0x0380c7fc, 0x0380c7fc, 0x00637800, 0x00637800}, ++ {0x0000c2e0, 0x0000f800, 0x0000f800, 0x03838000, 0x03838000}, ++ {0x0000c2e4, 0x03ff0000, 0x03ff0000, 0x03fc0000, 0x03fc0000}, ++ {0x0000c2e8, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x00016044, 0x056db2e6, 0x056db2e6, 0x056db2e6, 0x056db2e6}, + {0x00016048, 0xae480001, 0xae480001, 0xae480001, 0xae480001}, + {0x00016068, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c}, +@@ -913,6 +941,10 @@ static const u32 ar9300Modes_high_power_ + + static const u32 ar9300Modes_high_ob_db_tx_gain_table_2p2[][5] = { + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ ++ {0x0000a2dc, 0x01feee00, 0x01feee00, 0x00637800, 0x00637800}, ++ {0x0000a2e0, 0x0000f000, 0x0000f000, 0x03838000, 0x03838000}, ++ {0x0000a2e4, 0x01ff0000, 0x01ff0000, 0x03fc0000, 0x03fc0000}, ++ {0x0000a2e8, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a410, 0x000050d8, 0x000050d8, 0x000050d9, 0x000050d9}, + {0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000}, + {0x0000a504, 0x04002222, 0x04002222, 0x04000002, 0x04000002}, +@@ -933,7 +965,7 @@ static const u32 ar9300Modes_high_ob_db_ + {0x0000a540, 0x49005e72, 0x49005e72, 0x38001660, 0x38001660}, + {0x0000a544, 0x4e005eb2, 0x4e005eb2, 0x3b001861, 0x3b001861}, + {0x0000a548, 0x53005f12, 0x53005f12, 0x3e001a81, 0x3e001a81}, +- {0x0000a54c, 0x59025eb5, 0x59025eb5, 0x42001a83, 0x42001a83}, ++ {0x0000a54c, 0x59025eb2, 0x59025eb2, 0x42001a83, 0x42001a83}, + {0x0000a550, 0x5e025f12, 0x5e025f12, 0x44001c84, 0x44001c84}, + {0x0000a554, 0x61027f12, 0x61027f12, 0x48001ce3, 0x48001ce3}, + {0x0000a558, 0x6702bf12, 0x6702bf12, 0x4c001ce5, 0x4c001ce5}, +@@ -978,6 +1010,30 @@ static const u32 ar9300Modes_high_ob_db_ + {0x0000a5f4, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, + {0x0000a5f8, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, + {0x0000a5fc, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, ++ {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, ++ {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, ++ {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, ++ {0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, ++ {0x0000a610, 0x00804000, 0x00804000, 0x00000000, 0x00000000}, ++ {0x0000a614, 0x00804201, 0x00804201, 0x01404000, 0x01404000}, ++ {0x0000a618, 0x0280c802, 0x0280c802, 0x01404501, 0x01404501}, ++ {0x0000a61c, 0x0280ca03, 0x0280ca03, 0x02008501, 0x02008501}, ++ {0x0000a620, 0x04c15104, 0x04c15104, 0x0280ca03, 0x0280ca03}, ++ {0x0000a624, 0x04c15305, 0x04c15305, 0x03010c04, 0x03010c04}, ++ {0x0000a628, 0x04c15305, 0x04c15305, 0x04014c04, 0x04014c04}, ++ {0x0000a62c, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, ++ {0x0000a630, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, ++ {0x0000a634, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, ++ {0x0000a638, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, ++ {0x0000a63c, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, ++ {0x0000b2dc, 0x01feee00, 0x01feee00, 0x00637800, 0x00637800}, ++ {0x0000b2e0, 0x0000f000, 0x0000f000, 0x03838000, 0x03838000}, ++ {0x0000b2e4, 0x01ff0000, 0x01ff0000, 0x03fc0000, 0x03fc0000}, ++ {0x0000b2e8, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, ++ {0x0000c2dc, 0x01feee00, 0x01feee00, 0x00637800, 0x00637800}, ++ {0x0000c2e0, 0x0000f000, 0x0000f000, 0x03838000, 0x03838000}, ++ {0x0000c2e4, 0x01ff0000, 0x01ff0000, 0x03fc0000, 0x03fc0000}, ++ {0x0000c2e8, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x00016044, 0x056db2e4, 0x056db2e4, 0x056db2e4, 0x056db2e4}, + {0x00016048, 0x8e480001, 0x8e480001, 0x8e480001, 0x8e480001}, + {0x00016068, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, +@@ -1151,14 +1207,14 @@ static const u32 ar9300Common_rx_gain_ta + {0x0000b074, 0x00000000}, + {0x0000b078, 0x00000000}, + {0x0000b07c, 0x00000000}, +- {0x0000b080, 0x32323232}, +- {0x0000b084, 0x2f2f3232}, +- {0x0000b088, 0x23282a2d}, +- {0x0000b08c, 0x1c1e2123}, +- {0x0000b090, 0x14171919}, +- {0x0000b094, 0x0e0e1214}, +- {0x0000b098, 0x03050707}, +- {0x0000b09c, 0x00030303}, ++ {0x0000b080, 0x2a2d2f32}, ++ {0x0000b084, 0x21232328}, ++ {0x0000b088, 0x19191c1e}, ++ {0x0000b08c, 0x12141417}, ++ {0x0000b090, 0x07070e0e}, ++ {0x0000b094, 0x03030305}, ++ {0x0000b098, 0x00000003}, ++ {0x0000b09c, 0x00000000}, + {0x0000b0a0, 0x00000000}, + {0x0000b0a4, 0x00000000}, + {0x0000b0a8, 0x00000000}, +@@ -1251,6 +1307,10 @@ static const u32 ar9300Common_rx_gain_ta + + static const u32 ar9300Modes_low_ob_db_tx_gain_table_2p2[][5] = { + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ ++ {0x0000a2dc, 0x0380c7fc, 0x0380c7fc, 0x00637800, 0x00637800}, ++ {0x0000a2e0, 0x0000f800, 0x0000f800, 0x03838000, 0x03838000}, ++ {0x0000a2e4, 0x03ff0000, 0x03ff0000, 0x03fc0000, 0x03fc0000}, ++ {0x0000a2e8, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9}, + {0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a504, 0x06000003, 0x06000003, 0x04000002, 0x04000002}, +@@ -1316,6 +1376,30 @@ static const u32 ar9300Modes_low_ob_db_t + {0x0000a5f4, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec}, + {0x0000a5f8, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec}, + {0x0000a5fc, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec}, ++ {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, ++ {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, ++ {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, ++ {0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, ++ {0x0000a610, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, ++ {0x0000a614, 0x01404000, 0x01404000, 0x01404000, 0x01404000}, ++ {0x0000a618, 0x01404501, 0x01404501, 0x01404501, 0x01404501}, ++ {0x0000a61c, 0x02008802, 0x02008802, 0x02008501, 0x02008501}, ++ {0x0000a620, 0x0300cc03, 0x0300cc03, 0x0280ca03, 0x0280ca03}, ++ {0x0000a624, 0x0300cc03, 0x0300cc03, 0x03010c04, 0x03010c04}, ++ {0x0000a628, 0x0300cc03, 0x0300cc03, 0x04014c04, 0x04014c04}, ++ {0x0000a62c, 0x03810c03, 0x03810c03, 0x04015005, 0x04015005}, ++ {0x0000a630, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005}, ++ {0x0000a634, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005}, ++ {0x0000a638, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005}, ++ {0x0000a63c, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005}, ++ {0x0000b2dc, 0x0380c7fc, 0x0380c7fc, 0x00637800, 0x00637800}, ++ {0x0000b2e0, 0x0000f800, 0x0000f800, 0x03838000, 0x03838000}, ++ {0x0000b2e4, 0x03ff0000, 0x03ff0000, 0x03fc0000, 0x03fc0000}, ++ {0x0000b2e8, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, ++ {0x0000c2dc, 0x0380c7fc, 0x0380c7fc, 0x00637800, 0x00637800}, ++ {0x0000c2e0, 0x0000f800, 0x0000f800, 0x03838000, 0x03838000}, ++ {0x0000c2e4, 0x03ff0000, 0x03ff0000, 0x03fc0000, 0x03fc0000}, ++ {0x0000c2e8, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x00016044, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4}, + {0x00016048, 0x66480001, 0x66480001, 0x66480001, 0x66480001}, + {0x00016068, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, +@@ -1414,15 +1498,10 @@ static const u32 ar9300_2p2_mac_core[][2 + {0x00008144, 0xffffffff}, + {0x00008168, 0x00000000}, + {0x0000816c, 0x00000000}, +- {0x00008170, 0x18486200}, +- {0x00008174, 0x33332210}, +- {0x00008178, 0x00000000}, +- {0x0000817c, 0x00020000}, + {0x000081c0, 0x00000000}, + {0x000081c4, 0x33332210}, + {0x000081c8, 0x00000000}, + {0x000081cc, 0x00000000}, +- {0x000081d4, 0x00000000}, + {0x000081ec, 0x00000000}, + {0x000081f0, 0x00000000}, + {0x000081f4, 0x00000000}, diff --git a/queue-2.6.36/ath9k_hw-handle-rx-key-miss.patch b/queue-2.6.36/ath9k_hw-handle-rx-key-miss.patch new file mode 100644 index 00000000000..a9cc62b93fb --- /dev/null +++ b/queue-2.6.36/ath9k_hw-handle-rx-key-miss.patch @@ -0,0 +1,47 @@ +From 3ae74c33c4f799f6bf6d67240a94a0814a8f1944 Mon Sep 17 00:00:00 2001 +From: Felix Fietkau +Date: Tue, 14 Sep 2010 18:38:26 +0200 +Subject: ath9k_hw: handle rx key miss + +From: Felix Fietkau + +commit 3ae74c33c4f799f6bf6d67240a94a0814a8f1944 upstream. + +If AR_KeyMiss is set in the rx descriptor and AR_RxFrameOK is unset, +the hardware could not locate a valid key during a decryption attempt. + +In this case, the frame must not be reported as decrypted, otherwise +mac80211 sees only random garbage. + +Signed-off-by: Felix Fietkau +Signed-off-by: John W. Linville +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/wireless/ath/ath9k/ar9003_mac.c | 3 ++- + drivers/net/wireless/ath/ath9k/mac.c | 2 ++ + 2 files changed, 4 insertions(+), 1 deletion(-) + +--- a/drivers/net/wireless/ath/ath9k/ar9003_mac.c ++++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.c +@@ -616,7 +616,8 @@ int ath9k_hw_process_rxdesc_edma(struct + rxs->rs_status |= ATH9K_RXERR_DECRYPT; + } else if (rxsp->status11 & AR_MichaelErr) { + rxs->rs_status |= ATH9K_RXERR_MIC; +- } ++ } else if (rxsp->status11 & AR_KeyMiss) ++ rxs->rs_status |= ATH9K_RXERR_DECRYPT; + } + + return 0; +--- a/drivers/net/wireless/ath/ath9k/mac.c ++++ b/drivers/net/wireless/ath/ath9k/mac.c +@@ -713,6 +713,8 @@ int ath9k_hw_rxprocdesc(struct ath_hw *a + rs->rs_status |= ATH9K_RXERR_DECRYPT; + else if (ads.ds_rxstatus8 & AR_MichaelErr) + rs->rs_status |= ATH9K_RXERR_MIC; ++ else if (ads.ds_rxstatus8 & AR_KeyMiss) ++ rs->rs_status |= ATH9K_RXERR_DECRYPT; + } + + return 0; diff --git a/queue-2.6.36/ath9k_hw-set-proper-eeprom-offset-for-ar9287-htc-devices.patch b/queue-2.6.36/ath9k_hw-set-proper-eeprom-offset-for-ar9287-htc-devices.patch new file mode 100644 index 00000000000..af6b6922cfb --- /dev/null +++ b/queue-2.6.36/ath9k_hw-set-proper-eeprom-offset-for-ar9287-htc-devices.patch @@ -0,0 +1,45 @@ +From b5261cf4f3860bd772346a3e692683b6144dd44c Mon Sep 17 00:00:00 2001 +From: Rajkumar Manoharan +Date: Wed, 10 Nov 2010 17:51:26 +0530 +Subject: ath9k_hw: Set proper eeprom offset for AR9287 HTC devices + +From: Rajkumar Manoharan + +commit b5261cf4f3860bd772346a3e692683b6144dd44c upstream. + +AR9287 based PCI & USB devices are differed in eeprom start offset. +So set proper the offset for HTC devices to read nvram correctly. + +Signed-off-by: Rajkumar Manoharan +Signed-off-by: John W. Linville +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/wireless/ath/ath9k/eeprom_9287.c | 2 +- + drivers/net/wireless/ath/ath9k/reg.h | 4 ++++ + 2 files changed, 5 insertions(+), 1 deletion(-) + +--- a/drivers/net/wireless/ath/ath9k/eeprom_9287.c ++++ b/drivers/net/wireless/ath/ath9k/eeprom_9287.c +@@ -37,7 +37,7 @@ static bool ath9k_hw_ar9287_fill_eeprom( + int addr, eep_start_loc; + eep_data = (u16 *)eep; + +- if (ah->hw_version.devid == 0x7015) ++ if (AR9287_HTC_DEVID(ah)) + eep_start_loc = AR9287_HTC_EEP_START_LOC; + else + eep_start_loc = AR9287_EEP_START_LOC; +--- a/drivers/net/wireless/ath/ath9k/reg.h ++++ b/drivers/net/wireless/ath/ath9k/reg.h +@@ -903,6 +903,10 @@ + ((_ah)->hw_version.devid == 0x7015) || \ + ((_ah)->hw_version.devid == 0x9018)) + ++#define AR9287_HTC_DEVID(_ah) \ ++ (((_ah)->hw_version.devid == 0x7015) || \ ++ ((_ah)->hw_version.devid == 0x1200)) ++ + #define AR_RADIO_SREV_MAJOR 0xf0 + #define AR_RAD5133_SREV_MAJOR 0xc0 + #define AR_RAD2133_SREV_MAJOR 0xd0 diff --git a/queue-2.6.36/drm-radeon-kms-fix-2d-tile-height-alignment-in-the-r600-cs-checker.patch b/queue-2.6.36/drm-radeon-kms-fix-2d-tile-height-alignment-in-the-r600-cs-checker.patch new file mode 100644 index 00000000000..9f059df3f0f --- /dev/null +++ b/queue-2.6.36/drm-radeon-kms-fix-2d-tile-height-alignment-in-the-r600-cs-checker.patch @@ -0,0 +1,41 @@ +From 354da653233898ed1e51f20cebac9705456bf9b1 Mon Sep 17 00:00:00 2001 +From: Alex Deucher +Date: Mon, 18 Oct 2010 23:45:39 -0400 +Subject: drm/radeon/kms: fix 2D tile height alignment in the r600 CS checker + +From: Alex Deucher + +commit 354da653233898ed1e51f20cebac9705456bf9b1 upstream. + +macro tile heights are aligned to num channels, not num banks. + +Noticed by Dave Airlie. + +Signed-off-by: Alex Deucher +Signed-off-by: Dave Airlie +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/radeon/r600_cs.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/gpu/drm/radeon/r600_cs.c ++++ b/drivers/gpu/drm/radeon/r600_cs.c +@@ -228,7 +228,7 @@ static inline int r600_cs_track_validate + __func__, __LINE__, pitch); + return -EINVAL; + } +- if (!IS_ALIGNED((height / 8), track->nbanks)) { ++ if (!IS_ALIGNED((height / 8), track->npipes)) { + dev_warn(p->dev, "%s:%d cb height (%d) invalid\n", + __func__, __LINE__, height); + return -EINVAL; +@@ -367,7 +367,7 @@ static int r600_cs_track_check(struct ra + __func__, __LINE__, pitch); + return -EINVAL; + } +- if ((height / 8) & (track->nbanks - 1)) { ++ if (!IS_ALIGNED((height / 8), track->npipes)) { + dev_warn(p->dev, "%s:%d db height (%d) invalid\n", + __func__, __LINE__, height); + return -EINVAL; diff --git a/queue-2.6.36/r6040-fix-multicast-filter-some-more.patch b/queue-2.6.36/r6040-fix-multicast-filter-some-more.patch new file mode 100644 index 00000000000..2d8682eedc4 --- /dev/null +++ b/queue-2.6.36/r6040-fix-multicast-filter-some-more.patch @@ -0,0 +1,82 @@ +From e2269308359d5863b6aa1fcb95a425a2ab255f1f Mon Sep 17 00:00:00 2001 +From: Ben Hutchings +Date: Thu, 14 Oct 2010 17:41:53 +0000 +Subject: r6040: Fix multicast filter some more + +From: Ben Hutchings + +commit e2269308359d5863b6aa1fcb95a425a2ab255f1f upstream. + +This code has been broken forever, but in several different and +creative ways. + +So far as I can work out, the R6040 MAC filter has 4 exact-match +entries, the first of which the driver uses for its assigned unicast +address, plus a 64-entry hash-based filter for multicast addresses +(maybe unicast as well?). + +The original version of this code would write the first 4 multicast +addresses as exact-match entries from offset 1 (bug #1: there is no +entry 4 so this could write to some PHY registers). It would fill the +remainder of the exact-match entries with the broadcast address (bug #2: +this would overwrite the last used entry). If more than 4 multicast +addresses were configured, it would set up the hash table, write some +random crap to the MAC control register (bug #3) and finally walk off +the end of the list when filling the exact-match entries (bug #4). + +All of this seems to be pointless, since it sets the promiscuous bit +when the interface is made promiscuous or if >4 multicast addresses +are enabled, and never clears it (bug #5, masking bug #2). + +The recent(ish) changes to the multicast list fixed bug #4, but +completely removed the limit on iteration over the exact-match entries +(bug #6). + +Bug #4 was reported as + and more recently +as . Florian Fainelli attempted to fix +these in commit 3bcf8229a8c49769e48d3e0bd1e20d8e003f8106, but that +actually dealt with bugs #1-3, bug #4 having been fixed in mainline at +that point. + +That commit fixes the most important current bug #6. + +Signed-off-by: Ben Hutchings +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/r6040.c | 22 ++++++++++++---------- + 1 file changed, 12 insertions(+), 10 deletions(-) + +--- a/drivers/net/r6040.c ++++ b/drivers/net/r6040.c +@@ -893,16 +893,18 @@ static void r6040_multicast_list(struct + /* Multicast Address 1~4 case */ + i = 0; + netdev_for_each_mc_addr(ha, dev) { +- if (i < MCAST_MAX) { +- adrp = (u16 *) ha->addr; +- iowrite16(adrp[0], ioaddr + MID_1L + 8 * i); +- iowrite16(adrp[1], ioaddr + MID_1M + 8 * i); +- iowrite16(adrp[2], ioaddr + MID_1H + 8 * i); +- } else { +- iowrite16(0xffff, ioaddr + MID_1L + 8 * i); +- iowrite16(0xffff, ioaddr + MID_1M + 8 * i); +- iowrite16(0xffff, ioaddr + MID_1H + 8 * i); +- } ++ if (i >= MCAST_MAX) ++ break; ++ adrp = (u16 *) ha->addr; ++ iowrite16(adrp[0], ioaddr + MID_1L + 8 * i); ++ iowrite16(adrp[1], ioaddr + MID_1M + 8 * i); ++ iowrite16(adrp[2], ioaddr + MID_1H + 8 * i); ++ i++; ++ } ++ while (i < MCAST_MAX) { ++ iowrite16(0xffff, ioaddr + MID_1L + 8 * i); ++ iowrite16(0xffff, ioaddr + MID_1M + 8 * i); ++ iowrite16(0xffff, ioaddr + MID_1H + 8 * i); + i++; + } + } diff --git a/queue-2.6.36/series b/queue-2.6.36/series index 595a3e3966f..038a6909d25 100644 --- a/queue-2.6.36/series +++ b/queue-2.6.36/series @@ -8,3 +8,35 @@ drm-radeon-kms-don-t-disable-shared-encoders-on-pre-dce3-display-blocks.patch jme-fix-phy-power-off-error.patch irda-fix-parameter-extraction-stack-overflow.patch irda-fix-heap-memory-corruption-in-iriap.c.patch +r6040-fix-multicast-filter-some-more.patch +drm-radeon-kms-fix-2d-tile-height-alignment-in-the-r600-cs-checker.patch +ath9k-built-in-rate-control-a-mpdu-fix.patch +ath9k-fix-channel-flag-regd-issues-with-multiple-cards.patch +ath9k-a-mpdu-rate-control-info-fix.patch +ath9k-fix-tx-struck-state-with-paprd.patch +ath9k-clean-up-fix-aggregation-session-flush.patch +ath9k-fix-power-save-race-conditions.patch +ath9k-fix-an-aggregation-start-related-race-condition.patch +ath9k-fix-regression-which-prevents-chip-sleep-after-cab-data.patch +ath9k_hw-handle-rx-key-miss.patch +ath9k-fix-regression-which-disabled-ps-on-ath9k.patch +ath9k-fix-regression-on-beacon-loss-after-bgscan.patch +ath9k-fix-spurious-mic-failure-reports.patch +ath9k-resume-aggregation-immediately-after-a-hardware-reset.patch +ath9k_hw-fix-divide-by-zero-cases-in-paprd.patch +ath9k_hw-fix-tx-carrier-leakage-for-ieee-compliance-on-ar9003-2.2.patch +ath9k_htc-set-proper-firmware-offset-for-netgear-wnda3200.patch +ath9k-fix-incorrect-access-of-rate-flags-in-rc.patch +ath9k-rename-rxflushlock-to-pcu_lock.patch +ath9k-fix-tx-aggregation-flush-on-ar9003.patch +ath9k-add-locking-for-stopping-rx.patch +ath9k-fix-enabling-ani-tx-monitor-after-bg-scan.patch +ath9k_hw-fix-memory-leak-on-ath9k_hw_rf_alloc_ext_banks-failure.patch +ath9k_hw-fix-ar9280-surprise-removal-during-frequent-idle-on-off.patch +ath9k_htc-avoid-setting-qos-control-for-non-qos-frames.patch +ath9k-add-locking-for-starting-the-pcu-on-rx.patch +ath9k_hw-set-proper-eeprom-offset-for-ar9287-htc-devices.patch +ath9k_htc-add-new-devices-into-ar7010.patch +ath9k_htc-add-support-for-device-id-3346.patch +ath9k_htc-update-usb-device-id-list.patch +ath9k-lock-reset-and-pcu-start-stopping.patch