source: trunk/package/mac80211/patches/521-ath9k_fix_ap_ps_buffering.patch @ 26545

Last change on this file since 26545 was 26545, checked in by nbd, 6 years ago

ath9k: properly count retries when frames are filtered due to excessive retries when a client is not in powersave mode

File size: 9.6 KB
  • drivers/net/wireless/ath/ath9k/ath9k.h

    a b struct ath_atx_ac { 
    200200        int sched; 
    201201        struct list_head list; 
    202202        struct list_head tid_q; 
     203        bool clear_ps_filter; 
    203204}; 
    204205 
    205206struct ath_frame_info { 
    struct ath_node { 
    257258        struct ath_atx_ac ac[WME_NUM_AC]; 
    258259        u16 maxampdu; 
    259260        u8 mpdudensity; 
     261 
     262        bool sleeping; 
    260263}; 
    261264 
    262265#define AGGR_CLEANUP         BIT(1) 
    int ath_tx_aggr_start(struct ath_softc * 
    338341void ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid); 
    339342void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid); 
    340343 
     344void ath_tx_aggr_wakeup(struct ath_softc *sc, struct ath_node *an); 
     345bool ath_tx_aggr_sleep(struct ath_softc *sc, struct ath_node *an); 
     346 
    341347/********/ 
    342348/* VIFs */ 
    343349/********/ 
  • drivers/net/wireless/ath/ath9k/main.c

    a b static int ath9k_sta_remove(struct ieee8 
    18001800        return 0; 
    18011801} 
    18021802 
     1803static void ath9k_sta_notify(struct ieee80211_hw *hw, 
     1804                         struct ieee80211_vif *vif, 
     1805                         enum sta_notify_cmd cmd, 
     1806                         struct ieee80211_sta *sta) 
     1807{ 
     1808        struct ath_softc *sc = hw->priv; 
     1809        struct ath_node *an = (struct ath_node *) sta->drv_priv; 
     1810 
     1811        switch (cmd) { 
     1812        case STA_NOTIFY_SLEEP: 
     1813                an->sleeping = true; 
     1814                if (ath_tx_aggr_sleep(sc, an)) 
     1815                        ieee80211_sta_set_tim(sta); 
     1816                break; 
     1817        case STA_NOTIFY_AWAKE: 
     1818                an->sleeping = false; 
     1819                ath_tx_aggr_wakeup(sc, an); 
     1820                break; 
     1821        } 
     1822} 
     1823 
    18031824static int ath9k_conf_tx(struct ieee80211_hw *hw, u16 queue, 
    18041825                         const struct ieee80211_tx_queue_params *params) 
    18051826{ 
    struct ieee80211_ops ath9k_ops = { 
    22062227        .configure_filter   = ath9k_configure_filter, 
    22072228        .sta_add            = ath9k_sta_add, 
    22082229        .sta_remove         = ath9k_sta_remove, 
     2230        .sta_notify         = ath9k_sta_notify, 
    22092231        .conf_tx            = ath9k_conf_tx, 
    22102232        .bss_info_changed   = ath9k_bss_info_changed, 
    22112233        .set_key            = ath9k_set_key, 
  • drivers/net/wireless/ath/ath9k/xmit.c

    a b static void ath_tx_complete_aggr(struct  
    357357        struct ath_frame_info *fi; 
    358358        int nframes; 
    359359        u8 tidno; 
     360        bool clear_filter; 
    360361 
    361362        skb = bf->bf_mpdu; 
    362363        hdr = (struct ieee80211_hdr *)skb->data; 
    static void ath_tx_complete_aggr(struct  
    441442                        /* transmit completion */ 
    442443                        acked_cnt++; 
    443444                } else { 
    444                         if (!(tid->state & AGGR_CLEANUP) && retry) { 
    445                                 if (fi->retries < ATH_MAX_SW_RETRIES) { 
    446                                         ath_tx_set_retry(sc, txq, bf->bf_mpdu); 
    447                                         txpending = 1; 
    448                                 } else { 
    449                                         bf->bf_state.bf_type |= BUF_XRETRY; 
    450                                         txfail = 1; 
    451                                         sendbar = 1; 
    452                                         txfail_cnt++; 
    453                                 } 
    454                         } else { 
     445                        if ((tid->state & AGGR_CLEANUP) || !retry) { 
    455446                                /* 
    456447                                 * cleanup in progress, just fail 
    457448                                 * the un-acked sub-frames 
    458449                                 */ 
    459450                                txfail = 1; 
     451                        } else if (fi->retries < ATH_MAX_SW_RETRIES) { 
     452                                if (!(ts->ts_status & ATH9K_TXERR_FILT) || 
     453                                    !an->sleeping) 
     454                                        ath_tx_set_retry(sc, txq, bf->bf_mpdu); 
     455 
     456                                clear_filter = true; 
     457                                txpending = 1; 
     458                        } else { 
     459                                bf->bf_state.bf_type |= BUF_XRETRY; 
     460                                txfail = 1; 
     461                                sendbar = 1; 
     462                                txfail_cnt++; 
    460463                        } 
    461464                } 
    462465 
    static void ath_tx_complete_aggr(struct  
    496499                                !txfail, sendbar); 
    497500                } else { 
    498501                        /* retry the un-acked ones */ 
     502                        ath9k_hw_set_clrdmask(sc->sc_ah, bf->bf_desc, false); 
    499503                        if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)) { 
    500504                                if (bf->bf_next == NULL && bf_last->bf_stale) { 
    501505                                        struct ath_buf *tbf; 
    static void ath_tx_complete_aggr(struct  
    546550 
    547551        /* prepend un-acked frames to the beginning of the pending frame queue */ 
    548552        if (!list_empty(&bf_pending)) { 
     553                if (an->sleeping) 
     554                        ieee80211_sta_set_tim(sta); 
     555 
    549556                spin_lock_bh(&txq->axq_lock); 
     557                if (clear_filter) 
     558                        tid->ac->clear_ps_filter = true; 
    550559                list_splice(&bf_pending, &tid->buf_q); 
    551560                ath_tx_queue_tid(txq, tid); 
    552561                spin_unlock_bh(&txq->axq_lock); 
    static void ath_tx_sched_aggr(struct ath 
    816825                bf = list_first_entry(&bf_q, struct ath_buf, list); 
    817826                bf->bf_lastbf = list_entry(bf_q.prev, struct ath_buf, list); 
    818827 
     828                if (tid->ac->clear_ps_filter) { 
     829                        tid->ac->clear_ps_filter = false; 
     830                        ath9k_hw_set_clrdmask(sc->sc_ah, bf->bf_desc, true); 
     831                } 
     832 
    819833                /* if only one frame, send as non-aggregate */ 
    820834                if (bf == bf->bf_lastbf) { 
    821835                        fi = get_frame_info(bf->bf_mpdu); 
    void ath_tx_aggr_stop(struct ath_softc * 
    896910        ath_tx_flush_tid(sc, txtid); 
    897911} 
    898912 
     913bool ath_tx_aggr_sleep(struct ath_softc *sc, struct ath_node *an) 
     914{ 
     915        struct ath_atx_tid *tid; 
     916        struct ath_atx_ac *ac; 
     917        struct ath_txq *txq; 
     918        bool buffered = false; 
     919        int tidno; 
     920 
     921        for (tidno = 0, tid = &an->tid[tidno]; 
     922             tidno < WME_NUM_TID; tidno++, tid++) { 
     923 
     924                if (!tid->sched) 
     925                        continue; 
     926 
     927                ac = tid->ac; 
     928                txq = ac->txq; 
     929 
     930                spin_lock_bh(&txq->axq_lock); 
     931 
     932                if (!list_empty(&tid->buf_q)) 
     933                        buffered = true; 
     934 
     935                tid->sched = false; 
     936                list_del(&tid->list); 
     937 
     938                if (ac->sched) { 
     939                        ac->sched = false; 
     940                        list_del(&ac->list); 
     941                } 
     942 
     943                spin_unlock_bh(&txq->axq_lock); 
     944        } 
     945 
     946        return buffered; 
     947} 
     948 
     949void ath_tx_aggr_wakeup(struct ath_softc *sc, struct ath_node *an) 
     950{ 
     951        struct ath_atx_tid *tid; 
     952        struct ath_atx_ac *ac; 
     953        struct ath_txq *txq; 
     954        int tidno; 
     955 
     956        for (tidno = 0, tid = &an->tid[tidno]; 
     957             tidno < WME_NUM_TID; tidno++, tid++) { 
     958 
     959                ac = tid->ac; 
     960                txq = ac->txq; 
     961 
     962                spin_lock_bh(&txq->axq_lock); 
     963                ac->clear_ps_filter = true; 
     964 
     965                if (!list_empty(&tid->buf_q) && !tid->paused) { 
     966                        ath_tx_queue_tid(txq, tid); 
     967                        ath_txq_schedule(sc, txq); 
     968                } 
     969 
     970                spin_unlock_bh(&txq->axq_lock); 
     971        } 
     972} 
     973 
    899974void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid) 
    900975{ 
    901976        struct ath_atx_tid *txtid; 
    static int setup_tx_flags(struct sk_buff 
    14911566        struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); 
    14921567        int flags = 0; 
    14931568 
    1494         flags |= ATH9K_TXDESC_CLRDMASK; /* needed for crypto errors */ 
    14951569        flags |= ATH9K_TXDESC_INTREQ; 
    14961570 
    14971571        if (tx_info->flags & IEEE80211_TX_CTL_NO_ACK) 
    static void ath_tx_start_dma(struct ath_ 
    17541828                if (txctl->paprd) 
    17551829                        bf->bf_state.bfs_paprd_timestamp = jiffies; 
    17561830 
     1831                if (tx_info->flags & IEEE80211_TX_CTL_CLEAR_PS_FILT) 
     1832                        ath9k_hw_set_clrdmask(sc->sc_ah, bf->bf_desc, true); 
     1833 
    17571834                ath_tx_send_normal(sc, txctl->txq, tid, &bf_head); 
    17581835        } 
    17591836 
  • drivers/net/wireless/ath/ath9k/hw-ops.h

    a b static inline void ath9k_hw_set11n_burst 
    122122        ath9k_hw_ops(ah)->set11n_burstduration(ah, ds, burstDuration); 
    123123} 
    124124 
     125static inline void ath9k_hw_set_clrdmask(struct ath_hw *ah, void *ds, bool val) 
     126{ 
     127        ath9k_hw_ops(ah)->set_clrdmask(ah, ds, val); 
     128} 
     129 
    125130/* Private hardware call ops */ 
    126131 
    127132/* PHY ops */ 
  • drivers/net/wireless/ath/ath9k/hw.h

    a b struct ath_hw_ops { 
    626626        void (*clr11n_aggr)(struct ath_hw *ah, void *ds); 
    627627        void (*set11n_burstduration)(struct ath_hw *ah, void *ds, 
    628628                                     u32 burstDuration); 
     629        void (*set_clrdmask)(struct ath_hw *ah, void *ds, bool val); 
    629630}; 
    630631 
    631632struct ath_nf_limits { 
  • drivers/net/wireless/ath/ath9k/ar9002_mac.c

    a b static void ar9002_hw_set11n_txdesc(stru 
    290290                | (flags & ATH9K_TXDESC_VMF ? AR_VirtMoreFrag : 0) 
    291291                | SM(txPower, AR_XmitPower) 
    292292                | (flags & ATH9K_TXDESC_VEOL ? AR_VEOL : 0) 
    293                 | (flags & ATH9K_TXDESC_CLRDMASK ? AR_ClrDestMask : 0) 
    294293                | (flags & ATH9K_TXDESC_INTREQ ? AR_TxIntrReq : 0) 
    295294                | (keyIx != ATH9K_TXKEYIX_INVALID ? AR_DestIdxValid : 0); 
    296295 
    static void ar9002_hw_set11n_txdesc(stru 
    311310        } 
    312311} 
    313312 
     313static void ar9002_hw_set_clrdmask(struct ath_hw *ah, void *ds, bool val) 
     314{ 
     315        struct ar5416_desc *ads = AR5416DESC(ds); 
     316 
     317        if (val) 
     318                ads->ds_ctl0 |= AR_ClrDestMask; 
     319        else 
     320                ads->ds_ctl0 &= ~AR_ClrDestMask; 
     321} 
     322 
    314323static void ar9002_hw_set11n_ratescenario(struct ath_hw *ah, void *ds, 
    315324                                          void *lastds, 
    316325                                          u32 durUpdateEn, u32 rtsctsRate, 
    void ar9002_hw_attach_mac_ops(struct ath 
    448457        ops->set11n_aggr_last = ar9002_hw_set11n_aggr_last; 
    449458        ops->clr11n_aggr = ar9002_hw_clr11n_aggr; 
    450459        ops->set11n_burstduration = ar9002_hw_set11n_burstduration; 
     460        ops->set_clrdmask = ar9002_hw_set_clrdmask; 
    451461} 
  • drivers/net/wireless/ath/ath9k/ar9003_mac.c

    a b static void ar9003_hw_set11n_txdesc(stru 
    329329                | (flags & ATH9K_TXDESC_VMF ? AR_VirtMoreFrag : 0) 
    330330                | SM(txpower, AR_XmitPower) 
    331331                | (flags & ATH9K_TXDESC_VEOL ? AR_VEOL : 0) 
    332                 | (flags & ATH9K_TXDESC_CLRDMASK ? AR_ClrDestMask : 0) 
    333332                | (keyIx != ATH9K_TXKEYIX_INVALID ? AR_DestIdxValid : 0) 
    334333                | (flags & ATH9K_TXDESC_LOWRXCHAIN ? AR_LowRxChain : 0); 
    335334 
    static void ar9003_hw_set11n_txdesc(stru 
    350349        ads->ctl22 = 0; 
    351350} 
    352351 
     352static void ar9003_hw_set_clrdmask(struct ath_hw *ah, void *ds, bool val) 
     353{ 
     354        struct ar9003_txc *ads = (struct ar9003_txc *) ds; 
     355 
     356        if (val) 
     357                ads->ctl11 |= AR_ClrDestMask; 
     358        else 
     359                ads->ctl11 &= ~AR_ClrDestMask; 
     360} 
     361 
    353362static void ar9003_hw_set11n_ratescenario(struct ath_hw *ah, void *ds, 
    354363                                          void *lastds, 
    355364                                          u32 durUpdateEn, u32 rtsctsRate, 
    void ar9003_hw_attach_mac_ops(struct ath 
    510519        ops->set11n_aggr_last = ar9003_hw_set11n_aggr_last; 
    511520        ops->clr11n_aggr = ar9003_hw_clr11n_aggr; 
    512521        ops->set11n_burstduration = ar9003_hw_set11n_burstduration; 
     522        ops->set_clrdmask = ar9003_hw_set_clrdmask; 
    513523} 
    514524 
    515525void ath9k_hw_set_rx_bufsize(struct ath_hw *ah, u16 buf_size) 
  • drivers/net/wireless/ath/ath9k/mac.h

    a b struct ath_desc { 
    239239        void *ds_vdata; 
    240240} __packed __aligned(4); 
    241241 
    242 #define ATH9K_TXDESC_CLRDMASK           0x0001 
    243242#define ATH9K_TXDESC_NOACK              0x0002 
    244243#define ATH9K_TXDESC_RTSENA             0x0004 
    245244#define ATH9K_TXDESC_CTSENA             0x0008 
Note: See TracBrowser for help on using the repository browser.