.. | .. |
---|
19 | 19 | #include "ath9k.h" |
---|
20 | 20 | #include "btcoex.h" |
---|
21 | 21 | |
---|
| 22 | +static void ath9k_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif, |
---|
| 23 | + u32 queues, bool drop); |
---|
| 24 | + |
---|
22 | 25 | u8 ath9k_parse_mpdudensity(u8 mpdudensity) |
---|
23 | 26 | { |
---|
24 | 27 | /* |
---|
.. | .. |
---|
200 | 203 | void ath_restart_work(struct ath_softc *sc) |
---|
201 | 204 | { |
---|
202 | 205 | ieee80211_queue_delayed_work(sc->hw, &sc->hw_check_work, |
---|
203 | | - ATH_HW_CHECK_POLL_INT); |
---|
| 206 | + msecs_to_jiffies(ATH_HW_CHECK_POLL_INT)); |
---|
204 | 207 | |
---|
205 | 208 | if (AR_SREV_9340(sc->sc_ah) || AR_SREV_9330(sc->sc_ah)) |
---|
206 | 209 | ieee80211_queue_delayed_work(sc->hw, &sc->hw_pll_work, |
---|
.. | .. |
---|
373 | 376 | ath_dynack_node_deinit(sc->sc_ah, an); |
---|
374 | 377 | } |
---|
375 | 378 | |
---|
376 | | -void ath9k_tasklet(unsigned long data) |
---|
| 379 | +void ath9k_tasklet(struct tasklet_struct *t) |
---|
377 | 380 | { |
---|
378 | | - struct ath_softc *sc = (struct ath_softc *)data; |
---|
| 381 | + struct ath_softc *sc = from_tasklet(sc, t, intr_tq); |
---|
379 | 382 | struct ath_hw *ah = sc->sc_ah; |
---|
380 | 383 | struct ath_common *common = ath9k_hw_common(ah); |
---|
381 | 384 | enum ath_reset_type type; |
---|
.. | .. |
---|
816 | 819 | |
---|
817 | 820 | if (ath_tx_start(hw, skb, &txctl) != 0) { |
---|
818 | 821 | ath_dbg(common, XMIT, "TX failed\n"); |
---|
819 | | - TX_STAT_INC(txctl.txq->axq_qnum, txfailed); |
---|
| 822 | + TX_STAT_INC(sc, txctl.txq->axq_qnum, txfailed); |
---|
820 | 823 | goto exit; |
---|
821 | 824 | } |
---|
822 | 825 | |
---|
.. | .. |
---|
836 | 839 | continue; |
---|
837 | 840 | |
---|
838 | 841 | txinfo = IEEE80211_SKB_CB(bf->bf_mpdu); |
---|
839 | | - fi = (struct ath_frame_info *)&txinfo->rate_driver_data[0]; |
---|
| 842 | + fi = (struct ath_frame_info *)&txinfo->status.status_driver_data[0]; |
---|
840 | 843 | if (fi->keyix == keyix) |
---|
841 | 844 | return true; |
---|
842 | 845 | } |
---|
.. | .. |
---|
847 | 850 | static bool ath9k_txq_has_key(struct ath_softc *sc, u32 keyix) |
---|
848 | 851 | { |
---|
849 | 852 | struct ath_hw *ah = sc->sc_ah; |
---|
850 | | - int i; |
---|
| 853 | + int i, j; |
---|
851 | 854 | struct ath_txq *txq; |
---|
852 | 855 | bool key_in_use = false; |
---|
853 | 856 | |
---|
.. | .. |
---|
865 | 868 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) { |
---|
866 | 869 | int idx = txq->txq_tailidx; |
---|
867 | 870 | |
---|
868 | | - while (!key_in_use && |
---|
869 | | - !list_empty(&txq->txq_fifo[idx])) { |
---|
| 871 | + for (j = 0; !key_in_use && |
---|
| 872 | + !list_empty(&txq->txq_fifo[idx]) && |
---|
| 873 | + j < ATH_TXFIFO_DEPTH; j++) { |
---|
870 | 874 | key_in_use = ath9k_txq_list_has_key( |
---|
871 | 875 | &txq->txq_fifo[idx], keyix); |
---|
872 | 876 | INCR(idx, ATH_TXFIFO_DEPTH); |
---|
.. | .. |
---|
1279 | 1283 | { |
---|
1280 | 1284 | int *power = data; |
---|
1281 | 1285 | |
---|
| 1286 | + if (vif->bss_conf.txpower == INT_MIN) |
---|
| 1287 | + return; |
---|
| 1288 | + |
---|
1282 | 1289 | if (*power < vif->bss_conf.txpower) |
---|
1283 | 1290 | *power = vif->bss_conf.txpower; |
---|
1284 | 1291 | } |
---|
.. | .. |
---|
1556 | 1563 | FIF_OTHER_BSS | \ |
---|
1557 | 1564 | FIF_BCN_PRBRESP_PROMISC | \ |
---|
1558 | 1565 | FIF_PROBE_REQ | \ |
---|
| 1566 | + FIF_MCAST_ACTION | \ |
---|
1559 | 1567 | FIF_FCSFAIL) |
---|
1560 | 1568 | |
---|
1561 | 1569 | /* FIXME: sc->sc_full_reset ? */ |
---|
.. | .. |
---|
1777 | 1785 | * frames is a acceptable to allow RSN IBSS to be used. |
---|
1778 | 1786 | */ |
---|
1779 | 1787 | return -EOPNOTSUPP; |
---|
| 1788 | + } |
---|
| 1789 | + |
---|
| 1790 | + /* There may be MPDUs queued for the outgoing PTK key. Flush queues to |
---|
| 1791 | + * make sure these are not send unencrypted or with a wrong (new) key |
---|
| 1792 | + */ |
---|
| 1793 | + if (cmd == DISABLE_KEY && key->flags & IEEE80211_KEY_FLAG_PAIRWISE) { |
---|
| 1794 | + ieee80211_stop_queues(hw); |
---|
| 1795 | + ath9k_flush(hw, vif, 0, true); |
---|
| 1796 | + ieee80211_wake_queues(hw); |
---|
1780 | 1797 | } |
---|
1781 | 1798 | |
---|
1782 | 1799 | mutex_lock(&sc->mutex); |
---|
.. | .. |
---|
2020 | 2037 | ath9k_ps_wakeup(sc); |
---|
2021 | 2038 | ret = ath_tx_aggr_start(sc, sta, tid, ssn); |
---|
2022 | 2039 | if (!ret) |
---|
2023 | | - ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid); |
---|
| 2040 | + ret = IEEE80211_AMPDU_TX_START_IMMEDIATE; |
---|
2024 | 2041 | ath9k_ps_restore(sc); |
---|
2025 | 2042 | break; |
---|
2026 | 2043 | case IEEE80211_AMPDU_TX_STOP_FLUSH: |
---|
2027 | 2044 | case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT: |
---|
2028 | 2045 | flush = true; |
---|
2029 | | - /* fall through */ |
---|
| 2046 | + fallthrough; |
---|
2030 | 2047 | case IEEE80211_AMPDU_TX_STOP_CONT: |
---|
2031 | 2048 | ath9k_ps_wakeup(sc); |
---|
2032 | 2049 | ath_tx_aggr_stop(sc, sta, tid); |
---|
.. | .. |
---|
2227 | 2244 | } |
---|
2228 | 2245 | |
---|
2229 | 2246 | ieee80211_queue_delayed_work(hw, &sc->hw_check_work, |
---|
2230 | | - ATH_HW_CHECK_POLL_INT); |
---|
| 2247 | + msecs_to_jiffies(ATH_HW_CHECK_POLL_INT)); |
---|
2231 | 2248 | } |
---|
2232 | 2249 | |
---|
2233 | 2250 | static bool ath9k_tx_frames_pending(struct ieee80211_hw *hw) |
---|
.. | .. |
---|
2491 | 2508 | return ret; |
---|
2492 | 2509 | } |
---|
2493 | 2510 | |
---|
2494 | | -static int ath9k_cancel_remain_on_channel(struct ieee80211_hw *hw) |
---|
| 2511 | +static int ath9k_cancel_remain_on_channel(struct ieee80211_hw *hw, |
---|
| 2512 | + struct ieee80211_vif *vif) |
---|
2495 | 2513 | { |
---|
2496 | 2514 | struct ath_softc *sc = hw->priv; |
---|
2497 | 2515 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); |
---|