From: Felix Fietkau Date: Wed, 18 Sep 2013 13:24:55 +0000 (+0000) Subject: ath9k: add missing tx locking X-Git-Url: http://git.lede-project.org./?a=commitdiff_plain;h=50bc1a7593ae9566ad3ad3f208b97a0c393c44a7;p=openwrt%2Fstaging%2Fldir.git ath9k: add missing tx locking Signed-off-by: Felix Fietkau SVN-Revision: 38034 --- diff --git a/package/kernel/mac80211/patches/300-pending_work.patch b/package/kernel/mac80211/patches/300-pending_work.patch index b397b721d6..3312284d11 100644 --- a/package/kernel/mac80211/patches/300-pending_work.patch +++ b/package/kernel/mac80211/patches/300-pending_work.patch @@ -931,7 +931,7 @@ } info.buf_addr[0] = bf->bf_buf_addr; -@@ -1188,53 +1304,86 @@ static void ath_tx_fill_desc(struct ath_ +@@ -1188,64 +1304,101 @@ static void ath_tx_fill_desc(struct ath_ } } @@ -1015,11 +1015,7 @@ + return false; + + INIT_LIST_HEAD(&bf_q); - -- ath_tx_fill_desc(sc, bf, txq, aggr_len); -- ath_tx_txqaddbuf(sc, txq, &bf_q, false); -- } while (txq->axq_ampdu_depth < ATH_AGGR_MIN_QDEPTH && -- status != ATH_AGGR_BAW_CLOSED); ++ + bf = ath_tx_get_tid_subframe(sc, txq, tid, &tid_q); + if (!bf) + return false; @@ -1046,14 +1042,33 @@ + tid->ac->clear_ps_filter = false; + tx_info->flags |= IEEE80211_TX_CTL_CLEAR_PS_FILT; + } -+ + +- ath_tx_fill_desc(sc, bf, txq, aggr_len); +- ath_tx_txqaddbuf(sc, txq, &bf_q, false); +- } while (txq->axq_ampdu_depth < ATH_AGGR_MIN_QDEPTH && +- status != ATH_AGGR_BAW_CLOSED); + ath_tx_fill_desc(sc, bf, txq, aggr_len); + ath_tx_txqaddbuf(sc, txq, &bf_q, false); + return true; } int ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta, -@@ -1258,6 +1407,9 @@ int ath_tx_aggr_start(struct ath_softc * + u16 tid, u16 *ssn) + { + struct ath_atx_tid *txtid; ++ struct ath_txq *txq; + struct ath_node *an; + u8 density; + + an = (struct ath_node *)sta->drv_priv; + txtid = ATH_AN_2_TID(an, tid); ++ txq = txtid->ac->txq; ++ ++ ath_txq_lock(sc, txq); + + /* update ampdu factor/density, they may have changed. This may happen + * in HT IBSS when a beacon with HT-info is received after the station +@@ -1258,6 +1411,9 @@ int ath_tx_aggr_start(struct ath_softc * an->mpdudensity = density; } @@ -1063,7 +1078,16 @@ txtid->active = true; txtid->paused = true; *ssn = txtid->seq_start = txtid->seq_next; -@@ -1277,8 +1429,9 @@ void ath_tx_aggr_stop(struct ath_softc * +@@ -1266,6 +1422,8 @@ int ath_tx_aggr_start(struct ath_softc * + memset(txtid->tx_buf, 0, sizeof(txtid->tx_buf)); + txtid->baw_head = txtid->baw_tail = 0; + ++ ath_txq_unlock_complete(sc, txq); ++ + return 0; + } + +@@ -1277,8 +1435,9 @@ void ath_tx_aggr_stop(struct ath_softc * ath_txq_lock(sc, txq); txtid->active = false; @@ -1074,7 +1098,7 @@ ath_txq_unlock_complete(sc, txq); } -@@ -1302,7 +1455,7 @@ void ath_tx_aggr_sleep(struct ieee80211_ +@@ -1302,7 +1461,7 @@ void ath_tx_aggr_sleep(struct ieee80211_ ath_txq_lock(sc, txq); @@ -1083,7 +1107,7 @@ tid->sched = false; list_del(&tid->list); -@@ -1334,7 +1487,7 @@ void ath_tx_aggr_wakeup(struct ath_softc +@@ -1334,7 +1493,7 @@ void ath_tx_aggr_wakeup(struct ath_softc ath_txq_lock(sc, txq); ac->clear_ps_filter = true; @@ -1092,7 +1116,7 @@ ath_tx_queue_tid(txq, tid); ath_txq_schedule(sc, txq); } -@@ -1359,7 +1512,7 @@ void ath_tx_aggr_resume(struct ath_softc +@@ -1359,7 +1518,7 @@ void ath_tx_aggr_resume(struct ath_softc tid->baw_size = IEEE80211_MIN_AMPDU_BUF << sta->ht_cap.ampdu_factor; tid->paused = false; @@ -1101,7 +1125,7 @@ ath_tx_queue_tid(txq, tid); ath_txq_schedule(sc, txq); } -@@ -1379,6 +1532,7 @@ void ath9k_release_buffered_frames(struc +@@ -1379,6 +1538,7 @@ void ath9k_release_buffered_frames(struc struct ieee80211_tx_info *info; struct list_head bf_q; struct ath_buf *bf_tail = NULL, *bf; @@ -1109,7 +1133,7 @@ int sent = 0; int i; -@@ -1394,16 +1548,18 @@ void ath9k_release_buffered_frames(struc +@@ -1394,16 +1554,18 @@ void ath9k_release_buffered_frames(struc continue; ath_txq_lock(sc, tid->ac->txq); @@ -1133,7 +1157,7 @@ if (bf_tail) bf_tail->bf_next = bf; -@@ -1412,7 +1568,7 @@ void ath9k_release_buffered_frames(struc +@@ -1412,7 +1574,7 @@ void ath9k_release_buffered_frames(struc sent++; TX_STAT_INC(txq->axq_qnum, a_queued_hw); @@ -1142,7 +1166,7 @@ ieee80211_sta_set_buffered(an->sta, i, false); } ath_txq_unlock_complete(sc, tid->ac->txq); -@@ -1571,7 +1727,7 @@ static void ath_drain_txq_list(struct at +@@ -1571,7 +1733,7 @@ static void ath_drain_txq_list(struct at while (!list_empty(list)) { bf = list_first_entry(list, struct ath_buf, list); @@ -1151,7 +1175,7 @@ list_del(&bf->list); ath_tx_return_buffer(sc, bf); -@@ -1665,25 +1821,27 @@ void ath_tx_cleanupq(struct ath_softc *s +@@ -1665,25 +1827,27 @@ void ath_tx_cleanupq(struct ath_softc *s */ void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq) { @@ -1184,7 +1208,7 @@ tid = list_first_entry(&ac->tid_q, struct ath_atx_tid, list); list_del(&tid->list); -@@ -1692,17 +1850,17 @@ void ath_txq_schedule(struct ath_softc * +@@ -1692,17 +1856,17 @@ void ath_txq_schedule(struct ath_softc * if (tid->paused) continue; @@ -1206,7 +1230,7 @@ break; } -@@ -1711,9 +1869,17 @@ void ath_txq_schedule(struct ath_softc * +@@ -1711,9 +1875,17 @@ void ath_txq_schedule(struct ath_softc * list_add_tail(&ac->list, &txq->axq_acq); } @@ -1226,7 +1250,7 @@ } rcu_read_unlock(); -@@ -1787,62 +1953,13 @@ static void ath_tx_txqaddbuf(struct ath_ +@@ -1787,62 +1959,13 @@ static void ath_tx_txqaddbuf(struct ath_ if (bf_is_ampdu_not_probing(bf)) txq->axq_ampdu_depth++; @@ -1292,7 +1316,7 @@ static void ath_tx_send_normal(struct ath_softc *sc, struct ath_txq *txq, struct ath_atx_tid *tid, struct sk_buff *skb) { -@@ -1985,6 +2102,7 @@ static int ath_tx_prepare(struct ieee802 +@@ -1985,6 +2108,7 @@ static int ath_tx_prepare(struct ieee802 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); struct ieee80211_sta *sta = txctl->sta; struct ieee80211_vif *vif = info->control.vif; @@ -1300,7 +1324,7 @@ struct ath_softc *sc = hw->priv; int frmlen = skb->len + FCS_LEN; int padpos, padsize; -@@ -1992,6 +2110,10 @@ static int ath_tx_prepare(struct ieee802 +@@ -1992,6 +2116,10 @@ static int ath_tx_prepare(struct ieee802 /* NOTE: sta can be NULL according to net/mac80211.h */ if (sta) txctl->an = (struct ath_node *)sta->drv_priv; @@ -1311,7 +1335,7 @@ if (info->control.hw_key) frmlen += info->control.hw_key->icv_len; -@@ -2041,7 +2163,6 @@ int ath_tx_start(struct ieee80211_hw *hw +@@ -2041,7 +2169,6 @@ int ath_tx_start(struct ieee80211_hw *hw struct ath_txq *txq = txctl->txq; struct ath_atx_tid *tid = NULL; struct ath_buf *bf; @@ -1319,7 +1343,7 @@ int q; int ret; -@@ -2069,27 +2190,31 @@ int ath_tx_start(struct ieee80211_hw *hw +@@ -2069,27 +2196,31 @@ int ath_tx_start(struct ieee80211_hw *hw ath_txq_unlock(sc, txq); txq = sc->tx.uapsdq; ath_txq_lock(sc, txq); @@ -1362,7 +1386,7 @@ if (txctl->paprd) dev_kfree_skb_any(skb); else -@@ -2142,7 +2267,7 @@ void ath_tx_cabq(struct ieee80211_hw *hw +@@ -2142,7 +2273,7 @@ void ath_tx_cabq(struct ieee80211_hw *hw bf->bf_lastbf = bf; ath_set_rates(vif, NULL, bf); @@ -1371,7 +1395,7 @@ duration += info.rates[0].PktDuration; if (bf_tail) bf_tail->bf_next = bf; -@@ -2189,7 +2314,7 @@ static void ath_tx_complete(struct ath_s +@@ -2189,7 +2320,7 @@ static void ath_tx_complete(struct ath_s struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); struct ath_common *common = ath9k_hw_common(sc->sc_ah); struct ieee80211_hdr * hdr = (struct ieee80211_hdr *)skb->data; @@ -1380,7 +1404,7 @@ unsigned long flags; ath_dbg(common, XMIT, "TX complete: skb: %p\n", skb); -@@ -2225,21 +2350,7 @@ static void ath_tx_complete(struct ath_s +@@ -2225,21 +2356,7 @@ static void ath_tx_complete(struct ath_s spin_unlock_irqrestore(&sc->sc_pm_lock, flags); __skb_queue_tail(&txq->complete_q, skb); @@ -1403,7 +1427,7 @@ } static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf, -@@ -2360,8 +2471,7 @@ static void ath_tx_processq(struct ath_s +@@ -2360,8 +2477,7 @@ static void ath_tx_processq(struct ath_s if (list_empty(&txq->axq_q)) { txq->axq_link = NULL; @@ -1413,7 +1437,7 @@ break; } bf = list_first_entry(&txq->axq_q, struct ath_buf, list); -@@ -2375,7 +2485,7 @@ static void ath_tx_processq(struct ath_s +@@ -2375,7 +2491,7 @@ static void ath_tx_processq(struct ath_s * it with the STALE flag. */ bf_held = NULL; @@ -1422,7 +1446,7 @@ bf_held = bf; if (list_is_last(&bf_held->list, &txq->axq_q)) break; -@@ -2399,7 +2509,7 @@ static void ath_tx_processq(struct ath_s +@@ -2399,7 +2515,7 @@ static void ath_tx_processq(struct ath_s * however leave the last descriptor back as the holding * descriptor for hw. */ @@ -1431,7 +1455,7 @@ INIT_LIST_HEAD(&bf_head); if (!list_is_singular(&lastbf->list)) list_cut_position(&bf_head, -@@ -2470,7 +2580,7 @@ void ath_tx_edma_tasklet(struct ath_soft +@@ -2470,7 +2586,7 @@ void ath_tx_edma_tasklet(struct ath_soft } bf = list_first_entry(fifo_list, struct ath_buf, list); @@ -1440,7 +1464,7 @@ list_del(&bf->list); ath_tx_return_buffer(sc, bf); bf = list_first_entry(fifo_list, struct ath_buf, list); -@@ -2492,7 +2602,7 @@ void ath_tx_edma_tasklet(struct ath_soft +@@ -2492,7 +2608,7 @@ void ath_tx_edma_tasklet(struct ath_soft ath_tx_txqaddbuf(sc, txq, &bf_q, true); } } else { @@ -1449,7 +1473,7 @@ if (bf != lastbf) list_cut_position(&bf_head, fifo_list, lastbf->list.prev); -@@ -2583,6 +2693,7 @@ void ath_tx_node_init(struct ath_softc * +@@ -2583,6 +2699,7 @@ void ath_tx_node_init(struct ath_softc * tid->paused = false; tid->active = false; __skb_queue_head_init(&tid->buf_q); @@ -1457,7 +1481,7 @@ acno = TID_TO_WME_AC(tidno); tid->ac = &an->ac[acno]; } -@@ -2590,6 +2701,7 @@ void ath_tx_node_init(struct ath_softc * +@@ -2590,6 +2707,7 @@ void ath_tx_node_init(struct ath_softc * for (acno = 0, ac = &an->ac[acno]; acno < IEEE80211_NUM_ACS; acno++, ac++) { ac->sched = false;