| .. | .. |
|---|
| 113 | 113 | ath_tx_status(hw, skb); |
|---|
| 114 | 114 | } |
|---|
| 115 | 115 | |
|---|
| 116 | | -void __ath_tx_queue_tid(struct ath_softc *sc, struct ath_atx_tid *tid) |
|---|
| 117 | | -{ |
|---|
| 118 | | - struct ath_vif *avp = (struct ath_vif *) tid->an->vif->drv_priv; |
|---|
| 119 | | - struct ath_chanctx *ctx = avp->chanctx; |
|---|
| 120 | | - struct ath_acq *acq; |
|---|
| 121 | | - struct list_head *tid_list; |
|---|
| 122 | | - u8 acno = TID_TO_WME_AC(tid->tidno); |
|---|
| 123 | | - |
|---|
| 124 | | - if (!ctx || !list_empty(&tid->list)) |
|---|
| 125 | | - return; |
|---|
| 126 | | - |
|---|
| 127 | | - |
|---|
| 128 | | - acq = &ctx->acq[acno]; |
|---|
| 129 | | - if ((sc->airtime_flags & AIRTIME_USE_NEW_QUEUES) && |
|---|
| 130 | | - tid->an->airtime_deficit[acno] > 0) |
|---|
| 131 | | - tid_list = &acq->acq_new; |
|---|
| 132 | | - else |
|---|
| 133 | | - tid_list = &acq->acq_old; |
|---|
| 134 | | - |
|---|
| 135 | | - list_add_tail(&tid->list, tid_list); |
|---|
| 136 | | -} |
|---|
| 137 | | - |
|---|
| 138 | 116 | void ath_tx_queue_tid(struct ath_softc *sc, struct ath_atx_tid *tid) |
|---|
| 139 | 117 | { |
|---|
| 140 | | - struct ath_vif *avp = (struct ath_vif *) tid->an->vif->drv_priv; |
|---|
| 141 | | - struct ath_chanctx *ctx = avp->chanctx; |
|---|
| 142 | | - struct ath_acq *acq; |
|---|
| 118 | + struct ieee80211_txq *queue = |
|---|
| 119 | + container_of((void *)tid, struct ieee80211_txq, drv_priv); |
|---|
| 143 | 120 | |
|---|
| 144 | | - if (!ctx || !list_empty(&tid->list)) |
|---|
| 145 | | - return; |
|---|
| 146 | | - |
|---|
| 147 | | - acq = &ctx->acq[TID_TO_WME_AC(tid->tidno)]; |
|---|
| 148 | | - spin_lock_bh(&acq->lock); |
|---|
| 149 | | - __ath_tx_queue_tid(sc, tid); |
|---|
| 150 | | - spin_unlock_bh(&acq->lock); |
|---|
| 121 | + ieee80211_schedule_txq(sc->hw, queue); |
|---|
| 151 | 122 | } |
|---|
| 152 | | - |
|---|
| 153 | 123 | |
|---|
| 154 | 124 | void ath9k_wake_tx_queue(struct ieee80211_hw *hw, struct ieee80211_txq *queue) |
|---|
| 155 | 125 | { |
|---|
| .. | .. |
|---|
| 163 | 133 | tid->tidno); |
|---|
| 164 | 134 | |
|---|
| 165 | 135 | ath_txq_lock(sc, txq); |
|---|
| 166 | | - |
|---|
| 167 | | - tid->has_queued = true; |
|---|
| 168 | | - ath_tx_queue_tid(sc, tid); |
|---|
| 169 | 136 | ath_txq_schedule(sc, txq); |
|---|
| 170 | | - |
|---|
| 171 | 137 | ath_txq_unlock(sc, txq); |
|---|
| 172 | 138 | } |
|---|
| 173 | 139 | |
|---|
| .. | .. |
|---|
| 175 | 141 | { |
|---|
| 176 | 142 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); |
|---|
| 177 | 143 | BUILD_BUG_ON(sizeof(struct ath_frame_info) > |
|---|
| 178 | | - sizeof(tx_info->rate_driver_data)); |
|---|
| 179 | | - return (struct ath_frame_info *) &tx_info->rate_driver_data[0]; |
|---|
| 144 | + sizeof(tx_info->status.status_driver_data)); |
|---|
| 145 | + return (struct ath_frame_info *) &tx_info->status.status_driver_data[0]; |
|---|
| 180 | 146 | } |
|---|
| 181 | 147 | |
|---|
| 182 | 148 | static void ath_send_bar(struct ath_atx_tid *tid, u16 seqno) |
|---|
| .. | .. |
|---|
| 217 | 183 | return ATH_AN_2_TID(an, tidno); |
|---|
| 218 | 184 | } |
|---|
| 219 | 185 | |
|---|
| 220 | | -static struct sk_buff * |
|---|
| 221 | | -ath_tid_pull(struct ath_atx_tid *tid) |
|---|
| 186 | +static int |
|---|
| 187 | +ath_tid_pull(struct ath_atx_tid *tid, struct sk_buff **skbuf) |
|---|
| 222 | 188 | { |
|---|
| 223 | 189 | struct ieee80211_txq *txq = container_of((void*)tid, struct ieee80211_txq, drv_priv); |
|---|
| 224 | 190 | struct ath_softc *sc = tid->an->sc; |
|---|
| .. | .. |
|---|
| 229 | 195 | }; |
|---|
| 230 | 196 | struct sk_buff *skb; |
|---|
| 231 | 197 | struct ath_frame_info *fi; |
|---|
| 232 | | - int q; |
|---|
| 233 | | - |
|---|
| 234 | | - if (!tid->has_queued) |
|---|
| 235 | | - return NULL; |
|---|
| 198 | + int q, ret; |
|---|
| 236 | 199 | |
|---|
| 237 | 200 | skb = ieee80211_tx_dequeue(hw, txq); |
|---|
| 238 | | - if (!skb) { |
|---|
| 239 | | - tid->has_queued = false; |
|---|
| 240 | | - return NULL; |
|---|
| 241 | | - } |
|---|
| 201 | + if (!skb) |
|---|
| 202 | + return -ENOENT; |
|---|
| 242 | 203 | |
|---|
| 243 | | - if (ath_tx_prepare(hw, skb, &txctl)) { |
|---|
| 204 | + ret = ath_tx_prepare(hw, skb, &txctl); |
|---|
| 205 | + if (ret) { |
|---|
| 244 | 206 | ieee80211_free_txskb(hw, skb); |
|---|
| 245 | | - return NULL; |
|---|
| 207 | + return ret; |
|---|
| 246 | 208 | } |
|---|
| 247 | 209 | |
|---|
| 248 | 210 | q = skb_get_queue_mapping(skb); |
|---|
| .. | .. |
|---|
| 252 | 214 | ++tid->txq->pending_frames; |
|---|
| 253 | 215 | } |
|---|
| 254 | 216 | |
|---|
| 255 | | - return skb; |
|---|
| 217 | + *skbuf = skb; |
|---|
| 218 | + return 0; |
|---|
| 256 | 219 | } |
|---|
| 257 | 220 | |
|---|
| 258 | | - |
|---|
| 259 | | -static bool ath_tid_has_buffered(struct ath_atx_tid *tid) |
|---|
| 221 | +static int ath_tid_dequeue(struct ath_atx_tid *tid, |
|---|
| 222 | + struct sk_buff **skb) |
|---|
| 260 | 223 | { |
|---|
| 261 | | - return !skb_queue_empty(&tid->retry_q) || tid->has_queued; |
|---|
| 262 | | -} |
|---|
| 224 | + int ret = 0; |
|---|
| 225 | + *skb = __skb_dequeue(&tid->retry_q); |
|---|
| 226 | + if (!*skb) |
|---|
| 227 | + ret = ath_tid_pull(tid, skb); |
|---|
| 263 | 228 | |
|---|
| 264 | | -static struct sk_buff *ath_tid_dequeue(struct ath_atx_tid *tid) |
|---|
| 265 | | -{ |
|---|
| 266 | | - struct sk_buff *skb; |
|---|
| 267 | | - |
|---|
| 268 | | - skb = __skb_dequeue(&tid->retry_q); |
|---|
| 269 | | - if (!skb) |
|---|
| 270 | | - skb = ath_tid_pull(tid); |
|---|
| 271 | | - |
|---|
| 272 | | - return skb; |
|---|
| 229 | + return ret; |
|---|
| 273 | 230 | } |
|---|
| 274 | 231 | |
|---|
| 275 | 232 | static void ath_tx_flush_tid(struct ath_softc *sc, struct ath_atx_tid *tid) |
|---|
| .. | .. |
|---|
| 365 | 322 | struct list_head bf_head; |
|---|
| 366 | 323 | struct ath_tx_status ts; |
|---|
| 367 | 324 | struct ath_frame_info *fi; |
|---|
| 325 | + int ret; |
|---|
| 368 | 326 | |
|---|
| 369 | 327 | memset(&ts, 0, sizeof(ts)); |
|---|
| 370 | 328 | INIT_LIST_HEAD(&bf_head); |
|---|
| 371 | 329 | |
|---|
| 372 | | - while ((skb = ath_tid_dequeue(tid))) { |
|---|
| 330 | + while ((ret = ath_tid_dequeue(tid, &skb)) == 0) { |
|---|
| 373 | 331 | fi = get_frame_info(skb); |
|---|
| 374 | 332 | bf = fi->bf; |
|---|
| 375 | 333 | |
|---|
| .. | .. |
|---|
| 391 | 349 | struct ieee80211_hdr *hdr; |
|---|
| 392 | 350 | int prev = fi->retries; |
|---|
| 393 | 351 | |
|---|
| 394 | | - TX_STAT_INC(txq->axq_qnum, a_retries); |
|---|
| 352 | + TX_STAT_INC(sc, txq->axq_qnum, a_retries); |
|---|
| 395 | 353 | fi->retries += count; |
|---|
| 396 | 354 | |
|---|
| 397 | 355 | if (prev > 0) |
|---|
| .. | .. |
|---|
| 452 | 410 | struct ath_tx_status *ts, int txok, |
|---|
| 453 | 411 | int *nframes, int *nbad) |
|---|
| 454 | 412 | { |
|---|
| 455 | | - struct ath_frame_info *fi; |
|---|
| 456 | 413 | u16 seq_st = 0; |
|---|
| 457 | 414 | u32 ba[WME_BA_BMP_SIZE >> 5]; |
|---|
| 458 | 415 | int ba_index; |
|---|
| .. | .. |
|---|
| 464 | 421 | isaggr = bf_isaggr(bf); |
|---|
| 465 | 422 | if (isaggr) { |
|---|
| 466 | 423 | seq_st = ts->ts_seqnum; |
|---|
| 467 | | - memcpy(ba, &ts->ba_low, WME_BA_BMP_SIZE >> 3); |
|---|
| 424 | + memcpy(ba, &ts->ba, WME_BA_BMP_SIZE >> 3); |
|---|
| 468 | 425 | } |
|---|
| 469 | 426 | |
|---|
| 470 | 427 | while (bf) { |
|---|
| 471 | | - fi = get_frame_info(bf->bf_mpdu); |
|---|
| 472 | 428 | ba_index = ATH_BA_INDEX(seq_st, bf->bf_state.seqno); |
|---|
| 473 | 429 | |
|---|
| 474 | 430 | (*nframes)++; |
|---|
| .. | .. |
|---|
| 488 | 444 | { |
|---|
| 489 | 445 | struct ath_node *an = NULL; |
|---|
| 490 | 446 | struct sk_buff *skb; |
|---|
| 491 | | - struct ieee80211_hdr *hdr; |
|---|
| 492 | 447 | struct ieee80211_tx_info *tx_info; |
|---|
| 493 | 448 | struct ath_buf *bf_next, *bf_last = bf->bf_lastbf; |
|---|
| 494 | 449 | struct list_head bf_head; |
|---|
| .. | .. |
|---|
| 505 | 460 | int bar_index = -1; |
|---|
| 506 | 461 | |
|---|
| 507 | 462 | skb = bf->bf_mpdu; |
|---|
| 508 | | - hdr = (struct ieee80211_hdr *)skb->data; |
|---|
| 509 | | - |
|---|
| 510 | 463 | tx_info = IEEE80211_SKB_CB(skb); |
|---|
| 511 | 464 | |
|---|
| 512 | 465 | memcpy(rates, bf->rates, sizeof(rates)); |
|---|
| .. | .. |
|---|
| 551 | 504 | if (isaggr && txok) { |
|---|
| 552 | 505 | if (ts->ts_flags & ATH9K_TX_BA) { |
|---|
| 553 | 506 | seq_st = ts->ts_seqnum; |
|---|
| 554 | | - memcpy(ba, &ts->ba_low, WME_BA_BMP_SIZE >> 3); |
|---|
| 507 | + memcpy(ba, &ts->ba, WME_BA_BMP_SIZE >> 3); |
|---|
| 555 | 508 | } else { |
|---|
| 556 | 509 | /* |
|---|
| 557 | 510 | * AR5416 can become deaf/mute when BA |
|---|
| .. | .. |
|---|
| 681 | 634 | skb_queue_splice_tail(&bf_pending, &tid->retry_q); |
|---|
| 682 | 635 | if (!an->sleeping) { |
|---|
| 683 | 636 | ath_tx_queue_tid(sc, tid); |
|---|
| 684 | | - |
|---|
| 685 | 637 | if (ts->ts_status & (ATH9K_TXERR_FILT | ATH9K_TXERR_XRETRY)) |
|---|
| 686 | 638 | tid->clear_ps_filter = true; |
|---|
| 687 | 639 | } |
|---|
| .. | .. |
|---|
| 708 | 660 | return bf_isampdu(bf) && !(info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE); |
|---|
| 709 | 661 | } |
|---|
| 710 | 662 | |
|---|
| 711 | | -static void ath_tx_count_airtime(struct ath_softc *sc, struct ath_node *an, |
|---|
| 712 | | - struct ath_atx_tid *tid, struct ath_buf *bf, |
|---|
| 713 | | - struct ath_tx_status *ts) |
|---|
| 663 | +static void ath_tx_count_airtime(struct ath_softc *sc, |
|---|
| 664 | + struct ieee80211_sta *sta, |
|---|
| 665 | + struct ath_buf *bf, |
|---|
| 666 | + struct ath_tx_status *ts, |
|---|
| 667 | + u8 tid) |
|---|
| 714 | 668 | { |
|---|
| 715 | | - struct ath_txq *txq = tid->txq; |
|---|
| 716 | 669 | u32 airtime = 0; |
|---|
| 717 | 670 | int i; |
|---|
| 718 | 671 | |
|---|
| .. | .. |
|---|
| 722 | 675 | airtime += rate_dur * bf->rates[i].count; |
|---|
| 723 | 676 | } |
|---|
| 724 | 677 | |
|---|
| 725 | | - if (sc->airtime_flags & AIRTIME_USE_TX) { |
|---|
| 726 | | - int q = txq->mac80211_qnum; |
|---|
| 727 | | - struct ath_acq *acq = &sc->cur_chan->acq[q]; |
|---|
| 728 | | - |
|---|
| 729 | | - spin_lock_bh(&acq->lock); |
|---|
| 730 | | - an->airtime_deficit[q] -= airtime; |
|---|
| 731 | | - if (an->airtime_deficit[q] <= 0) |
|---|
| 732 | | - __ath_tx_queue_tid(sc, tid); |
|---|
| 733 | | - spin_unlock_bh(&acq->lock); |
|---|
| 734 | | - } |
|---|
| 735 | | - ath_debug_airtime(sc, an, 0, airtime); |
|---|
| 678 | + ieee80211_sta_register_airtime(sta, tid, airtime, 0); |
|---|
| 736 | 679 | } |
|---|
| 737 | 680 | |
|---|
| 738 | 681 | static void ath_tx_process_buffer(struct ath_softc *sc, struct ath_txq *txq, |
|---|
| .. | .. |
|---|
| 762 | 705 | if (sta) { |
|---|
| 763 | 706 | struct ath_node *an = (struct ath_node *)sta->drv_priv; |
|---|
| 764 | 707 | tid = ath_get_skb_tid(sc, an, bf->bf_mpdu); |
|---|
| 765 | | - ath_tx_count_airtime(sc, an, tid, bf, ts); |
|---|
| 708 | + ath_tx_count_airtime(sc, sta, bf, ts, tid->tidno); |
|---|
| 766 | 709 | if (ts->ts_status & (ATH9K_TXERR_FILT | ATH9K_TXERR_XRETRY)) |
|---|
| 767 | 710 | tid->clear_ps_filter = true; |
|---|
| 768 | 711 | } |
|---|
| .. | .. |
|---|
| 947 | 890 | return ndelim; |
|---|
| 948 | 891 | } |
|---|
| 949 | 892 | |
|---|
| 950 | | -static struct ath_buf * |
|---|
| 893 | +static int |
|---|
| 951 | 894 | ath_tx_get_tid_subframe(struct ath_softc *sc, struct ath_txq *txq, |
|---|
| 952 | | - struct ath_atx_tid *tid) |
|---|
| 895 | + struct ath_atx_tid *tid, struct ath_buf **buf) |
|---|
| 953 | 896 | { |
|---|
| 954 | 897 | struct ieee80211_tx_info *tx_info; |
|---|
| 955 | 898 | struct ath_frame_info *fi; |
|---|
| 956 | | - struct sk_buff *skb, *first_skb = NULL; |
|---|
| 957 | 899 | struct ath_buf *bf; |
|---|
| 900 | + struct sk_buff *skb, *first_skb = NULL; |
|---|
| 958 | 901 | u16 seqno; |
|---|
| 902 | + int ret; |
|---|
| 959 | 903 | |
|---|
| 960 | 904 | while (1) { |
|---|
| 961 | | - skb = ath_tid_dequeue(tid); |
|---|
| 962 | | - if (!skb) |
|---|
| 963 | | - break; |
|---|
| 905 | + ret = ath_tid_dequeue(tid, &skb); |
|---|
| 906 | + if (ret < 0) |
|---|
| 907 | + return ret; |
|---|
| 964 | 908 | |
|---|
| 965 | 909 | fi = get_frame_info(skb); |
|---|
| 966 | 910 | bf = fi->bf; |
|---|
| .. | .. |
|---|
| 992 | 936 | |
|---|
| 993 | 937 | if (!(tx_info->flags & IEEE80211_TX_CTL_AMPDU)) { |
|---|
| 994 | 938 | bf->bf_state.bf_type = 0; |
|---|
| 995 | | - return bf; |
|---|
| 939 | + break; |
|---|
| 996 | 940 | } |
|---|
| 997 | 941 | |
|---|
| 998 | 942 | bf->bf_state.bf_type = BUF_AMPDU | BUF_AGGR; |
|---|
| .. | .. |
|---|
| 1011 | 955 | first_skb = skb; |
|---|
| 1012 | 956 | continue; |
|---|
| 1013 | 957 | } |
|---|
| 1014 | | - break; |
|---|
| 958 | + return -EINPROGRESS; |
|---|
| 1015 | 959 | } |
|---|
| 1016 | 960 | |
|---|
| 1017 | 961 | if (tid->bar_index > ATH_BA_INDEX(tid->seq_start, seqno)) { |
|---|
| .. | .. |
|---|
| 1028 | 972 | if (bf_isampdu(bf)) |
|---|
| 1029 | 973 | ath_tx_addto_baw(sc, tid, bf); |
|---|
| 1030 | 974 | |
|---|
| 1031 | | - return bf; |
|---|
| 975 | + break; |
|---|
| 1032 | 976 | } |
|---|
| 1033 | 977 | |
|---|
| 1034 | | - return NULL; |
|---|
| 978 | + *buf = bf; |
|---|
| 979 | + return 0; |
|---|
| 1035 | 980 | } |
|---|
| 1036 | 981 | |
|---|
| 1037 | 982 | static int |
|---|
| .. | .. |
|---|
| 1041 | 986 | { |
|---|
| 1042 | 987 | #define PADBYTES(_len) ((4 - ((_len) % 4)) % 4) |
|---|
| 1043 | 988 | struct ath_buf *bf = bf_first, *bf_prev = NULL; |
|---|
| 1044 | | - int nframes = 0, ndelim; |
|---|
| 989 | + int nframes = 0, ndelim, ret; |
|---|
| 1045 | 990 | u16 aggr_limit = 0, al = 0, bpad = 0, |
|---|
| 1046 | 991 | al_delta, h_baw = tid->baw_size / 2; |
|---|
| 1047 | 992 | struct ieee80211_tx_info *tx_info; |
|---|
| .. | .. |
|---|
| 1093 | 1038 | |
|---|
| 1094 | 1039 | bf_prev = bf; |
|---|
| 1095 | 1040 | |
|---|
| 1096 | | - bf = ath_tx_get_tid_subframe(sc, txq, tid); |
|---|
| 1041 | + ret = ath_tx_get_tid_subframe(sc, txq, tid, &bf); |
|---|
| 1042 | + if (ret < 0) |
|---|
| 1043 | + break; |
|---|
| 1097 | 1044 | } |
|---|
| 1098 | 1045 | goto finish; |
|---|
| 1099 | 1046 | stop: |
|---|
| .. | .. |
|---|
| 1106 | 1053 | al = get_frame_info(bf->bf_mpdu)->framelen; |
|---|
| 1107 | 1054 | bf->bf_state.bf_type = BUF_AMPDU; |
|---|
| 1108 | 1055 | } else { |
|---|
| 1109 | | - TX_STAT_INC(txq->axq_qnum, a_aggr); |
|---|
| 1056 | + TX_STAT_INC(sc, txq->axq_qnum, a_aggr); |
|---|
| 1110 | 1057 | } |
|---|
| 1111 | 1058 | |
|---|
| 1112 | 1059 | return al; |
|---|
| .. | .. |
|---|
| 1495 | 1442 | struct ath_buf *bf_first) |
|---|
| 1496 | 1443 | { |
|---|
| 1497 | 1444 | struct ath_buf *bf = bf_first, *bf_prev = NULL; |
|---|
| 1498 | | - int nframes = 0; |
|---|
| 1445 | + int nframes = 0, ret; |
|---|
| 1499 | 1446 | |
|---|
| 1500 | 1447 | do { |
|---|
| 1501 | 1448 | struct ieee80211_tx_info *tx_info; |
|---|
| .. | .. |
|---|
| 1509 | 1456 | if (nframes >= 2) |
|---|
| 1510 | 1457 | break; |
|---|
| 1511 | 1458 | |
|---|
| 1512 | | - bf = ath_tx_get_tid_subframe(sc, txq, tid); |
|---|
| 1513 | | - if (!bf) |
|---|
| 1459 | + ret = ath_tx_get_tid_subframe(sc, txq, tid, &bf); |
|---|
| 1460 | + if (ret < 0) |
|---|
| 1514 | 1461 | break; |
|---|
| 1515 | 1462 | |
|---|
| 1516 | 1463 | tx_info = IEEE80211_SKB_CB(bf->bf_mpdu); |
|---|
| .. | .. |
|---|
| 1523 | 1470 | } while (1); |
|---|
| 1524 | 1471 | } |
|---|
| 1525 | 1472 | |
|---|
| 1526 | | -static bool ath_tx_sched_aggr(struct ath_softc *sc, struct ath_txq *txq, |
|---|
| 1527 | | - struct ath_atx_tid *tid) |
|---|
| 1473 | +static int ath_tx_sched_aggr(struct ath_softc *sc, struct ath_txq *txq, |
|---|
| 1474 | + struct ath_atx_tid *tid) |
|---|
| 1528 | 1475 | { |
|---|
| 1529 | | - struct ath_buf *bf; |
|---|
| 1476 | + struct ath_buf *bf = NULL; |
|---|
| 1530 | 1477 | struct ieee80211_tx_info *tx_info; |
|---|
| 1531 | 1478 | struct list_head bf_q; |
|---|
| 1532 | | - int aggr_len = 0; |
|---|
| 1479 | + int aggr_len = 0, ret; |
|---|
| 1533 | 1480 | bool aggr; |
|---|
| 1534 | | - |
|---|
| 1535 | | - if (!ath_tid_has_buffered(tid)) |
|---|
| 1536 | | - return false; |
|---|
| 1537 | 1481 | |
|---|
| 1538 | 1482 | INIT_LIST_HEAD(&bf_q); |
|---|
| 1539 | 1483 | |
|---|
| 1540 | | - bf = ath_tx_get_tid_subframe(sc, txq, tid); |
|---|
| 1541 | | - if (!bf) |
|---|
| 1542 | | - return false; |
|---|
| 1484 | + ret = ath_tx_get_tid_subframe(sc, txq, tid, &bf); |
|---|
| 1485 | + if (ret < 0) |
|---|
| 1486 | + return ret; |
|---|
| 1543 | 1487 | |
|---|
| 1544 | 1488 | tx_info = IEEE80211_SKB_CB(bf->bf_mpdu); |
|---|
| 1545 | 1489 | aggr = !!(tx_info->flags & IEEE80211_TX_CTL_AMPDU); |
|---|
| 1546 | 1490 | if ((aggr && txq->axq_ampdu_depth >= ATH_AGGR_MIN_QDEPTH) || |
|---|
| 1547 | 1491 | (!aggr && txq->axq_depth >= ATH_NON_AGGR_MIN_QDEPTH)) { |
|---|
| 1548 | 1492 | __skb_queue_tail(&tid->retry_q, bf->bf_mpdu); |
|---|
| 1549 | | - return false; |
|---|
| 1493 | + return -EBUSY; |
|---|
| 1550 | 1494 | } |
|---|
| 1551 | 1495 | |
|---|
| 1552 | 1496 | ath_set_rates(tid->an->vif, tid->an->sta, bf); |
|---|
| .. | .. |
|---|
| 1556 | 1500 | ath_tx_form_burst(sc, txq, tid, &bf_q, bf); |
|---|
| 1557 | 1501 | |
|---|
| 1558 | 1502 | if (list_empty(&bf_q)) |
|---|
| 1559 | | - return false; |
|---|
| 1503 | + return -EAGAIN; |
|---|
| 1560 | 1504 | |
|---|
| 1561 | 1505 | if (tid->clear_ps_filter || tid->an->no_ps_filter) { |
|---|
| 1562 | 1506 | tid->clear_ps_filter = false; |
|---|
| .. | .. |
|---|
| 1565 | 1509 | |
|---|
| 1566 | 1510 | ath_tx_fill_desc(sc, bf, txq, aggr_len); |
|---|
| 1567 | 1511 | ath_tx_txqaddbuf(sc, txq, &bf_q, false); |
|---|
| 1568 | | - return true; |
|---|
| 1512 | + return 0; |
|---|
| 1569 | 1513 | } |
|---|
| 1570 | 1514 | |
|---|
| 1571 | 1515 | int ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta, |
|---|
| .. | .. |
|---|
| 1628 | 1572 | { |
|---|
| 1629 | 1573 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); |
|---|
| 1630 | 1574 | struct ath_atx_tid *tid; |
|---|
| 1631 | | - struct ath_txq *txq; |
|---|
| 1632 | 1575 | int tidno; |
|---|
| 1633 | 1576 | |
|---|
| 1634 | 1577 | ath_dbg(common, XMIT, "%s called\n", __func__); |
|---|
| 1635 | 1578 | |
|---|
| 1636 | 1579 | for (tidno = 0; tidno < IEEE80211_NUM_TIDS; tidno++) { |
|---|
| 1637 | 1580 | tid = ath_node_to_tid(an, tidno); |
|---|
| 1638 | | - txq = tid->txq; |
|---|
| 1639 | | - |
|---|
| 1640 | | - ath_txq_lock(sc, txq); |
|---|
| 1641 | | - |
|---|
| 1642 | | - if (list_empty(&tid->list)) { |
|---|
| 1643 | | - ath_txq_unlock(sc, txq); |
|---|
| 1644 | | - continue; |
|---|
| 1645 | | - } |
|---|
| 1646 | 1581 | |
|---|
| 1647 | 1582 | if (!skb_queue_empty(&tid->retry_q)) |
|---|
| 1648 | 1583 | ieee80211_sta_set_buffered(sta, tid->tidno, true); |
|---|
| 1649 | 1584 | |
|---|
| 1650 | | - list_del_init(&tid->list); |
|---|
| 1651 | | - |
|---|
| 1652 | | - ath_txq_unlock(sc, txq); |
|---|
| 1653 | 1585 | } |
|---|
| 1654 | 1586 | } |
|---|
| 1655 | 1587 | |
|---|
| .. | .. |
|---|
| 1668 | 1600 | |
|---|
| 1669 | 1601 | ath_txq_lock(sc, txq); |
|---|
| 1670 | 1602 | tid->clear_ps_filter = true; |
|---|
| 1671 | | - if (ath_tid_has_buffered(tid)) { |
|---|
| 1603 | + if (!skb_queue_empty(&tid->retry_q)) { |
|---|
| 1672 | 1604 | ath_tx_queue_tid(sc, tid); |
|---|
| 1673 | 1605 | ath_txq_schedule(sc, txq); |
|---|
| 1674 | 1606 | } |
|---|
| 1675 | 1607 | ath_txq_unlock_complete(sc, txq); |
|---|
| 1608 | + |
|---|
| 1676 | 1609 | } |
|---|
| 1677 | 1610 | } |
|---|
| 1678 | 1611 | |
|---|
| .. | .. |
|---|
| 1703 | 1636 | struct ath_txq *txq = sc->tx.uapsdq; |
|---|
| 1704 | 1637 | struct ieee80211_tx_info *info; |
|---|
| 1705 | 1638 | struct list_head bf_q; |
|---|
| 1706 | | - struct ath_buf *bf_tail = NULL, *bf; |
|---|
| 1639 | + struct ath_buf *bf_tail = NULL, *bf = NULL; |
|---|
| 1707 | 1640 | int sent = 0; |
|---|
| 1708 | | - int i; |
|---|
| 1641 | + int i, ret; |
|---|
| 1709 | 1642 | |
|---|
| 1710 | 1643 | INIT_LIST_HEAD(&bf_q); |
|---|
| 1711 | 1644 | for (i = 0; tids && nframes; i++, tids >>= 1) { |
|---|
| .. | .. |
|---|
| 1718 | 1651 | |
|---|
| 1719 | 1652 | ath_txq_lock(sc, tid->txq); |
|---|
| 1720 | 1653 | while (nframes > 0) { |
|---|
| 1721 | | - bf = ath_tx_get_tid_subframe(sc, sc->tx.uapsdq, tid); |
|---|
| 1722 | | - if (!bf) |
|---|
| 1654 | + ret = ath_tx_get_tid_subframe(sc, sc->tx.uapsdq, |
|---|
| 1655 | + tid, &bf); |
|---|
| 1656 | + if (ret < 0) |
|---|
| 1723 | 1657 | break; |
|---|
| 1724 | 1658 | |
|---|
| 1725 | 1659 | ath9k_set_moredata(sc, bf, true); |
|---|
| .. | .. |
|---|
| 1733 | 1667 | bf_tail = bf; |
|---|
| 1734 | 1668 | nframes--; |
|---|
| 1735 | 1669 | sent++; |
|---|
| 1736 | | - TX_STAT_INC(txq->axq_qnum, a_queued_hw); |
|---|
| 1670 | + TX_STAT_INC(sc, txq->axq_qnum, a_queued_hw); |
|---|
| 1737 | 1671 | |
|---|
| 1738 | 1672 | if (an->sta && skb_queue_empty(&tid->retry_q)) |
|---|
| 1739 | 1673 | ieee80211_sta_set_buffered(an->sta, i, false); |
|---|
| .. | .. |
|---|
| 1985 | 1919 | */ |
|---|
| 1986 | 1920 | void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq) |
|---|
| 1987 | 1921 | { |
|---|
| 1922 | + struct ieee80211_hw *hw = sc->hw; |
|---|
| 1988 | 1923 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); |
|---|
| 1924 | + struct ieee80211_txq *queue; |
|---|
| 1989 | 1925 | struct ath_atx_tid *tid; |
|---|
| 1990 | | - struct list_head *tid_list; |
|---|
| 1991 | | - struct ath_acq *acq; |
|---|
| 1992 | | - bool active = AIRTIME_ACTIVE(sc->airtime_flags); |
|---|
| 1926 | + int ret; |
|---|
| 1993 | 1927 | |
|---|
| 1994 | 1928 | if (txq->mac80211_qnum < 0) |
|---|
| 1995 | 1929 | return; |
|---|
| .. | .. |
|---|
| 1997 | 1931 | if (test_bit(ATH_OP_HW_RESET, &common->op_flags)) |
|---|
| 1998 | 1932 | return; |
|---|
| 1999 | 1933 | |
|---|
| 1934 | + ieee80211_txq_schedule_start(hw, txq->mac80211_qnum); |
|---|
| 2000 | 1935 | spin_lock_bh(&sc->chan_lock); |
|---|
| 2001 | 1936 | rcu_read_lock(); |
|---|
| 2002 | | - acq = &sc->cur_chan->acq[txq->mac80211_qnum]; |
|---|
| 2003 | 1937 | |
|---|
| 2004 | 1938 | if (sc->cur_chan->stopped) |
|---|
| 2005 | 1939 | goto out; |
|---|
| 2006 | 1940 | |
|---|
| 2007 | | -begin: |
|---|
| 2008 | | - tid_list = &acq->acq_new; |
|---|
| 2009 | | - if (list_empty(tid_list)) { |
|---|
| 2010 | | - tid_list = &acq->acq_old; |
|---|
| 2011 | | - if (list_empty(tid_list)) |
|---|
| 2012 | | - goto out; |
|---|
| 2013 | | - } |
|---|
| 2014 | | - tid = list_first_entry(tid_list, struct ath_atx_tid, list); |
|---|
| 1941 | + while ((queue = ieee80211_next_txq(hw, txq->mac80211_qnum))) { |
|---|
| 1942 | + bool force; |
|---|
| 2015 | 1943 | |
|---|
| 2016 | | - if (active && tid->an->airtime_deficit[txq->mac80211_qnum] <= 0) { |
|---|
| 2017 | | - spin_lock_bh(&acq->lock); |
|---|
| 2018 | | - tid->an->airtime_deficit[txq->mac80211_qnum] += ATH_AIRTIME_QUANTUM; |
|---|
| 2019 | | - list_move_tail(&tid->list, &acq->acq_old); |
|---|
| 2020 | | - spin_unlock_bh(&acq->lock); |
|---|
| 2021 | | - goto begin; |
|---|
| 2022 | | - } |
|---|
| 1944 | + tid = (struct ath_atx_tid *)queue->drv_priv; |
|---|
| 2023 | 1945 | |
|---|
| 2024 | | - if (!ath_tid_has_buffered(tid)) { |
|---|
| 2025 | | - spin_lock_bh(&acq->lock); |
|---|
| 2026 | | - if ((tid_list == &acq->acq_new) && !list_empty(&acq->acq_old)) |
|---|
| 2027 | | - list_move_tail(&tid->list, &acq->acq_old); |
|---|
| 2028 | | - else { |
|---|
| 2029 | | - list_del_init(&tid->list); |
|---|
| 2030 | | - } |
|---|
| 2031 | | - spin_unlock_bh(&acq->lock); |
|---|
| 2032 | | - goto begin; |
|---|
| 2033 | | - } |
|---|
| 1946 | + ret = ath_tx_sched_aggr(sc, txq, tid); |
|---|
| 1947 | + ath_dbg(common, QUEUE, "ath_tx_sched_aggr returned %d\n", ret); |
|---|
| 2034 | 1948 | |
|---|
| 2035 | | - |
|---|
| 2036 | | - /* |
|---|
| 2037 | | - * If we succeed in scheduling something, immediately restart to make |
|---|
| 2038 | | - * sure we keep the HW busy. |
|---|
| 2039 | | - */ |
|---|
| 2040 | | - if(ath_tx_sched_aggr(sc, txq, tid)) { |
|---|
| 2041 | | - if (!active) { |
|---|
| 2042 | | - spin_lock_bh(&acq->lock); |
|---|
| 2043 | | - list_move_tail(&tid->list, &acq->acq_old); |
|---|
| 2044 | | - spin_unlock_bh(&acq->lock); |
|---|
| 2045 | | - } |
|---|
| 2046 | | - goto begin; |
|---|
| 1949 | + force = !skb_queue_empty(&tid->retry_q); |
|---|
| 1950 | + ieee80211_return_txq(hw, queue, force); |
|---|
| 2047 | 1951 | } |
|---|
| 2048 | 1952 | |
|---|
| 2049 | 1953 | out: |
|---|
| 2050 | 1954 | rcu_read_unlock(); |
|---|
| 2051 | 1955 | spin_unlock_bh(&sc->chan_lock); |
|---|
| 1956 | + ieee80211_txq_schedule_end(hw, txq->mac80211_qnum); |
|---|
| 2052 | 1957 | } |
|---|
| 2053 | 1958 | |
|---|
| 2054 | 1959 | void ath_txq_schedule_all(struct ath_softc *sc) |
|---|
| .. | .. |
|---|
| 2116 | 2021 | } |
|---|
| 2117 | 2022 | |
|---|
| 2118 | 2023 | if (puttxbuf) { |
|---|
| 2119 | | - TX_STAT_INC(txq->axq_qnum, puttxbuf); |
|---|
| 2024 | + TX_STAT_INC(sc, txq->axq_qnum, puttxbuf); |
|---|
| 2120 | 2025 | ath9k_hw_puttxbuf(ah, txq->axq_qnum, bf->bf_daddr); |
|---|
| 2121 | 2026 | ath_dbg(common, XMIT, "TXDP[%u] = %llx (%p)\n", |
|---|
| 2122 | 2027 | txq->axq_qnum, ito64(bf->bf_daddr), bf->bf_desc); |
|---|
| 2123 | 2028 | } |
|---|
| 2124 | 2029 | |
|---|
| 2125 | 2030 | if (!edma || sc->tx99_state) { |
|---|
| 2126 | | - TX_STAT_INC(txq->axq_qnum, txstart); |
|---|
| 2031 | + TX_STAT_INC(sc, txq->axq_qnum, txstart); |
|---|
| 2127 | 2032 | ath9k_hw_txstart(ah, txq->axq_qnum); |
|---|
| 2128 | 2033 | } |
|---|
| 2129 | 2034 | |
|---|
| .. | .. |
|---|
| 2160 | 2065 | bf->bf_lastbf = bf; |
|---|
| 2161 | 2066 | ath_tx_fill_desc(sc, bf, txq, fi->framelen); |
|---|
| 2162 | 2067 | ath_tx_txqaddbuf(sc, txq, &bf_head, false); |
|---|
| 2163 | | - TX_STAT_INC(txq->axq_qnum, queued); |
|---|
| 2068 | + TX_STAT_INC(sc, txq->axq_qnum, queued); |
|---|
| 2164 | 2069 | } |
|---|
| 2165 | 2070 | |
|---|
| 2166 | 2071 | static void setup_frame_info(struct ieee80211_hw *hw, |
|---|
| .. | .. |
|---|
| 2195 | 2100 | |
|---|
| 2196 | 2101 | if (tx_info->control.vif) { |
|---|
| 2197 | 2102 | struct ieee80211_vif *vif = tx_info->control.vif; |
|---|
| 2198 | | - |
|---|
| 2103 | + if (vif->bss_conf.txpower == INT_MIN) |
|---|
| 2104 | + goto nonvifpower; |
|---|
| 2199 | 2105 | txpower = 2 * vif->bss_conf.txpower; |
|---|
| 2200 | 2106 | } else { |
|---|
| 2201 | | - struct ath_softc *sc = hw->priv; |
|---|
| 2107 | + struct ath_softc *sc; |
|---|
| 2108 | + nonvifpower: |
|---|
| 2109 | + sc = hw->priv; |
|---|
| 2202 | 2110 | |
|---|
| 2203 | 2111 | txpower = sc->cur_chan->cur_txpower; |
|---|
| 2204 | 2112 | } |
|---|
| .. | .. |
|---|
| 2366 | 2274 | int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb, |
|---|
| 2367 | 2275 | struct ath_tx_control *txctl) |
|---|
| 2368 | 2276 | { |
|---|
| 2369 | | - struct ieee80211_hdr *hdr; |
|---|
| 2370 | 2277 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
|---|
| 2371 | 2278 | struct ieee80211_sta *sta = txctl->sta; |
|---|
| 2372 | 2279 | struct ieee80211_vif *vif = info->control.vif; |
|---|
| 2373 | 2280 | struct ath_frame_info *fi = get_frame_info(skb); |
|---|
| 2374 | | - struct ath_vif *avp = NULL; |
|---|
| 2375 | 2281 | struct ath_softc *sc = hw->priv; |
|---|
| 2376 | 2282 | struct ath_txq *txq = txctl->txq; |
|---|
| 2377 | 2283 | struct ath_atx_tid *tid = NULL; |
|---|
| .. | .. |
|---|
| 2380 | 2286 | bool ps_resp; |
|---|
| 2381 | 2287 | int q, ret; |
|---|
| 2382 | 2288 | |
|---|
| 2383 | | - if (vif) |
|---|
| 2384 | | - avp = (void *)vif->drv_priv; |
|---|
| 2385 | | - |
|---|
| 2386 | 2289 | ps_resp = !!(info->control.flags & IEEE80211_TX_CTRL_PS_RESPONSE); |
|---|
| 2387 | 2290 | |
|---|
| 2388 | 2291 | ret = ath_tx_prepare(hw, skb, txctl); |
|---|
| 2389 | 2292 | if (ret) |
|---|
| 2390 | 2293 | return ret; |
|---|
| 2391 | 2294 | |
|---|
| 2392 | | - hdr = (struct ieee80211_hdr *) skb->data; |
|---|
| 2393 | 2295 | /* |
|---|
| 2394 | 2296 | * At this point, the vif, hw_key and sta pointers in the tx control |
|---|
| 2395 | 2297 | * info are no longer valid (overwritten by the ath_frame_info data. |
|---|
| .. | .. |
|---|
| 2493 | 2395 | ath_txq_lock(sc, txctl.txq); |
|---|
| 2494 | 2396 | ath_tx_fill_desc(sc, bf, txctl.txq, 0); |
|---|
| 2495 | 2397 | ath_tx_txqaddbuf(sc, txctl.txq, &bf_q, false); |
|---|
| 2496 | | - TX_STAT_INC(txctl.txq->axq_qnum, queued); |
|---|
| 2398 | + TX_STAT_INC(sc, txctl.txq->axq_qnum, queued); |
|---|
| 2497 | 2399 | ath_txq_unlock(sc, txctl.txq); |
|---|
| 2498 | 2400 | } |
|---|
| 2499 | 2401 | |
|---|
| .. | .. |
|---|
| 2599 | 2501 | spin_unlock_irqrestore(&sc->tx.txbuflock, flags); |
|---|
| 2600 | 2502 | } |
|---|
| 2601 | 2503 | |
|---|
| 2504 | +static void ath_clear_tx_status(struct ieee80211_tx_info *tx_info) |
|---|
| 2505 | +{ |
|---|
| 2506 | + void *ptr = &tx_info->status; |
|---|
| 2507 | + |
|---|
| 2508 | + memset(ptr + sizeof(tx_info->status.rates), 0, |
|---|
| 2509 | + sizeof(tx_info->status) - |
|---|
| 2510 | + sizeof(tx_info->status.rates) - |
|---|
| 2511 | + sizeof(tx_info->status.status_driver_data)); |
|---|
| 2512 | +} |
|---|
| 2513 | + |
|---|
| 2602 | 2514 | static void ath_tx_rc_status(struct ath_softc *sc, struct ath_buf *bf, |
|---|
| 2603 | 2515 | struct ath_tx_status *ts, int nframes, int nbad, |
|---|
| 2604 | 2516 | int txok) |
|---|
| .. | .. |
|---|
| 2609 | 2521 | struct ieee80211_hw *hw = sc->hw; |
|---|
| 2610 | 2522 | struct ath_hw *ah = sc->sc_ah; |
|---|
| 2611 | 2523 | u8 i, tx_rateindex; |
|---|
| 2524 | + |
|---|
| 2525 | + ath_clear_tx_status(tx_info); |
|---|
| 2612 | 2526 | |
|---|
| 2613 | 2527 | if (txok) |
|---|
| 2614 | 2528 | tx_info->status.ack_signal = ts->ts_rssi; |
|---|
| .. | .. |
|---|
| 2623 | 2537 | } |
|---|
| 2624 | 2538 | tx_info->status.ampdu_len = nframes; |
|---|
| 2625 | 2539 | tx_info->status.ampdu_ack_len = nframes - nbad; |
|---|
| 2540 | + |
|---|
| 2541 | + tx_info->status.rates[tx_rateindex].count = ts->ts_longretry + 1; |
|---|
| 2542 | + |
|---|
| 2543 | + for (i = tx_rateindex + 1; i < hw->max_rates; i++) { |
|---|
| 2544 | + tx_info->status.rates[i].count = 0; |
|---|
| 2545 | + tx_info->status.rates[i].idx = -1; |
|---|
| 2546 | + } |
|---|
| 2626 | 2547 | |
|---|
| 2627 | 2548 | if ((ts->ts_status & ATH9K_TXERR_FILT) == 0 && |
|---|
| 2628 | 2549 | (tx_info->flags & IEEE80211_TX_CTL_NO_ACK) == 0) { |
|---|
| .. | .. |
|---|
| 2645 | 2566 | tx_info->status.rates[tx_rateindex].count = |
|---|
| 2646 | 2567 | hw->max_rate_tries; |
|---|
| 2647 | 2568 | } |
|---|
| 2648 | | - |
|---|
| 2649 | | - for (i = tx_rateindex + 1; i < hw->max_rates; i++) { |
|---|
| 2650 | | - tx_info->status.rates[i].count = 0; |
|---|
| 2651 | | - tx_info->status.rates[i].idx = -1; |
|---|
| 2652 | | - } |
|---|
| 2653 | | - |
|---|
| 2654 | | - tx_info->status.rates[tx_rateindex].count = ts->ts_longretry + 1; |
|---|
| 2655 | 2569 | } |
|---|
| 2656 | 2570 | |
|---|
| 2657 | 2571 | static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq) |
|---|
| .. | .. |
|---|
| 2706 | 2620 | if (status == -EINPROGRESS) |
|---|
| 2707 | 2621 | break; |
|---|
| 2708 | 2622 | |
|---|
| 2709 | | - TX_STAT_INC(txq->axq_qnum, txprocdesc); |
|---|
| 2623 | + TX_STAT_INC(sc, txq->axq_qnum, txprocdesc); |
|---|
| 2710 | 2624 | |
|---|
| 2711 | 2625 | /* |
|---|
| 2712 | 2626 | * Remove ath_buf's of the same transmit unit from txq, |
|---|
| .. | .. |
|---|
| 2785 | 2699 | |
|---|
| 2786 | 2700 | ath_txq_lock(sc, txq); |
|---|
| 2787 | 2701 | |
|---|
| 2788 | | - TX_STAT_INC(txq->axq_qnum, txprocdesc); |
|---|
| 2702 | + TX_STAT_INC(sc, txq->axq_qnum, txprocdesc); |
|---|
| 2789 | 2703 | |
|---|
| 2790 | 2704 | fifo_list = &txq->txq_fifo[txq->txq_tailidx]; |
|---|
| 2791 | 2705 | if (list_empty(fifo_list)) { |
|---|
| .. | .. |
|---|
| 2893 | 2807 | struct ath_atx_tid *tid; |
|---|
| 2894 | 2808 | int tidno, acno; |
|---|
| 2895 | 2809 | |
|---|
| 2896 | | - for (acno = 0; acno < IEEE80211_NUM_ACS; acno++) |
|---|
| 2897 | | - an->airtime_deficit[acno] = ATH_AIRTIME_QUANTUM; |
|---|
| 2898 | | - |
|---|
| 2899 | 2810 | for (tidno = 0; tidno < IEEE80211_NUM_TIDS; tidno++) { |
|---|
| 2900 | 2811 | tid = ath_node_to_tid(an, tidno); |
|---|
| 2901 | 2812 | tid->an = an; |
|---|
| .. | .. |
|---|
| 2905 | 2816 | tid->baw_head = tid->baw_tail = 0; |
|---|
| 2906 | 2817 | tid->active = false; |
|---|
| 2907 | 2818 | tid->clear_ps_filter = true; |
|---|
| 2908 | | - tid->has_queued = false; |
|---|
| 2909 | 2819 | __skb_queue_head_init(&tid->retry_q); |
|---|
| 2910 | 2820 | INIT_LIST_HEAD(&tid->list); |
|---|
| 2911 | 2821 | acno = TID_TO_WME_AC(tidno); |
|---|