Lines Matching +full:local +full:- +full:timer +full:- +full:stop
1 // SPDX-License-Identifier: GPL-2.0-only
6 * Copyright 2002-2005, Instant802 Networks, Inc.
7 * Copyright 2005-2006, Devicescape Software, Inc.
8 * Copyright 2006-2007 Jiri Benc <jbenc@suse.cz>
10 * Copyright 2007-2010, Intel Corporation
11 * Copyright(c) 2015-2017 Intel Deutschland GmbH
12 * Copyright (C) 2018 - 2024 Intel Corporation
20 #include "driver-ops.h"
24 * DOC: TX A-MPDU aggregation
28 * packets with a flag indicating A-MPDU aggregation. The driver
65 struct ieee80211_sub_if_data *sdata = sta->sdata; in ieee80211_send_addba_request()
66 struct ieee80211_local *local = sdata->local; in ieee80211_send_addba_request() local
73 local->hw.extra_tx_headroom); in ieee80211_send_addba_request()
77 skb_reserve(skb, local->hw.extra_tx_headroom); in ieee80211_send_addba_request()
78 mgmt = ieee80211_mgmt_ba(skb, sta->sta.addr, sdata); in ieee80211_send_addba_request()
80 skb_put(skb, 1 + sizeof(mgmt->u.action.u.addba_req)); in ieee80211_send_addba_request()
82 mgmt->u.action.category = WLAN_CATEGORY_BACK; in ieee80211_send_addba_request()
83 mgmt->u.action.u.addba_req.action_code = WLAN_ACTION_ADDBA_REQ; in ieee80211_send_addba_request()
85 mgmt->u.action.u.addba_req.dialog_token = dialog_token; in ieee80211_send_addba_request()
91 mgmt->u.action.u.addba_req.capab = cpu_to_le16(capab); in ieee80211_send_addba_request()
93 mgmt->u.action.u.addba_req.timeout = cpu_to_le16(timeout); in ieee80211_send_addba_request()
94 mgmt->u.action.u.addba_req.start_seq_num = in ieee80211_send_addba_request()
97 if (sta->sta.deflink.he_cap.has_he) in ieee80211_send_addba_request()
100 ieee80211_tx_skb_tid(sdata, skb, tid, -1); in ieee80211_send_addba_request()
106 struct ieee80211_local *local = sdata->local; in ieee80211_send_bar() local
111 skb = dev_alloc_skb(sizeof(*bar) + local->hw.extra_tx_headroom); in ieee80211_send_bar()
115 skb_reserve(skb, local->hw.extra_tx_headroom); in ieee80211_send_bar()
117 bar->frame_control = cpu_to_le16(IEEE80211_FTYPE_CTL | in ieee80211_send_bar()
119 memcpy(bar->ra, ra, ETH_ALEN); in ieee80211_send_bar()
120 memcpy(bar->ta, sdata->vif.addr, ETH_ALEN); in ieee80211_send_bar()
124 bar->control = cpu_to_le16(bar_control); in ieee80211_send_bar()
125 bar->start_seq_num = cpu_to_le16(ssn); in ieee80211_send_bar()
127 IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT | in ieee80211_send_bar()
129 ieee80211_tx_skb_tid(sdata, skb, tid, -1); in ieee80211_send_bar()
136 lockdep_assert_wiphy(sta->local->hw.wiphy); in ieee80211_assign_tid_tx()
137 lockdep_assert_held(&sta->lock); in ieee80211_assign_tid_tx()
138 rcu_assign_pointer(sta->ampdu_mlme.tid_tx[tid], tid_tx); in ieee80211_assign_tid_tx()
144 * refcount the global queue stop caused by that in order
146 * setup or teardown re-enables queues before the other is
155 int queue = sdata->vif.hw_queue[ieee80211_ac_from_tid(tid)]; in __acquires()
159 if (atomic_inc_return(&sdata->local->agg_queue_stop[queue]) == 1) in __acquires()
161 &sdata->local->hw, queue, in __acquires()
170 int queue = sdata->vif.hw_queue[ieee80211_ac_from_tid(tid)]; in __releases()
172 if (atomic_dec_return(&sdata->local->agg_queue_stop[queue]) == 0) in __releases()
174 &sdata->local->hw, queue, in __releases()
183 struct ieee80211_txq *txq = sta->sta.txq[tid]; in ieee80211_agg_stop_txq()
192 sdata = vif_to_sdata(txq->vif); in ieee80211_agg_stop_txq()
193 fq = &sdata->local->fq; in ieee80211_agg_stop_txq()
196 spin_lock_bh(&fq->lock); in ieee80211_agg_stop_txq()
197 set_bit(IEEE80211_TXQ_STOP, &txqi->flags); in ieee80211_agg_stop_txq()
198 spin_unlock_bh(&fq->lock); in ieee80211_agg_stop_txq()
204 struct ieee80211_txq *txq = sta->sta.txq[tid]; in ieee80211_agg_start_txq()
207 lockdep_assert_wiphy(sta->local->hw.wiphy); in ieee80211_agg_start_txq()
215 set_bit(IEEE80211_TXQ_AMPDU, &txqi->flags); in ieee80211_agg_start_txq()
217 clear_bit(IEEE80211_TXQ_AMPDU, &txqi->flags); in ieee80211_agg_start_txq()
219 clear_bit(IEEE80211_TXQ_STOP, &txqi->flags); in ieee80211_agg_start_txq()
222 schedule_and_wake_txq(sta->sdata->local, txqi); in ieee80211_agg_start_txq()
228 * splice packets from the STA's pending to the local pending,
235 struct ieee80211_local *local = sdata->local; in __acquires() local
236 int queue = sdata->vif.hw_queue[ieee80211_ac_from_tid(tid)]; in __acquires()
246 if (!skb_queue_empty(&tid_tx->pending)) { in __acquires()
247 spin_lock_irqsave(&local->queue_stop_reason_lock, flags); in __acquires()
249 skb_queue_splice_tail_init(&tid_tx->pending, in __acquires()
250 &local->pending[queue]); in __acquires()
251 spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); in __acquires()
265 lockdep_assert_wiphy(sta->local->hw.wiphy); in ieee80211_remove_tid_tx()
266 lockdep_assert_held(&sta->lock); in ieee80211_remove_tid_tx()
274 * stop the queue now, we will not get any more packets, and any in ieee80211_remove_tid_tx()
280 ieee80211_agg_splice_packets(sta->sdata, tid_tx, tid); in ieee80211_remove_tid_tx()
285 ieee80211_agg_splice_finish(sta->sdata, tid); in ieee80211_remove_tid_tx()
293 struct ieee80211_local *local = sta->local; in __ieee80211_stop_tx_ba_session() local
296 .sta = &sta->sta, in __ieee80211_stop_tx_ba_session()
305 lockdep_assert_wiphy(sta->local->hw.wiphy); in __ieee80211_stop_tx_ba_session()
318 return -EINVAL; in __ieee80211_stop_tx_ba_session()
321 spin_lock_bh(&sta->lock); in __ieee80211_stop_tx_ba_session()
324 tid_tx = sta->ampdu_mlme.tid_start_tx[tid]; in __ieee80211_stop_tx_ba_session()
326 sta->ampdu_mlme.tid_start_tx[tid] = NULL; in __ieee80211_stop_tx_ba_session()
330 spin_unlock_bh(&sta->lock); in __ieee80211_stop_tx_ba_session()
331 return -ENOENT; in __ieee80211_stop_tx_ba_session()
335 * if we're already stopping ignore any new requests to stop in __ieee80211_stop_tx_ba_session()
338 if (test_bit(HT_AGG_STATE_STOPPING, &tid_tx->state)) { in __ieee80211_stop_tx_ba_session()
339 spin_unlock_bh(&sta->lock); in __ieee80211_stop_tx_ba_session()
341 return -EALREADY; in __ieee80211_stop_tx_ba_session()
343 ret = drv_ampdu_action(local, sta->sdata, ¶ms); in __ieee80211_stop_tx_ba_session()
348 if (test_bit(HT_AGG_STATE_WANT_START, &tid_tx->state)) { in __ieee80211_stop_tx_ba_session()
351 spin_unlock_bh(&sta->lock); in __ieee80211_stop_tx_ba_session()
356 set_bit(HT_AGG_STATE_STOPPING, &tid_tx->state); in __ieee80211_stop_tx_ba_session()
360 spin_unlock_bh(&sta->lock); in __ieee80211_stop_tx_ba_session()
362 ht_dbg(sta->sdata, "Tx BA session stop requested for %pM tid %u\n", in __ieee80211_stop_tx_ba_session()
363 sta->sta.addr, tid); in __ieee80211_stop_tx_ba_session()
365 timer_delete_sync(&tid_tx->addba_resp_timer); in __ieee80211_stop_tx_ba_session()
366 timer_delete_sync(&tid_tx->session_timer); in __ieee80211_stop_tx_ba_session()
370 * to the driver but are put onto tid_tx->pending instead, in __ieee80211_stop_tx_ba_session()
373 clear_bit(HT_AGG_STATE_OPERATIONAL, &tid_tx->state); in __ieee80211_stop_tx_ba_session()
387 if (!local->in_reconfig) in __ieee80211_stop_tx_ba_session()
390 tid_tx->stop_initiator = reason == AGG_STOP_PEER_REQUEST ? in __ieee80211_stop_tx_ba_session()
393 tid_tx->tx_stop = reason == AGG_STOP_LOCAL_REQUEST; in __ieee80211_stop_tx_ba_session()
395 ret = drv_ampdu_action(local, sta->sdata, ¶ms); in __ieee80211_stop_tx_ba_session()
419 * After sending add Block Ack request we activated a timer until
421 * If this timer expires sta_addba_resp_timer_expired will be executed.
426 struct sta_info *sta = tid_tx->sta; in sta_addba_resp_timer_expired()
427 u8 tid = tid_tx->tid; in sta_addba_resp_timer_expired()
430 if (test_bit(HT_AGG_STATE_RESPONSE_RECEIVED, &tid_tx->state)) { in sta_addba_resp_timer_expired()
431 ht_dbg(sta->sdata, in sta_addba_resp_timer_expired()
432 "timer expired on %pM tid %d not expecting addBA response\n", in sta_addba_resp_timer_expired()
433 sta->sta.addr, tid); in sta_addba_resp_timer_expired()
437 ht_dbg(sta->sdata, "addBA response timer expired on %pM tid %d\n", in sta_addba_resp_timer_expired()
438 sta->sta.addr, tid); in sta_addba_resp_timer_expired()
440 ieee80211_stop_tx_ba_session(&sta->sta, tid); in sta_addba_resp_timer_expired()
446 struct ieee80211_sub_if_data *sdata = sta->sdata; in ieee80211_send_addba_with_timeout()
447 struct ieee80211_local *local = sta->local; in ieee80211_send_addba_with_timeout() local
448 u8 tid = tid_tx->tid; in ieee80211_send_addba_with_timeout()
451 if (WARN_ON_ONCE(test_bit(HT_AGG_STATE_STOPPING, &tid_tx->state) || in ieee80211_send_addba_with_timeout()
452 test_bit(HT_AGG_STATE_WANT_STOP, &tid_tx->state))) in ieee80211_send_addba_with_timeout()
455 lockdep_assert_wiphy(sta->local->hw.wiphy); in ieee80211_send_addba_with_timeout()
457 /* activate the timer for the recipient's addBA response */ in ieee80211_send_addba_with_timeout()
458 mod_timer(&tid_tx->addba_resp_timer, jiffies + ADDBA_RESP_INTERVAL); in ieee80211_send_addba_with_timeout()
459 ht_dbg(sdata, "activated addBA response timer on %pM tid %d\n", in ieee80211_send_addba_with_timeout()
460 sta->sta.addr, tid); in ieee80211_send_addba_with_timeout()
462 spin_lock_bh(&sta->lock); in ieee80211_send_addba_with_timeout()
463 sta->ampdu_mlme.last_addba_req_time[tid] = jiffies; in ieee80211_send_addba_with_timeout()
464 sta->ampdu_mlme.addba_req_num[tid]++; in ieee80211_send_addba_with_timeout()
465 spin_unlock_bh(&sta->lock); in ieee80211_send_addba_with_timeout()
467 if (sta->sta.valid_links || in ieee80211_send_addba_with_timeout()
468 sta->sta.deflink.eht_cap.has_eht || in ieee80211_send_addba_with_timeout()
469 ieee80211_hw_check(&local->hw, STRICT)) { in ieee80211_send_addba_with_timeout()
470 buf_size = local->hw.max_tx_aggregation_subframes; in ieee80211_send_addba_with_timeout()
471 } else if (sta->sta.deflink.he_cap.has_he) { in ieee80211_send_addba_with_timeout()
472 buf_size = min_t(u16, local->hw.max_tx_aggregation_subframes, in ieee80211_send_addba_with_timeout()
485 ieee80211_send_addba_request(sta, tid, tid_tx->dialog_token, in ieee80211_send_addba_with_timeout()
486 tid_tx->ssn, buf_size, tid_tx->timeout); in ieee80211_send_addba_with_timeout()
488 WARN_ON(test_and_set_bit(HT_AGG_STATE_SENT_ADDBA, &tid_tx->state)); in ieee80211_send_addba_with_timeout()
494 struct ieee80211_local *local = sta->local; in ieee80211_tx_ba_session_handle_start() local
495 struct ieee80211_sub_if_data *sdata = sta->sdata; in ieee80211_tx_ba_session_handle_start()
497 .sta = &sta->sta, in ieee80211_tx_ba_session_handle_start()
513 clear_bit(HT_AGG_STATE_WANT_START, &tid_tx->state); in ieee80211_tx_ba_session_handle_start()
517 * we have a valid starting sequence number and that in-flight in ieee80211_tx_ba_session_handle_start()
523 params.ssn = sta->tid_seq[tid] >> 4; in ieee80211_tx_ba_session_handle_start()
524 ret = drv_ampdu_action(local, sdata, ¶ms); in ieee80211_tx_ba_session_handle_start()
525 tid_tx->ssn = params.ssn; in ieee80211_tx_ba_session_handle_start()
534 set_bit(HT_AGG_STATE_DRV_READY, &tid_tx->state); in ieee80211_tx_ba_session_handle_start()
537 "BA request denied - HW unavailable for %pM tid %d\n", in ieee80211_tx_ba_session_handle_start()
538 sta->sta.addr, tid); in ieee80211_tx_ba_session_handle_start()
539 spin_lock_bh(&sta->lock); in ieee80211_tx_ba_session_handle_start()
543 spin_unlock_bh(&sta->lock); in ieee80211_tx_ba_session_handle_start()
563 tid_tx = rcu_dereference(sta->ampdu_mlme.tid_tx[tid]); in ieee80211_refresh_tx_agg_session_timer()
567 tid_tx->last_tx = jiffies; in ieee80211_refresh_tx_agg_session_timer()
572 * After accepting the AddBA Response we activated a timer,
578 struct sta_info *sta = tid_tx->sta; in sta_tx_agg_session_timer_expired()
579 u8 tid = tid_tx->tid; in sta_tx_agg_session_timer_expired()
582 if (test_bit(HT_AGG_STATE_STOPPING, &tid_tx->state)) { in sta_tx_agg_session_timer_expired()
586 timeout = tid_tx->last_tx + TU_TO_JIFFIES(tid_tx->timeout); in sta_tx_agg_session_timer_expired()
588 mod_timer(&tid_tx->session_timer, timeout); in sta_tx_agg_session_timer_expired()
592 ht_dbg(sta->sdata, "tx session timer expired on %pM tid %d\n", in sta_tx_agg_session_timer_expired()
593 sta->sta.addr, tid); in sta_tx_agg_session_timer_expired()
595 ieee80211_stop_tx_ba_session(&sta->sta, tid); in sta_tx_agg_session_timer_expired()
602 struct ieee80211_sub_if_data *sdata = sta->sdata; in ieee80211_start_tx_ba_session()
603 struct ieee80211_local *local = sdata->local; in ieee80211_start_tx_ba_session() local
609 if (WARN(sta->reserved_tid == tid, in ieee80211_start_tx_ba_session()
611 return -EINVAL; in ieee80211_start_tx_ba_session()
613 if (!pubsta->valid_links && in ieee80211_start_tx_ba_session()
614 !pubsta->deflink.ht_cap.ht_supported && in ieee80211_start_tx_ba_session()
615 !pubsta->deflink.vht_cap.vht_supported && in ieee80211_start_tx_ba_session()
616 !pubsta->deflink.he_cap.has_he && in ieee80211_start_tx_ba_session()
617 !pubsta->deflink.eht_cap.has_eht) in ieee80211_start_tx_ba_session()
618 return -EINVAL; in ieee80211_start_tx_ba_session()
620 if (WARN_ON_ONCE(!local->ops->ampdu_action)) in ieee80211_start_tx_ba_session()
621 return -EINVAL; in ieee80211_start_tx_ba_session()
624 !ieee80211_hw_check(&local->hw, AMPDU_AGGREGATION) || in ieee80211_start_tx_ba_session()
625 ieee80211_hw_check(&local->hw, TX_AMPDU_SETUP_IN_HW)) in ieee80211_start_tx_ba_session()
626 return -EINVAL; in ieee80211_start_tx_ba_session()
629 return -EINVAL; in ieee80211_start_tx_ba_session()
632 pubsta->addr, tid); in ieee80211_start_tx_ba_session()
634 if (sdata->vif.type != NL80211_IFTYPE_STATION && in ieee80211_start_tx_ba_session()
635 sdata->vif.type != NL80211_IFTYPE_MESH_POINT && in ieee80211_start_tx_ba_session()
636 sdata->vif.type != NL80211_IFTYPE_AP_VLAN && in ieee80211_start_tx_ba_session()
637 sdata->vif.type != NL80211_IFTYPE_AP && in ieee80211_start_tx_ba_session()
638 sdata->vif.type != NL80211_IFTYPE_ADHOC) in ieee80211_start_tx_ba_session()
639 return -EINVAL; in ieee80211_start_tx_ba_session()
643 "BA sessions blocked - Denying BA session request %pM tid %d\n", in ieee80211_start_tx_ba_session()
644 sta->sta.addr, tid); in ieee80211_start_tx_ba_session()
645 return -EINVAL; in ieee80211_start_tx_ba_session()
651 "MFP STA not authorized - deny BA session request %pM tid %d\n", in ieee80211_start_tx_ba_session()
652 sta->sta.addr, tid); in ieee80211_start_tx_ba_session()
653 return -EINVAL; in ieee80211_start_tx_ba_session()
657 * 802.11n-2009 11.5.1.1: If the initiating STA is an HT STA, is a in ieee80211_start_tx_ba_session()
668 if (sta->sdata->vif.type == NL80211_IFTYPE_ADHOC && in ieee80211_start_tx_ba_session()
669 !sta->sta.deflink.ht_cap.ht_supported) { in ieee80211_start_tx_ba_session()
671 "BA request denied - IBSS STA %pM does not advertise HT support\n", in ieee80211_start_tx_ba_session()
672 pubsta->addr); in ieee80211_start_tx_ba_session()
673 return -EINVAL; in ieee80211_start_tx_ba_session()
676 spin_lock_bh(&sta->lock); in ieee80211_start_tx_ba_session()
678 /* we have tried too many times, receiver does not want A-MPDU */ in ieee80211_start_tx_ba_session()
679 if (sta->ampdu_mlme.addba_req_num[tid] > HT_AGG_MAX_RETRIES) { in ieee80211_start_tx_ba_session()
680 ret = -EBUSY; in ieee80211_start_tx_ba_session()
689 if (sta->ampdu_mlme.addba_req_num[tid] > HT_AGG_BURST_RETRIES && in ieee80211_start_tx_ba_session()
690 time_before(jiffies, sta->ampdu_mlme.last_addba_req_time[tid] + in ieee80211_start_tx_ba_session()
693 "BA request denied - %d failed requests on %pM tid %u\n", in ieee80211_start_tx_ba_session()
694 sta->ampdu_mlme.addba_req_num[tid], sta->sta.addr, tid); in ieee80211_start_tx_ba_session()
695 ret = -EBUSY; in ieee80211_start_tx_ba_session()
701 if (tid_tx || sta->ampdu_mlme.tid_start_tx[tid]) { in ieee80211_start_tx_ba_session()
703 "BA request denied - session is not idle on %pM tid %u\n", in ieee80211_start_tx_ba_session()
704 sta->sta.addr, tid); in ieee80211_start_tx_ba_session()
705 ret = -EAGAIN; in ieee80211_start_tx_ba_session()
709 /* prepare A-MPDU MLME for Tx aggregation */ in ieee80211_start_tx_ba_session()
712 ret = -ENOMEM; in ieee80211_start_tx_ba_session()
716 skb_queue_head_init(&tid_tx->pending); in ieee80211_start_tx_ba_session()
717 __set_bit(HT_AGG_STATE_WANT_START, &tid_tx->state); in ieee80211_start_tx_ba_session()
719 tid_tx->timeout = timeout; in ieee80211_start_tx_ba_session()
720 tid_tx->sta = sta; in ieee80211_start_tx_ba_session()
721 tid_tx->tid = tid; in ieee80211_start_tx_ba_session()
723 /* response timer */ in ieee80211_start_tx_ba_session()
724 timer_setup(&tid_tx->addba_resp_timer, sta_addba_resp_timer_expired, 0); in ieee80211_start_tx_ba_session()
726 /* tx timer */ in ieee80211_start_tx_ba_session()
727 timer_setup(&tid_tx->session_timer, in ieee80211_start_tx_ba_session()
731 sta->ampdu_mlme.dialog_token_allocator++; in ieee80211_start_tx_ba_session()
732 tid_tx->dialog_token = sta->ampdu_mlme.dialog_token_allocator; in ieee80211_start_tx_ba_session()
738 sta->ampdu_mlme.tid_start_tx[tid] = tid_tx; in ieee80211_start_tx_ba_session()
740 wiphy_work_queue(local->hw.wiphy, &sta->ampdu_mlme.work); in ieee80211_start_tx_ba_session()
744 spin_unlock_bh(&sta->lock); in ieee80211_start_tx_ba_session()
749 static void ieee80211_agg_tx_operational(struct ieee80211_local *local, in ieee80211_agg_tx_operational() argument
754 .sta = &sta->sta, in ieee80211_agg_tx_operational()
761 lockdep_assert_wiphy(sta->local->hw.wiphy); in ieee80211_agg_tx_operational()
764 params.buf_size = tid_tx->buf_size; in ieee80211_agg_tx_operational()
765 params.amsdu = tid_tx->amsdu; in ieee80211_agg_tx_operational()
767 ht_dbg(sta->sdata, "Aggregation is on for %pM tid %d\n", in ieee80211_agg_tx_operational()
768 sta->sta.addr, tid); in ieee80211_agg_tx_operational()
770 drv_ampdu_action(local, sta->sdata, ¶ms); in ieee80211_agg_tx_operational()
776 spin_lock_bh(&sta->lock); in ieee80211_agg_tx_operational()
778 ieee80211_agg_splice_packets(sta->sdata, tid_tx, tid); in ieee80211_agg_tx_operational()
781 * in the TX path, and lets it go lock-free in in ieee80211_agg_tx_operational()
784 set_bit(HT_AGG_STATE_OPERATIONAL, &tid_tx->state); in ieee80211_agg_tx_operational()
785 ieee80211_agg_splice_finish(sta->sdata, tid); in ieee80211_agg_tx_operational()
787 spin_unlock_bh(&sta->lock); in ieee80211_agg_tx_operational()
795 struct ieee80211_sub_if_data *sdata = sta->sdata; in ieee80211_start_tx_ba_cb()
796 struct ieee80211_local *local = sdata->local; in ieee80211_start_tx_ba_cb() local
798 lockdep_assert_wiphy(sta->local->hw.wiphy); in ieee80211_start_tx_ba_cb()
800 if (WARN_ON(test_and_set_bit(HT_AGG_STATE_DRV_READY, &tid_tx->state))) in ieee80211_start_tx_ba_cb()
803 if (test_bit(HT_AGG_STATE_STOPPING, &tid_tx->state) || in ieee80211_start_tx_ba_cb()
804 test_bit(HT_AGG_STATE_WANT_STOP, &tid_tx->state)) in ieee80211_start_tx_ba_cb()
807 if (!test_bit(HT_AGG_STATE_SENT_ADDBA, &tid_tx->state)) { in ieee80211_start_tx_ba_cb()
813 if (test_bit(HT_AGG_STATE_RESPONSE_RECEIVED, &tid_tx->state)) in ieee80211_start_tx_ba_cb()
814 ieee80211_agg_tx_operational(local, sta, tid); in ieee80211_start_tx_ba_cb()
835 tid_tx = rcu_dereference((*sta)->ampdu_mlme.tid_tx[tid]); in ieee80211_lookup_tid_tx()
847 struct ieee80211_local *local = sdata->local; in ieee80211_start_tx_ba_cb_irqsafe() local
858 set_bit(HT_AGG_STATE_START_CB, &tid_tx->state); in ieee80211_start_tx_ba_cb_irqsafe()
859 wiphy_work_queue(local->hw.wiphy, &sta->ampdu_mlme.work); in ieee80211_start_tx_ba_cb_irqsafe()
868 struct ieee80211_sub_if_data *sdata = sta->sdata; in ieee80211_stop_tx_ba_session()
869 struct ieee80211_local *local = sdata->local; in ieee80211_stop_tx_ba_session() local
875 if (!local->ops->ampdu_action) in ieee80211_stop_tx_ba_session()
876 return -EINVAL; in ieee80211_stop_tx_ba_session()
879 return -EINVAL; in ieee80211_stop_tx_ba_session()
881 spin_lock_bh(&sta->lock); in ieee80211_stop_tx_ba_session()
885 ret = -ENOENT; in ieee80211_stop_tx_ba_session()
889 WARN(sta->reserved_tid == tid, in ieee80211_stop_tx_ba_session()
890 "Requested to stop BA session on reserved tid=%d", tid); in ieee80211_stop_tx_ba_session()
892 if (test_bit(HT_AGG_STATE_STOPPING, &tid_tx->state)) { in ieee80211_stop_tx_ba_session()
898 set_bit(HT_AGG_STATE_WANT_STOP, &tid_tx->state); in ieee80211_stop_tx_ba_session()
899 wiphy_work_queue(local->hw.wiphy, &sta->ampdu_mlme.work); in ieee80211_stop_tx_ba_session()
902 spin_unlock_bh(&sta->lock); in ieee80211_stop_tx_ba_session()
910 struct ieee80211_sub_if_data *sdata = sta->sdata; in ieee80211_stop_tx_ba_cb()
915 sta->sta.addr, tid); in ieee80211_stop_tx_ba_cb()
917 spin_lock_bh(&sta->lock); in ieee80211_stop_tx_ba_cb()
919 if (!test_bit(HT_AGG_STATE_STOPPING, &tid_tx->state)) { in ieee80211_stop_tx_ba_cb()
921 "unexpected callback to A-MPDU stop for %pM tid %d\n", in ieee80211_stop_tx_ba_cb()
922 sta->sta.addr, tid); in ieee80211_stop_tx_ba_cb()
926 if (tid_tx->stop_initiator == WLAN_BACK_INITIATOR && tid_tx->tx_stop) in ieee80211_stop_tx_ba_cb()
933 spin_unlock_bh(&sta->lock); in ieee80211_stop_tx_ba_cb()
939 ieee80211_send_delba(sdata, sta->sta.addr, tid, in ieee80211_stop_tx_ba_cb()
947 struct ieee80211_local *local = sdata->local; in ieee80211_stop_tx_ba_cb_irqsafe() local
958 set_bit(HT_AGG_STATE_STOP_CB, &tid_tx->state); in ieee80211_stop_tx_ba_cb_irqsafe()
959 wiphy_work_queue(local->hw.wiphy, &sta->ampdu_mlme.work); in ieee80211_stop_tx_ba_cb_irqsafe()
966 void ieee80211_process_addba_resp(struct ieee80211_local *local, in ieee80211_process_addba_resp() argument
976 lockdep_assert_wiphy(sta->local->hw.wiphy); in ieee80211_process_addba_resp()
978 capab = le16_to_cpu(mgmt->u.action.u.addba_resp.capab); in ieee80211_process_addba_resp()
984 mgmt->u.action.u.addba_resp.variable, in ieee80211_process_addba_resp()
985 len - offsetof(typeof(*mgmt), in ieee80211_process_addba_resp()
989 buf_size = min(buf_size, local->hw.max_tx_aggregation_subframes); in ieee80211_process_addba_resp()
991 txq = sta->sta.txq[tid]; in ieee80211_process_addba_resp()
993 set_bit(IEEE80211_TXQ_NO_AMSDU, &to_txq_info(txq)->flags); in ieee80211_process_addba_resp()
999 if (mgmt->u.action.u.addba_resp.dialog_token != tid_tx->dialog_token) { in ieee80211_process_addba_resp()
1000 ht_dbg(sta->sdata, "wrong addBA response token, %pM tid %d\n", in ieee80211_process_addba_resp()
1001 sta->sta.addr, tid); in ieee80211_process_addba_resp()
1005 timer_delete_sync(&tid_tx->addba_resp_timer); in ieee80211_process_addba_resp()
1007 ht_dbg(sta->sdata, "switched off addBA timer for %pM tid %d\n", in ieee80211_process_addba_resp()
1008 sta->sta.addr, tid); in ieee80211_process_addba_resp()
1012 * caused WANT_STOP to be set. If the stop then was already in ieee80211_process_addba_resp()
1015 if (test_bit(HT_AGG_STATE_WANT_STOP, &tid_tx->state) || in ieee80211_process_addba_resp()
1016 test_bit(HT_AGG_STATE_STOPPING, &tid_tx->state)) { in ieee80211_process_addba_resp()
1017 ht_dbg(sta->sdata, in ieee80211_process_addba_resp()
1019 sta->sta.addr, tid); in ieee80211_process_addba_resp()
1024 * IEEE 802.11-2007 7.3.1.14: in ieee80211_process_addba_resp()
1029 if (le16_to_cpu(mgmt->u.action.u.addba_resp.status) in ieee80211_process_addba_resp()
1032 &tid_tx->state)) { in ieee80211_process_addba_resp()
1037 tid_tx->buf_size = buf_size; in ieee80211_process_addba_resp()
1038 tid_tx->amsdu = amsdu; in ieee80211_process_addba_resp()
1040 if (test_bit(HT_AGG_STATE_DRV_READY, &tid_tx->state)) in ieee80211_process_addba_resp()
1041 ieee80211_agg_tx_operational(local, sta, tid); in ieee80211_process_addba_resp()
1043 sta->ampdu_mlme.addba_req_num[tid] = 0; in ieee80211_process_addba_resp()
1045 tid_tx->timeout = in ieee80211_process_addba_resp()
1046 le16_to_cpu(mgmt->u.action.u.addba_resp.timeout); in ieee80211_process_addba_resp()
1048 if (tid_tx->timeout) { in ieee80211_process_addba_resp()
1049 mod_timer(&tid_tx->session_timer, in ieee80211_process_addba_resp()
1050 TU_TO_EXP_TIME(tid_tx->timeout)); in ieee80211_process_addba_resp()
1051 tid_tx->last_tx = jiffies; in ieee80211_process_addba_resp()