void ieee80211_tx_ba_session_handle_start(struct sta_info *sta, int tid) { struct tid_ampdu_tx *tid_tx = sta->ampdu_mlme.tid_tx[tid]; struct ieee80211_local *local = sta->local; struct ieee80211_sub_if_data *sdata = sta->sdata; u16 start_seq_num; int ret; lockdep_assert_held(&sta->ampdu_mlme.mtx); /* * While we're asking the driver about the aggregation, * stop the AC queue so that we don't have to worry * about frames that came in while we were doing that, * which would require us to put them to the AC pending * afterwards which just makes the code more complex. */ ieee80211_stop_queue_agg(local, tid); clear_bit(HT_AGG_STATE_WANT_START, &tid_tx->state); /* * make sure no packets are being processed to get * valid starting sequence number */ synchronize_net(); start_seq_num = sta->tid_seq[tid] >> 4; ret = drv_ampdu_action(local, sdata, IEEE80211_AMPDU_TX_START, &sta->sta, tid, &start_seq_num); if (ret) { #ifdef CONFIG_MAC80211_HT_DEBUG printk(KERN_DEBUG "BA request denied - HW unavailable for" " tid %d\n", tid); #endif spin_lock_bh(&sta->lock); rcu_assign_pointer(sta->ampdu_mlme.tid_tx[tid], NULL); spin_unlock_bh(&sta->lock); ieee80211_wake_queue_agg(local, tid); call_rcu(&tid_tx->rcu_head, kfree_tid_tx); return; } /* we can take packets again now */ ieee80211_wake_queue_agg(local, tid); /* activate the timer for the recipient's addBA response */ mod_timer(&tid_tx->addba_resp_timer, jiffies + ADDBA_RESP_INTERVAL); #ifdef CONFIG_MAC80211_HT_DEBUG printk(KERN_DEBUG "activated addBA response timer on tid %d\n", tid); #endif spin_lock_bh(&sta->lock); sta->ampdu_mlme.addba_req_num[tid]++; spin_unlock_bh(&sta->lock); /* send AddBA request */ ieee80211_send_addba_request(sdata, sta->sta.addr, tid, tid_tx->dialog_token, start_seq_num, 0x40, 5000); }
ieee80211_agg_splice_finish(struct ieee80211_local *local, u16 tid) { ieee80211_wake_queue_agg(local, tid); }
ieee80211_agg_splice_finish(struct ieee80211_sub_if_data *sdata, u16 tid) { ieee80211_wake_queue_agg(sdata, tid); }