source: trunk/package/mac80211/patches/560-mac80211_defer_bar_tx.patch @ 28190

Last change on this file since 28190 was 28190, checked in by nbd, 5 years ago

mac80211: fix an endian issue in BlockAckReq handling

File size: 2.9 KB
  • net/mac80211/sta_info.h

    a b enum ieee80211_sta_info_flags { 
    8484 * @stop_initiator: initiator of a session stop 
    8585 * @tx_stop: TX DelBA frame when stopping 
    8686 * @buf_size: reorder buffer size at receiver 
     87 * @failed_bar_ssn: ssn of the last failed BAR tx attempt 
     88 * @bar_pending: BAR needs to be re-sent 
    8789 * 
    8890 * This structure's lifetime is managed by RCU, assignments to 
    8991 * the array holding it must hold the aggregation mutex. 
    struct tid_ampdu_tx { 
    104106        u8 stop_initiator; 
    105107        bool tx_stop; 
    106108        u8 buf_size; 
     109 
     110        u16 failed_bar_ssn; 
     111        bool bar_pending; 
    107112}; 
    108113 
    109114/** 
  • net/mac80211/status.c

    a b static void ieee80211_handle_filtered_fr 
    127127        dev_kfree_skb(skb); 
    128128} 
    129129 
     130static void ieee80211_check_pending_bar(struct sta_info *sta, u8 *addr, u8 tid) 
     131{ 
     132        struct tid_ampdu_tx *tid_tx; 
     133 
     134        tid_tx = rcu_dereference(sta->ampdu_mlme.tid_tx[tid]); 
     135        if (!tid_tx || !tid_tx->bar_pending) 
     136                return; 
     137 
     138        tid_tx->bar_pending = false; 
     139        ieee80211_send_bar(sta->sdata, addr, tid, tid_tx->failed_bar_ssn); 
     140} 
     141 
    130142static void ieee80211_frame_acked(struct sta_info *sta, struct sk_buff *skb) 
    131143{ 
    132144        struct ieee80211_mgmt *mgmt = (void *) skb->data; 
    133145        struct ieee80211_local *local = sta->local; 
    134146        struct ieee80211_sub_if_data *sdata = sta->sdata; 
    135147 
     148        if (ieee80211_is_data_qos(mgmt->frame_control)) { 
     149                struct ieee80211_hdr *hdr = (void *) skb->data; 
     150                u8 *qc = ieee80211_get_qos_ctl(hdr); 
     151                u16 tid = qc[0] & 0xf; 
     152 
     153                ieee80211_check_pending_bar(sta, hdr->addr1, tid); 
     154        } 
     155 
    136156        if (ieee80211_is_action(mgmt->frame_control) && 
    137157            sdata->vif.type == NL80211_IFTYPE_STATION && 
    138158            mgmt->u.action.category == WLAN_CATEGORY_HT && 
    static void ieee80211_frame_acked(struct 
    161181        } 
    162182} 
    163183 
     184static void ieee80211_set_bar_pending(struct sta_info *sta, u8 tid, u16 ssn) 
     185{ 
     186        struct tid_ampdu_tx *tid_tx; 
     187 
     188        tid_tx = rcu_dereference(sta->ampdu_mlme.tid_tx[tid]); 
     189        if (!tid_tx) 
     190                return; 
     191 
     192        tid_tx->failed_bar_ssn = ssn; 
     193        tid_tx->bar_pending = true; 
     194} 
     195 
    164196/* 
    165197 * Use a static threshold for now, best value to be determined 
    166198 * by testing ... 
    void ieee80211_tx_status(struct ieee8021 
    246278                } 
    247279 
    248280                if (!acked && ieee80211_is_back_req(fc)) { 
     281                        u16 control; 
     282 
    249283                        /* 
    250284                         * BAR failed, let's tear down the BA session as a 
    251285                         * last resort as some STAs (Intel 5100 on Windows) 
    void ieee80211_tx_status(struct ieee8021 
    253287                         * correctly. 
    254288                         */ 
    255289                        bar = (struct ieee80211_bar *) skb->data; 
    256                         if (!(bar->control & IEEE80211_BAR_CTRL_MULTI_TID)) { 
    257                                 tid = (bar->control & 
     290                        control = le16_to_cpu(bar->control); 
     291                        if (!(control & IEEE80211_BAR_CTRL_MULTI_TID)) { 
     292                                u16 ssn = le16_to_cpu(bar->start_seq_num); 
     293 
     294                                tid = (control & 
    258295                                       IEEE80211_BAR_CTRL_TID_INFO_MASK) >> 
    259296                                      IEEE80211_BAR_CTRL_TID_INFO_SHIFT; 
    260                                 ieee80211_stop_tx_ba_session(&sta->sta, tid); 
     297 
     298                                ieee80211_set_bar_pending(sta, tid, ssn); 
    261299                        } 
    262300                } 
    263301 
Note: See TracBrowser for help on using the repository browser.