|
|
@ -436,7 +436,20 @@ |
|
|
|
|
|
|
|
|
|
|
|
if (index >= ((tid->baw_tail - tid->baw_head) &
|
|
|
|
if (index >= ((tid->baw_tail - tid->baw_head) &
|
|
|
|
(ATH_TID_MAX_BUFS - 1))) {
|
|
|
|
(ATH_TID_MAX_BUFS - 1))) {
|
|
|
|
@@ -243,7 +331,7 @@ static void ath_tid_drain(struct ath_sof
|
|
|
|
@@ -224,12 +312,6 @@ static void ath_tx_addto_baw(struct ath_
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
-/*
|
|
|
|
|
|
|
|
- * TODO: For frame(s) that are in the retry state, we will reuse the
|
|
|
|
|
|
|
|
- * sequence number(s) without setting the retry bit. The
|
|
|
|
|
|
|
|
- * alternative is to give up on these and BAR the receiver's window
|
|
|
|
|
|
|
|
- * forward.
|
|
|
|
|
|
|
|
- */
|
|
|
|
|
|
|
|
static void ath_tid_drain(struct ath_softc *sc, struct ath_txq *txq,
|
|
|
|
|
|
|
|
struct ath_atx_tid *tid)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@@ -243,7 +325,7 @@ static void ath_tid_drain(struct ath_sof
|
|
|
|
memset(&ts, 0, sizeof(ts));
|
|
|
|
memset(&ts, 0, sizeof(ts));
|
|
|
|
INIT_LIST_HEAD(&bf_head);
|
|
|
|
INIT_LIST_HEAD(&bf_head);
|
|
|
|
|
|
|
|
|
|
|
@ -445,7 +458,22 @@ |
|
|
|
fi = get_frame_info(skb);
|
|
|
|
fi = get_frame_info(skb);
|
|
|
|
bf = fi->bf;
|
|
|
|
bf = fi->bf;
|
|
|
|
|
|
|
|
|
|
|
|
@@ -380,7 +468,6 @@ static void ath_tx_complete_aggr(struct
|
|
|
|
@@ -253,14 +335,8 @@ static void ath_tid_drain(struct ath_sof
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
list_add_tail(&bf->list, &bf_head);
|
|
|
|
|
|
|
|
-
|
|
|
|
|
|
|
|
- ath_tx_update_baw(sc, tid, bf->bf_state.seqno);
|
|
|
|
|
|
|
|
ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
-
|
|
|
|
|
|
|
|
- tid->seq_next = tid->seq_start;
|
|
|
|
|
|
|
|
- tid->baw_tail = tid->baw_head;
|
|
|
|
|
|
|
|
- tid->bar_index = -1;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void ath_tx_set_retry(struct ath_softc *sc, struct ath_txq *txq,
|
|
|
|
|
|
|
|
@@ -380,7 +456,6 @@ static void ath_tx_complete_aggr(struct
|
|
|
|
struct ieee80211_tx_rate rates[4];
|
|
|
|
struct ieee80211_tx_rate rates[4];
|
|
|
|
struct ath_frame_info *fi;
|
|
|
|
struct ath_frame_info *fi;
|
|
|
|
int nframes;
|
|
|
|
int nframes;
|
|
|
@ -453,7 +481,16 @@ |
|
|
|
bool flush = !!(ts->ts_status & ATH9K_TX_FLUSH);
|
|
|
|
bool flush = !!(ts->ts_status & ATH9K_TX_FLUSH);
|
|
|
|
int i, retries;
|
|
|
|
int i, retries;
|
|
|
|
int bar_index = -1;
|
|
|
|
int bar_index = -1;
|
|
|
|
@@ -417,8 +504,7 @@ static void ath_tx_complete_aggr(struct
|
|
|
|
@@ -406,7 +481,7 @@ static void ath_tx_complete_aggr(struct
|
|
|
|
|
|
|
|
while (bf) {
|
|
|
|
|
|
|
|
bf_next = bf->bf_next;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
- if (!bf->bf_stale || bf_next != NULL)
|
|
|
|
|
|
|
|
+ if (!bf->bf_state.stale || bf_next != NULL)
|
|
|
|
|
|
|
|
list_move_tail(&bf->list, &bf_head);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ath_tx_complete_buf(sc, bf, txq, &bf_head, ts, 0);
|
|
|
|
|
|
|
|
@@ -417,8 +492,7 @@ static void ath_tx_complete_aggr(struct
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
an = (struct ath_node *)sta->drv_priv;
|
|
|
|
an = (struct ath_node *)sta->drv_priv;
|
|
|
@ -463,7 +500,7 @@ |
|
|
|
seq_first = tid->seq_start;
|
|
|
|
seq_first = tid->seq_start;
|
|
|
|
isba = ts->ts_flags & ATH9K_TX_BA;
|
|
|
|
isba = ts->ts_flags & ATH9K_TX_BA;
|
|
|
|
|
|
|
|
|
|
|
|
@@ -430,7 +516,7 @@ static void ath_tx_complete_aggr(struct
|
|
|
|
@@ -430,7 +504,7 @@ static void ath_tx_complete_aggr(struct
|
|
|
|
* Only BlockAcks have a TID and therefore normal Acks cannot be
|
|
|
|
* Only BlockAcks have a TID and therefore normal Acks cannot be
|
|
|
|
* checked
|
|
|
|
* checked
|
|
|
|
*/
|
|
|
|
*/
|
|
|
@ -472,7 +509,7 @@ |
|
|
|
txok = false;
|
|
|
|
txok = false;
|
|
|
|
|
|
|
|
|
|
|
|
isaggr = bf_isaggr(bf);
|
|
|
|
isaggr = bf_isaggr(bf);
|
|
|
|
@@ -466,7 +552,8 @@ static void ath_tx_complete_aggr(struct
|
|
|
|
@@ -466,7 +540,8 @@ static void ath_tx_complete_aggr(struct
|
|
|
|
tx_info = IEEE80211_SKB_CB(skb);
|
|
|
|
tx_info = IEEE80211_SKB_CB(skb);
|
|
|
|
fi = get_frame_info(skb);
|
|
|
|
fi = get_frame_info(skb);
|
|
|
|
|
|
|
|
|
|
|
@ -482,7 +519,25 @@ |
|
|
|
/*
|
|
|
|
/*
|
|
|
|
* Outside of the current BlockAck window,
|
|
|
|
* Outside of the current BlockAck window,
|
|
|
|
* maybe part of a previous session
|
|
|
|
* maybe part of a previous session
|
|
|
|
@@ -560,7 +647,7 @@ static void ath_tx_complete_aggr(struct
|
|
|
|
@@ -499,7 +574,7 @@ static void ath_tx_complete_aggr(struct
|
|
|
|
|
|
|
|
* not a holding desc.
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
INIT_LIST_HEAD(&bf_head);
|
|
|
|
|
|
|
|
- if (bf_next != NULL || !bf_last->bf_stale)
|
|
|
|
|
|
|
|
+ if (bf_next != NULL || !bf_last->bf_state.stale)
|
|
|
|
|
|
|
|
list_move_tail(&bf->list, &bf_head);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!txpending) {
|
|
|
|
|
|
|
|
@@ -523,7 +598,7 @@ static void ath_tx_complete_aggr(struct
|
|
|
|
|
|
|
|
ieee80211_sta_eosp(sta);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
/* retry the un-acked ones */
|
|
|
|
|
|
|
|
- if (bf->bf_next == NULL && bf_last->bf_stale) {
|
|
|
|
|
|
|
|
+ if (bf->bf_next == NULL && bf_last->bf_state.stale) {
|
|
|
|
|
|
|
|
struct ath_buf *tbf;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
tbf = ath_clone_txbuf(sc, bf_last);
|
|
|
|
|
|
|
|
@@ -560,7 +635,7 @@ static void ath_tx_complete_aggr(struct
|
|
|
|
if (an->sleeping)
|
|
|
|
if (an->sleeping)
|
|
|
|
ieee80211_sta_set_buffered(sta, tid->tidno, true);
|
|
|
|
ieee80211_sta_set_buffered(sta, tid->tidno, true);
|
|
|
|
|
|
|
|
|
|
|
@ -491,7 +546,7 @@ |
|
|
|
if (!an->sleeping) {
|
|
|
|
if (!an->sleeping) {
|
|
|
|
ath_tx_queue_tid(txq, tid);
|
|
|
|
ath_tx_queue_tid(txq, tid);
|
|
|
|
|
|
|
|
|
|
|
|
@@ -618,7 +705,7 @@ static void ath_tx_process_buffer(struct
|
|
|
|
@@ -618,7 +693,7 @@ static void ath_tx_process_buffer(struct
|
|
|
|
} else
|
|
|
|
} else
|
|
|
|
ath_tx_complete_aggr(sc, txq, bf, bf_head, ts, txok);
|
|
|
|
ath_tx_complete_aggr(sc, txq, bf, bf_head, ts, txok);
|
|
|
|
|
|
|
|
|
|
|
@ -500,7 +555,7 @@ |
|
|
|
ath_txq_schedule(sc, txq);
|
|
|
|
ath_txq_schedule(sc, txq);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@@ -792,15 +879,20 @@ static int ath_compute_num_delims(struct
|
|
|
|
@@ -792,15 +867,20 @@ static int ath_compute_num_delims(struct
|
|
|
|
|
|
|
|
|
|
|
|
static struct ath_buf *
|
|
|
|
static struct ath_buf *
|
|
|
|
ath_tx_get_tid_subframe(struct ath_softc *sc, struct ath_txq *txq,
|
|
|
|
ath_tx_get_tid_subframe(struct ath_softc *sc, struct ath_txq *txq,
|
|
|
@ -523,8 +578,12 @@ |
|
|
|
if (!skb)
|
|
|
|
if (!skb)
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
@@ -810,11 +902,22 @@ ath_tx_get_tid_subframe(struct ath_softc
|
|
|
|
@@ -808,13 +888,26 @@ ath_tx_get_tid_subframe(struct ath_softc
|
|
|
|
|
|
|
|
bf = fi->bf;
|
|
|
|
|
|
|
|
if (!fi->bf)
|
|
|
|
bf = ath_tx_setup_buffer(sc, txq, tid, skb);
|
|
|
|
bf = ath_tx_setup_buffer(sc, txq, tid, skb);
|
|
|
|
|
|
|
|
+ else
|
|
|
|
|
|
|
|
+ bf->bf_state.stale = false;
|
|
|
|
|
|
|
|
|
|
|
|
if (!bf) {
|
|
|
|
if (!bf) {
|
|
|
|
- __skb_unlink(skb, &tid->buf_q);
|
|
|
|
- __skb_unlink(skb, &tid->buf_q);
|
|
|
@ -547,7 +606,7 @@ |
|
|
|
bf->bf_state.bf_type = BUF_AMPDU | BUF_AGGR;
|
|
|
|
bf->bf_state.bf_type = BUF_AMPDU | BUF_AGGR;
|
|
|
|
seqno = bf->bf_state.seqno;
|
|
|
|
seqno = bf->bf_state.seqno;
|
|
|
|
|
|
|
|
|
|
|
|
@@ -828,73 +931,52 @@ ath_tx_get_tid_subframe(struct ath_softc
|
|
|
|
@@ -828,73 +921,52 @@ ath_tx_get_tid_subframe(struct ath_softc
|
|
|
|
|
|
|
|
|
|
|
|
INIT_LIST_HEAD(&bf_head);
|
|
|
|
INIT_LIST_HEAD(&bf_head);
|
|
|
|
list_add(&bf->list, &bf_head);
|
|
|
|
list_add(&bf->list, &bf_head);
|
|
|
@ -642,7 +701,7 @@ |
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* add padding for previous frame to aggregation length */
|
|
|
|
/* add padding for previous frame to aggregation length */
|
|
|
|
@@ -912,22 +994,37 @@ static enum ATH_AGGR_STATUS ath_tx_form_
|
|
|
|
@@ -912,22 +984,37 @@ static enum ATH_AGGR_STATUS ath_tx_form_
|
|
|
|
bf->bf_next = NULL;
|
|
|
|
bf->bf_next = NULL;
|
|
|
|
|
|
|
|
|
|
|
|
/* link buffers of this frame to the aggregate */
|
|
|
|
/* link buffers of this frame to the aggregate */
|
|
|
@ -685,7 +744,7 @@ |
|
|
|
#undef PADBYTES
|
|
|
|
#undef PADBYTES
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@@ -1188,53 +1285,86 @@ static void ath_tx_fill_desc(struct ath_
|
|
|
|
@@ -1188,53 +1275,86 @@ static void ath_tx_fill_desc(struct ath_
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -788,7 +847,11 @@ |
|
|
|
+ tid_q, &aggr_len);
|
|
|
|
+ tid_q, &aggr_len);
|
|
|
|
+ else
|
|
|
|
+ else
|
|
|
|
+ ath_tx_form_burst(sc, txq, tid, &bf_q, bf, tid_q);
|
|
|
|
+ ath_tx_form_burst(sc, txq, tid, &bf_q, bf, tid_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);
|
|
|
|
+ if (list_empty(&bf_q))
|
|
|
|
+ if (list_empty(&bf_q))
|
|
|
|
+ return false;
|
|
|
|
+ return false;
|
|
|
|
+
|
|
|
|
+
|
|
|
@ -796,18 +859,14 @@ |
|
|
|
+ tid->ac->clear_ps_filter = false;
|
|
|
|
+ tid->ac->clear_ps_filter = false;
|
|
|
|
+ tx_info->flags |= IEEE80211_TX_CTL_CLEAR_PS_FILT;
|
|
|
|
+ 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_fill_desc(sc, bf, txq, aggr_len);
|
|
|
|
+ ath_tx_txqaddbuf(sc, txq, &bf_q, false);
|
|
|
|
+ ath_tx_txqaddbuf(sc, txq, &bf_q, false);
|
|
|
|
+ return true;
|
|
|
|
+ return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta,
|
|
|
|
int ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta,
|
|
|
|
@@ -1258,6 +1388,9 @@ int ath_tx_aggr_start(struct ath_softc *
|
|
|
|
@@ -1258,6 +1378,9 @@ int ath_tx_aggr_start(struct ath_softc *
|
|
|
|
an->mpdudensity = density;
|
|
|
|
an->mpdudensity = density;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -817,7 +876,7 @@ |
|
|
|
txtid->active = true;
|
|
|
|
txtid->active = true;
|
|
|
|
txtid->paused = true;
|
|
|
|
txtid->paused = true;
|
|
|
|
*ssn = txtid->seq_start = txtid->seq_next;
|
|
|
|
*ssn = txtid->seq_start = txtid->seq_next;
|
|
|
|
@@ -1277,8 +1410,9 @@ void ath_tx_aggr_stop(struct ath_softc *
|
|
|
|
@@ -1277,8 +1400,9 @@ void ath_tx_aggr_stop(struct ath_softc *
|
|
|
|
|
|
|
|
|
|
|
|
ath_txq_lock(sc, txq);
|
|
|
|
ath_txq_lock(sc, txq);
|
|
|
|
txtid->active = false;
|
|
|
|
txtid->active = false;
|
|
|
@ -828,7 +887,7 @@ |
|
|
|
ath_txq_unlock_complete(sc, txq);
|
|
|
|
ath_txq_unlock_complete(sc, txq);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@@ -1302,7 +1436,7 @@ void ath_tx_aggr_sleep(struct ieee80211_
|
|
|
|
@@ -1302,7 +1426,7 @@ void ath_tx_aggr_sleep(struct ieee80211_
|
|
|
|
|
|
|
|
|
|
|
|
ath_txq_lock(sc, txq);
|
|
|
|
ath_txq_lock(sc, txq);
|
|
|
|
|
|
|
|
|
|
|
@ -837,7 +896,7 @@ |
|
|
|
|
|
|
|
|
|
|
|
tid->sched = false;
|
|
|
|
tid->sched = false;
|
|
|
|
list_del(&tid->list);
|
|
|
|
list_del(&tid->list);
|
|
|
|
@@ -1334,7 +1468,7 @@ void ath_tx_aggr_wakeup(struct ath_softc
|
|
|
|
@@ -1334,7 +1458,7 @@ void ath_tx_aggr_wakeup(struct ath_softc
|
|
|
|
ath_txq_lock(sc, txq);
|
|
|
|
ath_txq_lock(sc, txq);
|
|
|
|
ac->clear_ps_filter = true;
|
|
|
|
ac->clear_ps_filter = true;
|
|
|
|
|
|
|
|
|
|
|
@ -846,7 +905,7 @@ |
|
|
|
ath_tx_queue_tid(txq, tid);
|
|
|
|
ath_tx_queue_tid(txq, tid);
|
|
|
|
ath_txq_schedule(sc, txq);
|
|
|
|
ath_txq_schedule(sc, txq);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
@@ -1359,7 +1493,7 @@ void ath_tx_aggr_resume(struct ath_softc
|
|
|
|
@@ -1359,7 +1483,7 @@ void ath_tx_aggr_resume(struct ath_softc
|
|
|
|
tid->baw_size = IEEE80211_MIN_AMPDU_BUF << sta->ht_cap.ampdu_factor;
|
|
|
|
tid->baw_size = IEEE80211_MIN_AMPDU_BUF << sta->ht_cap.ampdu_factor;
|
|
|
|
tid->paused = false;
|
|
|
|
tid->paused = false;
|
|
|
|
|
|
|
|
|
|
|
@ -855,7 +914,7 @@ |
|
|
|
ath_tx_queue_tid(txq, tid);
|
|
|
|
ath_tx_queue_tid(txq, tid);
|
|
|
|
ath_txq_schedule(sc, txq);
|
|
|
|
ath_txq_schedule(sc, txq);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
@@ -1379,6 +1513,7 @@ void ath9k_release_buffered_frames(struc
|
|
|
|
@@ -1379,6 +1503,7 @@ void ath9k_release_buffered_frames(struc
|
|
|
|
struct ieee80211_tx_info *info;
|
|
|
|
struct ieee80211_tx_info *info;
|
|
|
|
struct list_head bf_q;
|
|
|
|
struct list_head bf_q;
|
|
|
|
struct ath_buf *bf_tail = NULL, *bf;
|
|
|
|
struct ath_buf *bf_tail = NULL, *bf;
|
|
|
@ -863,7 +922,7 @@ |
|
|
|
int sent = 0;
|
|
|
|
int sent = 0;
|
|
|
|
int i;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
|
|
@@ -1394,15 +1529,15 @@ void ath9k_release_buffered_frames(struc
|
|
|
|
@@ -1394,15 +1519,15 @@ void ath9k_release_buffered_frames(struc
|
|
|
|
continue;
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
|
|
ath_txq_lock(sc, tid->ac->txq);
|
|
|
|
ath_txq_lock(sc, tid->ac->txq);
|
|
|
@ -883,7 +942,7 @@ |
|
|
|
bf->bf_state.bf_type &= ~BUF_AGGR;
|
|
|
|
bf->bf_state.bf_type &= ~BUF_AGGR;
|
|
|
|
if (bf_tail)
|
|
|
|
if (bf_tail)
|
|
|
|
bf_tail->bf_next = bf;
|
|
|
|
bf_tail->bf_next = bf;
|
|
|
|
@@ -1412,7 +1547,7 @@ void ath9k_release_buffered_frames(struc
|
|
|
|
@@ -1412,7 +1537,7 @@ void ath9k_release_buffered_frames(struc
|
|
|
|
sent++;
|
|
|
|
sent++;
|
|
|
|
TX_STAT_INC(txq->axq_qnum, a_queued_hw);
|
|
|
|
TX_STAT_INC(txq->axq_qnum, a_queued_hw);
|
|
|
|
|
|
|
|
|
|
|
@ -892,7 +951,16 @@ |
|
|
|
ieee80211_sta_set_buffered(an->sta, i, false);
|
|
|
|
ieee80211_sta_set_buffered(an->sta, i, false);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
ath_txq_unlock_complete(sc, tid->ac->txq);
|
|
|
|
ath_txq_unlock_complete(sc, tid->ac->txq);
|
|
|
|
@@ -1665,25 +1800,27 @@ void ath_tx_cleanupq(struct ath_softc *s
|
|
|
|
@@ -1571,7 +1696,7 @@ static void ath_drain_txq_list(struct at
|
|
|
|
|
|
|
|
while (!list_empty(list)) {
|
|
|
|
|
|
|
|
bf = list_first_entry(list, struct ath_buf, list);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
- if (bf->bf_stale) {
|
|
|
|
|
|
|
|
+ if (bf->bf_state.stale) {
|
|
|
|
|
|
|
|
list_del(&bf->list);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ath_tx_return_buffer(sc, bf);
|
|
|
|
|
|
|
|
@@ -1665,25 +1790,27 @@ void ath_tx_cleanupq(struct ath_softc *s
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq)
|
|
|
|
void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq)
|
|
|
|
{
|
|
|
|
{
|
|
|
@ -925,7 +993,7 @@ |
|
|
|
tid = list_first_entry(&ac->tid_q, struct ath_atx_tid,
|
|
|
|
tid = list_first_entry(&ac->tid_q, struct ath_atx_tid,
|
|
|
|
list);
|
|
|
|
list);
|
|
|
|
list_del(&tid->list);
|
|
|
|
list_del(&tid->list);
|
|
|
|
@@ -1692,17 +1829,17 @@ void ath_txq_schedule(struct ath_softc *
|
|
|
|
@@ -1692,17 +1819,17 @@ void ath_txq_schedule(struct ath_softc *
|
|
|
|
if (tid->paused)
|
|
|
|
if (tid->paused)
|
|
|
|
continue;
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
|
@ -947,7 +1015,7 @@ |
|
|
|
break;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@@ -1711,9 +1848,17 @@ void ath_txq_schedule(struct ath_softc *
|
|
|
|
@@ -1711,9 +1838,17 @@ void ath_txq_schedule(struct ath_softc *
|
|
|
|
list_add_tail(&ac->list, &txq->axq_acq);
|
|
|
|
list_add_tail(&ac->list, &txq->axq_acq);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -967,7 +1035,7 @@ |
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
rcu_read_unlock();
|
|
|
|
rcu_read_unlock();
|
|
|
|
@@ -1792,57 +1937,6 @@ static void ath_tx_txqaddbuf(struct ath_
|
|
|
|
@@ -1792,57 +1927,6 @@ static void ath_tx_txqaddbuf(struct ath_
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -1025,7 +1093,7 @@ |
|
|
|
static void ath_tx_send_normal(struct ath_softc *sc, struct ath_txq *txq,
|
|
|
|
static void ath_tx_send_normal(struct ath_softc *sc, struct ath_txq *txq,
|
|
|
|
struct ath_atx_tid *tid, struct sk_buff *skb)
|
|
|
|
struct ath_atx_tid *tid, struct sk_buff *skb)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
@@ -1985,6 +2079,7 @@ static int ath_tx_prepare(struct ieee802
|
|
|
|
@@ -1985,6 +2069,7 @@ static int ath_tx_prepare(struct ieee802
|
|
|
|
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
|
|
|
|
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
|
|
|
|
struct ieee80211_sta *sta = txctl->sta;
|
|
|
|
struct ieee80211_sta *sta = txctl->sta;
|
|
|
|
struct ieee80211_vif *vif = info->control.vif;
|
|
|
|
struct ieee80211_vif *vif = info->control.vif;
|
|
|
@ -1033,7 +1101,7 @@ |
|
|
|
struct ath_softc *sc = hw->priv;
|
|
|
|
struct ath_softc *sc = hw->priv;
|
|
|
|
int frmlen = skb->len + FCS_LEN;
|
|
|
|
int frmlen = skb->len + FCS_LEN;
|
|
|
|
int padpos, padsize;
|
|
|
|
int padpos, padsize;
|
|
|
|
@@ -1992,6 +2087,10 @@ static int ath_tx_prepare(struct ieee802
|
|
|
|
@@ -1992,6 +2077,10 @@ static int ath_tx_prepare(struct ieee802
|
|
|
|
/* NOTE: sta can be NULL according to net/mac80211.h */
|
|
|
|
/* NOTE: sta can be NULL according to net/mac80211.h */
|
|
|
|
if (sta)
|
|
|
|
if (sta)
|
|
|
|
txctl->an = (struct ath_node *)sta->drv_priv;
|
|
|
|
txctl->an = (struct ath_node *)sta->drv_priv;
|
|
|
@ -1044,7 +1112,7 @@ |
|
|
|
|
|
|
|
|
|
|
|
if (info->control.hw_key)
|
|
|
|
if (info->control.hw_key)
|
|
|
|
frmlen += info->control.hw_key->icv_len;
|
|
|
|
frmlen += info->control.hw_key->icv_len;
|
|
|
|
@@ -2041,7 +2140,6 @@ int ath_tx_start(struct ieee80211_hw *hw
|
|
|
|
@@ -2041,7 +2130,6 @@ int ath_tx_start(struct ieee80211_hw *hw
|
|
|
|
struct ath_txq *txq = txctl->txq;
|
|
|
|
struct ath_txq *txq = txctl->txq;
|
|
|
|
struct ath_atx_tid *tid = NULL;
|
|
|
|
struct ath_atx_tid *tid = NULL;
|
|
|
|
struct ath_buf *bf;
|
|
|
|
struct ath_buf *bf;
|
|
|
@ -1052,7 +1120,7 @@ |
|
|
|
int q;
|
|
|
|
int q;
|
|
|
|
int ret;
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
|
|
|
|
@@ -2069,27 +2167,31 @@ int ath_tx_start(struct ieee80211_hw *hw
|
|
|
|
@@ -2069,27 +2157,31 @@ int ath_tx_start(struct ieee80211_hw *hw
|
|
|
|
ath_txq_unlock(sc, txq);
|
|
|
|
ath_txq_unlock(sc, txq);
|
|
|
|
txq = sc->tx.uapsdq;
|
|
|
|
txq = sc->tx.uapsdq;
|
|
|
|
ath_txq_lock(sc, txq);
|
|
|
|
ath_txq_lock(sc, txq);
|
|
|
@ -1095,7 +1163,7 @@ |
|
|
|
if (txctl->paprd)
|
|
|
|
if (txctl->paprd)
|
|
|
|
dev_kfree_skb_any(skb);
|
|
|
|
dev_kfree_skb_any(skb);
|
|
|
|
else
|
|
|
|
else
|
|
|
|
@@ -2189,7 +2291,7 @@ static void ath_tx_complete(struct ath_s
|
|
|
|
@@ -2189,7 +2281,7 @@ static void ath_tx_complete(struct ath_s
|
|
|
|
struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
|
|
|
|
struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
|
|
|
|
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
|
|
|
|
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
|
|
|
|
struct ieee80211_hdr * hdr = (struct ieee80211_hdr *)skb->data;
|
|
|
|
struct ieee80211_hdr * hdr = (struct ieee80211_hdr *)skb->data;
|
|
|
@ -1104,7 +1172,7 @@ |
|
|
|
unsigned long flags;
|
|
|
|
unsigned long flags;
|
|
|
|
|
|
|
|
|
|
|
|
ath_dbg(common, XMIT, "TX complete: skb: %p\n", skb);
|
|
|
|
ath_dbg(common, XMIT, "TX complete: skb: %p\n", skb);
|
|
|
|
@@ -2225,21 +2327,7 @@ static void ath_tx_complete(struct ath_s
|
|
|
|
@@ -2225,21 +2317,7 @@ static void ath_tx_complete(struct ath_s
|
|
|
|
spin_unlock_irqrestore(&sc->sc_pm_lock, flags);
|
|
|
|
spin_unlock_irqrestore(&sc->sc_pm_lock, flags);
|
|
|
|
|
|
|
|
|
|
|
|
__skb_queue_tail(&txq->complete_q, skb);
|
|
|
|
__skb_queue_tail(&txq->complete_q, skb);
|
|
|
@ -1127,7 +1195,7 @@ |
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf,
|
|
|
|
static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf,
|
|
|
|
@@ -2360,8 +2448,7 @@ static void ath_tx_processq(struct ath_s
|
|
|
|
@@ -2360,8 +2438,7 @@ static void ath_tx_processq(struct ath_s
|
|
|
|
|
|
|
|
|
|
|
|
if (list_empty(&txq->axq_q)) {
|
|
|
|
if (list_empty(&txq->axq_q)) {
|
|
|
|
txq->axq_link = NULL;
|
|
|
|
txq->axq_link = NULL;
|
|
|
@ -1137,7 +1205,43 @@ |
|
|
|
break;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
bf = list_first_entry(&txq->axq_q, struct ath_buf, list);
|
|
|
|
bf = list_first_entry(&txq->axq_q, struct ath_buf, list);
|
|
|
|
@@ -2583,6 +2670,7 @@ void ath_tx_node_init(struct ath_softc *
|
|
|
|
@@ -2375,7 +2452,7 @@ static void ath_tx_processq(struct ath_s
|
|
|
|
|
|
|
|
* it with the STALE flag.
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
bf_held = NULL;
|
|
|
|
|
|
|
|
- if (bf->bf_stale) {
|
|
|
|
|
|
|
|
+ if (bf->bf_state.stale) {
|
|
|
|
|
|
|
|
bf_held = bf;
|
|
|
|
|
|
|
|
if (list_is_last(&bf_held->list, &txq->axq_q))
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
@@ -2399,7 +2476,7 @@ static void ath_tx_processq(struct ath_s
|
|
|
|
|
|
|
|
* however leave the last descriptor back as the holding
|
|
|
|
|
|
|
|
* descriptor for hw.
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
- lastbf->bf_stale = true;
|
|
|
|
|
|
|
|
+ lastbf->bf_state.stale = true;
|
|
|
|
|
|
|
|
INIT_LIST_HEAD(&bf_head);
|
|
|
|
|
|
|
|
if (!list_is_singular(&lastbf->list))
|
|
|
|
|
|
|
|
list_cut_position(&bf_head,
|
|
|
|
|
|
|
|
@@ -2470,7 +2547,7 @@ void ath_tx_edma_tasklet(struct ath_soft
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bf = list_first_entry(fifo_list, struct ath_buf, list);
|
|
|
|
|
|
|
|
- if (bf->bf_stale) {
|
|
|
|
|
|
|
|
+ if (bf->bf_state.stale) {
|
|
|
|
|
|
|
|
list_del(&bf->list);
|
|
|
|
|
|
|
|
ath_tx_return_buffer(sc, bf);
|
|
|
|
|
|
|
|
bf = list_first_entry(fifo_list, struct ath_buf, list);
|
|
|
|
|
|
|
|
@@ -2492,7 +2569,7 @@ void ath_tx_edma_tasklet(struct ath_soft
|
|
|
|
|
|
|
|
ath_tx_txqaddbuf(sc, txq, &bf_q, true);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
- lastbf->bf_stale = true;
|
|
|
|
|
|
|
|
+ lastbf->bf_state.stale = true;
|
|
|
|
|
|
|
|
if (bf != lastbf)
|
|
|
|
|
|
|
|
list_cut_position(&bf_head, fifo_list,
|
|
|
|
|
|
|
|
lastbf->list.prev);
|
|
|
|
|
|
|
|
@@ -2583,6 +2660,7 @@ void ath_tx_node_init(struct ath_softc *
|
|
|
|
tid->paused = false;
|
|
|
|
tid->paused = false;
|
|
|
|
tid->active = false;
|
|
|
|
tid->active = false;
|
|
|
|
__skb_queue_head_init(&tid->buf_q);
|
|
|
|
__skb_queue_head_init(&tid->buf_q);
|
|
|
@ -1145,7 +1249,7 @@ |
|
|
|
acno = TID_TO_WME_AC(tidno);
|
|
|
|
acno = TID_TO_WME_AC(tidno);
|
|
|
|
tid->ac = &an->ac[acno];
|
|
|
|
tid->ac = &an->ac[acno];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
@@ -2590,6 +2678,7 @@ void ath_tx_node_init(struct ath_softc *
|
|
|
|
@@ -2590,6 +2668,7 @@ void ath_tx_node_init(struct ath_softc *
|
|
|
|
for (acno = 0, ac = &an->ac[acno];
|
|
|
|
for (acno = 0, ac = &an->ac[acno];
|
|
|
|
acno < IEEE80211_NUM_ACS; acno++, ac++) {
|
|
|
|
acno < IEEE80211_NUM_ACS; acno++, ac++) {
|
|
|
|
ac->sched = false;
|
|
|
|
ac->sched = false;
|
|
|
@ -2235,7 +2339,14 @@ |
|
|
|
#define REALTEK_USB_VENQT_WRITE 0x40
|
|
|
|
#define REALTEK_USB_VENQT_WRITE 0x40
|
|
|
|
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
|
|
|
|
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
|
|
|
|
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
|
|
|
|
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
|
|
|
|
@@ -79,10 +79,6 @@ struct ath_config {
|
|
|
|
@@ -72,17 +72,12 @@ struct ath_config {
|
|
|
|
|
|
|
|
/*************************/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#define ATH_TXBUF_RESET(_bf) do { \
|
|
|
|
|
|
|
|
- (_bf)->bf_stale = false; \
|
|
|
|
|
|
|
|
(_bf)->bf_lastbf = NULL; \
|
|
|
|
|
|
|
|
(_bf)->bf_next = NULL; \
|
|
|
|
|
|
|
|
memset(&((_bf)->bf_state), 0, \
|
|
|
|
sizeof(struct ath_buf_state)); \
|
|
|
|
sizeof(struct ath_buf_state)); \
|
|
|
|
} while (0)
|
|
|
|
} while (0)
|
|
|
|
|
|
|
|
|
|
|
@ -2246,7 +2357,7 @@ |
|
|
|
/**
|
|
|
|
/**
|
|
|
|
* enum buffer_type - Buffer type flags
|
|
|
|
* enum buffer_type - Buffer type flags
|
|
|
|
*
|
|
|
|
*
|
|
|
|
@@ -137,7 +133,8 @@ int ath_descdma_setup(struct ath_softc *
|
|
|
|
@@ -137,7 +132,8 @@ int ath_descdma_setup(struct ath_softc *
|
|
|
|
#define ATH_AGGR_ENCRYPTDELIM 10
|
|
|
|
#define ATH_AGGR_ENCRYPTDELIM 10
|
|
|
|
/* minimum h/w qdepth to be sustained to maximize aggregation */
|
|
|
|
/* minimum h/w qdepth to be sustained to maximize aggregation */
|
|
|
|
#define ATH_AGGR_MIN_QDEPTH 2
|
|
|
|
#define ATH_AGGR_MIN_QDEPTH 2
|
|
|
@ -2256,7 +2367,7 @@ |
|
|
|
|
|
|
|
|
|
|
|
#define IEEE80211_SEQ_SEQ_SHIFT 4
|
|
|
|
#define IEEE80211_SEQ_SEQ_SHIFT 4
|
|
|
|
#define IEEE80211_SEQ_MAX 4096
|
|
|
|
#define IEEE80211_SEQ_MAX 4096
|
|
|
|
@@ -174,12 +171,6 @@ int ath_descdma_setup(struct ath_softc *
|
|
|
|
@@ -174,12 +170,6 @@ int ath_descdma_setup(struct ath_softc *
|
|
|
|
|
|
|
|
|
|
|
|
#define ATH_TX_COMPLETE_POLL_INT 1000
|
|
|
|
#define ATH_TX_COMPLETE_POLL_INT 1000
|
|
|
|
|
|
|
|
|
|
|
@ -2269,7 +2380,19 @@ |
|
|
|
#define ATH_TXFIFO_DEPTH 8
|
|
|
|
#define ATH_TXFIFO_DEPTH 8
|
|
|
|
struct ath_txq {
|
|
|
|
struct ath_txq {
|
|
|
|
int mac80211_qnum; /* mac80211 queue number, -1 means not mac80211 Q */
|
|
|
|
int mac80211_qnum; /* mac80211 queue number, -1 means not mac80211 Q */
|
|
|
|
@@ -212,8 +203,9 @@ struct ath_frame_info {
|
|
|
|
@@ -201,10 +191,10 @@ struct ath_txq {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
struct ath_atx_ac {
|
|
|
|
|
|
|
|
struct ath_txq *txq;
|
|
|
|
|
|
|
|
- int sched;
|
|
|
|
|
|
|
|
struct list_head list;
|
|
|
|
|
|
|
|
struct list_head tid_q;
|
|
|
|
|
|
|
|
bool clear_ps_filter;
|
|
|
|
|
|
|
|
+ bool sched;
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
struct ath_frame_info {
|
|
|
|
|
|
|
|
@@ -212,14 +202,16 @@ struct ath_frame_info {
|
|
|
|
int framelen;
|
|
|
|
int framelen;
|
|
|
|
enum ath9k_key_type keytype;
|
|
|
|
enum ath9k_key_type keytype;
|
|
|
|
u8 keyix;
|
|
|
|
u8 keyix;
|
|
|
@ -2280,7 +2403,22 @@ |
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
struct ath_buf_state {
|
|
|
|
struct ath_buf_state {
|
|
|
|
@@ -241,6 +233,7 @@ struct ath_buf {
|
|
|
|
u8 bf_type;
|
|
|
|
|
|
|
|
u8 bfs_paprd;
|
|
|
|
|
|
|
|
u8 ndelim;
|
|
|
|
|
|
|
|
+ bool stale;
|
|
|
|
|
|
|
|
u16 seqno;
|
|
|
|
|
|
|
|
unsigned long bfs_paprd_timestamp;
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
@@ -233,7 +225,6 @@ struct ath_buf {
|
|
|
|
|
|
|
|
void *bf_desc; /* virtual addr of desc */
|
|
|
|
|
|
|
|
dma_addr_t bf_daddr; /* physical addr of desc */
|
|
|
|
|
|
|
|
dma_addr_t bf_buf_addr; /* physical addr of data buffer, for DMA */
|
|
|
|
|
|
|
|
- bool bf_stale;
|
|
|
|
|
|
|
|
struct ieee80211_tx_rate rates[4];
|
|
|
|
|
|
|
|
struct ath_buf_state bf_state;
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
@@ -241,16 +232,18 @@ struct ath_buf {
|
|
|
|
struct ath_atx_tid {
|
|
|
|
struct ath_atx_tid {
|
|
|
|
struct list_head list;
|
|
|
|
struct list_head list;
|
|
|
|
struct sk_buff_head buf_q;
|
|
|
|
struct sk_buff_head buf_q;
|
|
|
@ -2288,8 +2426,28 @@ |
|
|
|
struct ath_node *an;
|
|
|
|
struct ath_node *an;
|
|
|
|
struct ath_atx_ac *ac;
|
|
|
|
struct ath_atx_ac *ac;
|
|
|
|
unsigned long tx_buf[BITS_TO_LONGS(ATH_TID_MAX_BUFS)];
|
|
|
|
unsigned long tx_buf[BITS_TO_LONGS(ATH_TID_MAX_BUFS)];
|
|
|
|
@@ -268,6 +261,7 @@ struct ath_node {
|
|
|
|
- int bar_index;
|
|
|
|
|
|
|
|
u16 seq_start;
|
|
|
|
|
|
|
|
u16 seq_next;
|
|
|
|
|
|
|
|
u16 baw_size;
|
|
|
|
|
|
|
|
- int tidno;
|
|
|
|
|
|
|
|
+ u8 tidno;
|
|
|
|
|
|
|
|
int baw_head; /* first un-acked tx buffer */
|
|
|
|
|
|
|
|
int baw_tail; /* next unused tx buffer slot */
|
|
|
|
|
|
|
|
+
|
|
|
|
|
|
|
|
+ s8 bar_index;
|
|
|
|
|
|
|
|
bool sched;
|
|
|
|
|
|
|
|
bool paused;
|
|
|
|
|
|
|
|
bool active;
|
|
|
|
|
|
|
|
@@ -262,12 +255,13 @@ struct ath_node {
|
|
|
|
|
|
|
|
struct ieee80211_vif *vif; /* interface with which we're associated */
|
|
|
|
|
|
|
|
struct ath_atx_tid tid[IEEE80211_NUM_TIDS];
|
|
|
|
|
|
|
|
struct ath_atx_ac ac[IEEE80211_NUM_ACS];
|
|
|
|
|
|
|
|
- int ps_key;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
u16 maxampdu;
|
|
|
|
u8 mpdudensity;
|
|
|
|
u8 mpdudensity;
|
|
|
|
|
|
|
|
+ s8 ps_key;
|
|
|
|
|
|
|
|
|
|
|
|
bool sleeping;
|
|
|
|
bool sleeping;
|
|
|
|
+ bool no_ps_filter;
|
|
|
|
+ bool no_ps_filter;
|
|
|
|