1 /* 2 * HT handling 3 * 4 * Copyright 2003, Jouni Malinen <jkmaline@cc.hut.fi> 5 * Copyright 2002-2005, Instant802 Networks, Inc. 6 * Copyright 2005-2006, Devicescape Software, Inc. 7 * Copyright 2006-2007 Jiri Benc <jbenc@suse.cz> 8 * Copyright 2007, Michael Wu <flamingice@sourmilk.net> 9 * Copyright 2007-2009, Intel Corporation 10 * 11 * This program is free software; you can redistribute it and/or modify 12 * it under the terms of the GNU General Public License version 2 as 13 * published by the Free Software Foundation. 14 */ 15 16 #include <linux/ieee80211.h> 17 #include <net/mac80211.h> 18 #include "ieee80211_i.h" 19 #include "wme.h" 20 21 static void ieee80211_send_addba_request(struct ieee80211_sub_if_data *sdata, 22 const u8 *da, u16 tid, 23 u8 dialog_token, u16 start_seq_num, 24 u16 agg_size, u16 timeout) 25 { 26 struct ieee80211_local *local = sdata->local; 27 struct ieee80211_if_sta *ifsta = &sdata->u.sta; 28 struct sk_buff *skb; 29 struct ieee80211_mgmt *mgmt; 30 u16 capab; 31 32 skb = dev_alloc_skb(sizeof(*mgmt) + local->hw.extra_tx_headroom); 33 34 if (!skb) { 35 printk(KERN_ERR "%s: failed to allocate buffer " 36 "for addba request frame\n", sdata->dev->name); 37 return; 38 } 39 skb_reserve(skb, local->hw.extra_tx_headroom); 40 mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24); 41 memset(mgmt, 0, 24); 42 memcpy(mgmt->da, da, ETH_ALEN); 43 memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN); 44 if (sdata->vif.type == NL80211_IFTYPE_AP || 45 sdata->vif.type == NL80211_IFTYPE_AP_VLAN) 46 memcpy(mgmt->bssid, sdata->dev->dev_addr, ETH_ALEN); 47 else 48 memcpy(mgmt->bssid, ifsta->bssid, ETH_ALEN); 49 50 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | 51 IEEE80211_STYPE_ACTION); 52 53 skb_put(skb, 1 + sizeof(mgmt->u.action.u.addba_req)); 54 55 mgmt->u.action.category = WLAN_CATEGORY_BACK; 56 mgmt->u.action.u.addba_req.action_code = WLAN_ACTION_ADDBA_REQ; 57 58 mgmt->u.action.u.addba_req.dialog_token = dialog_token; 59 capab = (u16)(1 << 1); /* bit 1 aggregation policy */ 60 capab |= (u16)(tid << 2); /* bit 5:2 TID number */ 61 capab |= (u16)(agg_size << 6); /* bit 15:6 max size of aggergation */ 62 63 mgmt->u.action.u.addba_req.capab = cpu_to_le16(capab); 64 65 mgmt->u.action.u.addba_req.timeout = cpu_to_le16(timeout); 66 mgmt->u.action.u.addba_req.start_seq_num = 67 cpu_to_le16(start_seq_num << 4); 68 69 ieee80211_tx_skb(sdata, skb, 1); 70 } 71 72 void ieee80211_send_bar(struct ieee80211_sub_if_data *sdata, u8 *ra, u16 tid, u16 ssn) 73 { 74 struct ieee80211_local *local = sdata->local; 75 struct sk_buff *skb; 76 struct ieee80211_bar *bar; 77 u16 bar_control = 0; 78 79 skb = dev_alloc_skb(sizeof(*bar) + local->hw.extra_tx_headroom); 80 if (!skb) { 81 printk(KERN_ERR "%s: failed to allocate buffer for " 82 "bar frame\n", sdata->dev->name); 83 return; 84 } 85 skb_reserve(skb, local->hw.extra_tx_headroom); 86 bar = (struct ieee80211_bar *)skb_put(skb, sizeof(*bar)); 87 memset(bar, 0, sizeof(*bar)); 88 bar->frame_control = cpu_to_le16(IEEE80211_FTYPE_CTL | 89 IEEE80211_STYPE_BACK_REQ); 90 memcpy(bar->ra, ra, ETH_ALEN); 91 memcpy(bar->ta, sdata->dev->dev_addr, ETH_ALEN); 92 bar_control |= (u16)IEEE80211_BAR_CTRL_ACK_POLICY_NORMAL; 93 bar_control |= (u16)IEEE80211_BAR_CTRL_CBMTID_COMPRESSED_BA; 94 bar_control |= (u16)(tid << 12); 95 bar->control = cpu_to_le16(bar_control); 96 bar->start_seq_num = cpu_to_le16(ssn); 97 98 ieee80211_tx_skb(sdata, skb, 0); 99 } 100 101 /* 102 * After sending add Block Ack request we activated a timer until 103 * add Block Ack response will arrive from the recipient. 104 * If this timer expires sta_addba_resp_timer_expired will be executed. 105 */ 106 static void sta_addba_resp_timer_expired(unsigned long data) 107 { 108 /* not an elegant detour, but there is no choice as the timer passes 109 * only one argument, and both sta_info and TID are needed, so init 110 * flow in sta_info_create gives the TID as data, while the timer_to_id 111 * array gives the sta through container_of */ 112 u16 tid = *(u8 *)data; 113 struct sta_info *temp_sta = container_of((void *)data, 114 struct sta_info, timer_to_tid[tid]); 115 116 struct ieee80211_local *local = temp_sta->local; 117 struct ieee80211_hw *hw = &local->hw; 118 struct sta_info *sta; 119 u8 *state; 120 121 rcu_read_lock(); 122 123 sta = sta_info_get(local, temp_sta->sta.addr); 124 if (!sta) { 125 rcu_read_unlock(); 126 return; 127 } 128 129 state = &sta->ampdu_mlme.tid_state_tx[tid]; 130 /* check if the TID waits for addBA response */ 131 spin_lock_bh(&sta->lock); 132 if (!(*state & HT_ADDBA_REQUESTED_MSK)) { 133 spin_unlock_bh(&sta->lock); 134 *state = HT_AGG_STATE_IDLE; 135 #ifdef CONFIG_MAC80211_HT_DEBUG 136 printk(KERN_DEBUG "timer expired on tid %d but we are not " 137 "expecting addBA response there", tid); 138 #endif 139 goto timer_expired_exit; 140 } 141 142 #ifdef CONFIG_MAC80211_HT_DEBUG 143 printk(KERN_DEBUG "addBA response timer expired on tid %d\n", tid); 144 #endif 145 146 /* go through the state check in stop_BA_session */ 147 *state = HT_AGG_STATE_OPERATIONAL; 148 spin_unlock_bh(&sta->lock); 149 ieee80211_stop_tx_ba_session(hw, temp_sta->sta.addr, tid, 150 WLAN_BACK_INITIATOR); 151 152 timer_expired_exit: 153 rcu_read_unlock(); 154 } 155 156 int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid) 157 { 158 struct ieee80211_local *local = hw_to_local(hw); 159 struct sta_info *sta; 160 struct ieee80211_sub_if_data *sdata; 161 u16 start_seq_num; 162 u8 *state; 163 int ret = 0; 164 165 if ((tid >= STA_TID_NUM) || !(hw->flags & IEEE80211_HW_AMPDU_AGGREGATION)) 166 return -EINVAL; 167 168 #ifdef CONFIG_MAC80211_HT_DEBUG 169 printk(KERN_DEBUG "Open BA session requested for %pM tid %u\n", 170 ra, tid); 171 #endif /* CONFIG_MAC80211_HT_DEBUG */ 172 173 rcu_read_lock(); 174 175 sta = sta_info_get(local, ra); 176 if (!sta) { 177 #ifdef CONFIG_MAC80211_HT_DEBUG 178 printk(KERN_DEBUG "Could not find the station\n"); 179 #endif 180 ret = -ENOENT; 181 goto exit; 182 } 183 184 /* 185 * The aggregation code is not prepared to handle 186 * anything but STA/AP due to the BSSID handling. 187 * IBSS could work in the code but isn't supported 188 * by drivers or the standard. 189 */ 190 if (sta->sdata->vif.type != NL80211_IFTYPE_STATION && 191 sta->sdata->vif.type != NL80211_IFTYPE_AP_VLAN && 192 sta->sdata->vif.type != NL80211_IFTYPE_AP) { 193 ret = -EINVAL; 194 goto exit; 195 } 196 197 spin_lock_bh(&sta->lock); 198 199 /* we have tried too many times, receiver does not want A-MPDU */ 200 if (sta->ampdu_mlme.addba_req_num[tid] > HT_AGG_MAX_RETRIES) { 201 ret = -EBUSY; 202 goto err_unlock_sta; 203 } 204 205 state = &sta->ampdu_mlme.tid_state_tx[tid]; 206 /* check if the TID is not in aggregation flow already */ 207 if (*state != HT_AGG_STATE_IDLE) { 208 #ifdef CONFIG_MAC80211_HT_DEBUG 209 printk(KERN_DEBUG "BA request denied - session is not " 210 "idle on tid %u\n", tid); 211 #endif /* CONFIG_MAC80211_HT_DEBUG */ 212 ret = -EAGAIN; 213 goto err_unlock_sta; 214 } 215 216 /* prepare A-MPDU MLME for Tx aggregation */ 217 sta->ampdu_mlme.tid_tx[tid] = 218 kmalloc(sizeof(struct tid_ampdu_tx), GFP_ATOMIC); 219 if (!sta->ampdu_mlme.tid_tx[tid]) { 220 #ifdef CONFIG_MAC80211_HT_DEBUG 221 if (net_ratelimit()) 222 printk(KERN_ERR "allocate tx mlme to tid %d failed\n", 223 tid); 224 #endif 225 ret = -ENOMEM; 226 goto err_unlock_sta; 227 } 228 /* Tx timer */ 229 sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer.function = 230 sta_addba_resp_timer_expired; 231 sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer.data = 232 (unsigned long)&sta->timer_to_tid[tid]; 233 init_timer(&sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer); 234 235 if (hw->ampdu_queues) { 236 /* create a new queue for this aggregation */ 237 ret = ieee80211_ht_agg_queue_add(local, sta, tid); 238 239 /* case no queue is available to aggregation 240 * don't switch to aggregation */ 241 if (ret) { 242 #ifdef CONFIG_MAC80211_HT_DEBUG 243 printk(KERN_DEBUG "BA request denied - " 244 "queue unavailable for tid %d\n", tid); 245 #endif /* CONFIG_MAC80211_HT_DEBUG */ 246 goto err_unlock_queue; 247 } 248 } 249 sdata = sta->sdata; 250 251 /* Ok, the Addba frame hasn't been sent yet, but if the driver calls the 252 * call back right away, it must see that the flow has begun */ 253 *state |= HT_ADDBA_REQUESTED_MSK; 254 255 /* This is slightly racy because the queue isn't stopped */ 256 start_seq_num = sta->tid_seq[tid]; 257 258 if (local->ops->ampdu_action) 259 ret = local->ops->ampdu_action(hw, IEEE80211_AMPDU_TX_START, 260 &sta->sta, tid, &start_seq_num); 261 262 if (ret) { 263 /* No need to requeue the packets in the agg queue, since we 264 * held the tx lock: no packet could be enqueued to the newly 265 * allocated queue */ 266 if (hw->ampdu_queues) 267 ieee80211_ht_agg_queue_remove(local, sta, tid, 0); 268 #ifdef CONFIG_MAC80211_HT_DEBUG 269 printk(KERN_DEBUG "BA request denied - HW unavailable for" 270 " tid %d\n", tid); 271 #endif /* CONFIG_MAC80211_HT_DEBUG */ 272 *state = HT_AGG_STATE_IDLE; 273 goto err_unlock_queue; 274 } 275 276 /* Will put all the packets in the new SW queue */ 277 if (hw->ampdu_queues) 278 ieee80211_requeue(local, ieee802_1d_to_ac[tid]); 279 spin_unlock_bh(&sta->lock); 280 281 /* send an addBA request */ 282 sta->ampdu_mlme.dialog_token_allocator++; 283 sta->ampdu_mlme.tid_tx[tid]->dialog_token = 284 sta->ampdu_mlme.dialog_token_allocator; 285 sta->ampdu_mlme.tid_tx[tid]->ssn = start_seq_num; 286 287 288 ieee80211_send_addba_request(sta->sdata, ra, tid, 289 sta->ampdu_mlme.tid_tx[tid]->dialog_token, 290 sta->ampdu_mlme.tid_tx[tid]->ssn, 291 0x40, 5000); 292 /* activate the timer for the recipient's addBA response */ 293 sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer.expires = 294 jiffies + ADDBA_RESP_INTERVAL; 295 add_timer(&sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer); 296 #ifdef CONFIG_MAC80211_HT_DEBUG 297 printk(KERN_DEBUG "activated addBA response timer on tid %d\n", tid); 298 #endif 299 goto exit; 300 301 err_unlock_queue: 302 kfree(sta->ampdu_mlme.tid_tx[tid]); 303 sta->ampdu_mlme.tid_tx[tid] = NULL; 304 ret = -EBUSY; 305 err_unlock_sta: 306 spin_unlock_bh(&sta->lock); 307 exit: 308 rcu_read_unlock(); 309 return ret; 310 } 311 EXPORT_SYMBOL(ieee80211_start_tx_ba_session); 312 313 void ieee80211_start_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u16 tid) 314 { 315 struct ieee80211_local *local = hw_to_local(hw); 316 struct sta_info *sta; 317 u8 *state; 318 319 if (tid >= STA_TID_NUM) { 320 #ifdef CONFIG_MAC80211_HT_DEBUG 321 printk(KERN_DEBUG "Bad TID value: tid = %d (>= %d)\n", 322 tid, STA_TID_NUM); 323 #endif 324 return; 325 } 326 327 rcu_read_lock(); 328 sta = sta_info_get(local, ra); 329 if (!sta) { 330 rcu_read_unlock(); 331 #ifdef CONFIG_MAC80211_HT_DEBUG 332 printk(KERN_DEBUG "Could not find station: %pM\n", ra); 333 #endif 334 return; 335 } 336 337 state = &sta->ampdu_mlme.tid_state_tx[tid]; 338 spin_lock_bh(&sta->lock); 339 340 if (!(*state & HT_ADDBA_REQUESTED_MSK)) { 341 #ifdef CONFIG_MAC80211_HT_DEBUG 342 printk(KERN_DEBUG "addBA was not requested yet, state is %d\n", 343 *state); 344 #endif 345 spin_unlock_bh(&sta->lock); 346 rcu_read_unlock(); 347 return; 348 } 349 350 WARN_ON_ONCE(*state & HT_ADDBA_DRV_READY_MSK); 351 352 *state |= HT_ADDBA_DRV_READY_MSK; 353 354 if (*state == HT_AGG_STATE_OPERATIONAL) { 355 #ifdef CONFIG_MAC80211_HT_DEBUG 356 printk(KERN_DEBUG "Aggregation is on for tid %d \n", tid); 357 #endif 358 if (hw->ampdu_queues) 359 ieee80211_wake_queue(hw, sta->tid_to_tx_q[tid]); 360 } 361 spin_unlock_bh(&sta->lock); 362 rcu_read_unlock(); 363 } 364 EXPORT_SYMBOL(ieee80211_start_tx_ba_cb); 365 366 367 int ieee80211_stop_tx_ba_session(struct ieee80211_hw *hw, 368 u8 *ra, u16 tid, 369 enum ieee80211_back_parties initiator) 370 { 371 struct ieee80211_local *local = hw_to_local(hw); 372 struct sta_info *sta; 373 u8 *state; 374 int ret = 0; 375 376 if (tid >= STA_TID_NUM) 377 return -EINVAL; 378 379 rcu_read_lock(); 380 sta = sta_info_get(local, ra); 381 if (!sta) { 382 rcu_read_unlock(); 383 return -ENOENT; 384 } 385 386 /* check if the TID is in aggregation */ 387 state = &sta->ampdu_mlme.tid_state_tx[tid]; 388 spin_lock_bh(&sta->lock); 389 390 if (*state != HT_AGG_STATE_OPERATIONAL) { 391 ret = -ENOENT; 392 goto stop_BA_exit; 393 } 394 395 #ifdef CONFIG_MAC80211_HT_DEBUG 396 printk(KERN_DEBUG "Tx BA session stop requested for %pM tid %u\n", 397 ra, tid); 398 #endif /* CONFIG_MAC80211_HT_DEBUG */ 399 400 if (hw->ampdu_queues) 401 ieee80211_stop_queue(hw, sta->tid_to_tx_q[tid]); 402 403 *state = HT_AGG_STATE_REQ_STOP_BA_MSK | 404 (initiator << HT_AGG_STATE_INITIATOR_SHIFT); 405 406 if (local->ops->ampdu_action) 407 ret = local->ops->ampdu_action(hw, IEEE80211_AMPDU_TX_STOP, 408 &sta->sta, tid, NULL); 409 410 /* case HW denied going back to legacy */ 411 if (ret) { 412 WARN_ON(ret != -EBUSY); 413 *state = HT_AGG_STATE_OPERATIONAL; 414 if (hw->ampdu_queues) 415 ieee80211_wake_queue(hw, sta->tid_to_tx_q[tid]); 416 goto stop_BA_exit; 417 } 418 419 stop_BA_exit: 420 spin_unlock_bh(&sta->lock); 421 rcu_read_unlock(); 422 return ret; 423 } 424 EXPORT_SYMBOL(ieee80211_stop_tx_ba_session); 425 426 void ieee80211_stop_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u8 tid) 427 { 428 struct ieee80211_local *local = hw_to_local(hw); 429 struct sta_info *sta; 430 u8 *state; 431 int agg_queue; 432 433 if (tid >= STA_TID_NUM) { 434 #ifdef CONFIG_MAC80211_HT_DEBUG 435 printk(KERN_DEBUG "Bad TID value: tid = %d (>= %d)\n", 436 tid, STA_TID_NUM); 437 #endif 438 return; 439 } 440 441 #ifdef CONFIG_MAC80211_HT_DEBUG 442 printk(KERN_DEBUG "Stopping Tx BA session for %pM tid %d\n", 443 ra, tid); 444 #endif /* CONFIG_MAC80211_HT_DEBUG */ 445 446 rcu_read_lock(); 447 sta = sta_info_get(local, ra); 448 if (!sta) { 449 #ifdef CONFIG_MAC80211_HT_DEBUG 450 printk(KERN_DEBUG "Could not find station: %pM\n", ra); 451 #endif 452 rcu_read_unlock(); 453 return; 454 } 455 state = &sta->ampdu_mlme.tid_state_tx[tid]; 456 457 /* NOTE: no need to use sta->lock in this state check, as 458 * ieee80211_stop_tx_ba_session will let only one stop call to 459 * pass through per sta/tid 460 */ 461 if ((*state & HT_AGG_STATE_REQ_STOP_BA_MSK) == 0) { 462 #ifdef CONFIG_MAC80211_HT_DEBUG 463 printk(KERN_DEBUG "unexpected callback to A-MPDU stop\n"); 464 #endif 465 rcu_read_unlock(); 466 return; 467 } 468 469 if (*state & HT_AGG_STATE_INITIATOR_MSK) 470 ieee80211_send_delba(sta->sdata, ra, tid, 471 WLAN_BACK_INITIATOR, WLAN_REASON_QSTA_NOT_USE); 472 473 if (hw->ampdu_queues) { 474 agg_queue = sta->tid_to_tx_q[tid]; 475 ieee80211_ht_agg_queue_remove(local, sta, tid, 1); 476 477 /* We just requeued the all the frames that were in the 478 * removed queue, and since we might miss a softirq we do 479 * netif_schedule_queue. ieee80211_wake_queue is not used 480 * here as this queue is not necessarily stopped 481 */ 482 netif_schedule_queue(netdev_get_tx_queue(local->mdev, 483 agg_queue)); 484 } 485 spin_lock_bh(&sta->lock); 486 *state = HT_AGG_STATE_IDLE; 487 sta->ampdu_mlme.addba_req_num[tid] = 0; 488 kfree(sta->ampdu_mlme.tid_tx[tid]); 489 sta->ampdu_mlme.tid_tx[tid] = NULL; 490 spin_unlock_bh(&sta->lock); 491 492 rcu_read_unlock(); 493 } 494 EXPORT_SYMBOL(ieee80211_stop_tx_ba_cb); 495 496 void ieee80211_start_tx_ba_cb_irqsafe(struct ieee80211_hw *hw, 497 const u8 *ra, u16 tid) 498 { 499 struct ieee80211_local *local = hw_to_local(hw); 500 struct ieee80211_ra_tid *ra_tid; 501 struct sk_buff *skb = dev_alloc_skb(0); 502 503 if (unlikely(!skb)) { 504 #ifdef CONFIG_MAC80211_HT_DEBUG 505 if (net_ratelimit()) 506 printk(KERN_WARNING "%s: Not enough memory, " 507 "dropping start BA session", skb->dev->name); 508 #endif 509 return; 510 } 511 ra_tid = (struct ieee80211_ra_tid *) &skb->cb; 512 memcpy(&ra_tid->ra, ra, ETH_ALEN); 513 ra_tid->tid = tid; 514 515 skb->pkt_type = IEEE80211_ADDBA_MSG; 516 skb_queue_tail(&local->skb_queue, skb); 517 tasklet_schedule(&local->tasklet); 518 } 519 EXPORT_SYMBOL(ieee80211_start_tx_ba_cb_irqsafe); 520 521 void ieee80211_stop_tx_ba_cb_irqsafe(struct ieee80211_hw *hw, 522 const u8 *ra, u16 tid) 523 { 524 struct ieee80211_local *local = hw_to_local(hw); 525 struct ieee80211_ra_tid *ra_tid; 526 struct sk_buff *skb = dev_alloc_skb(0); 527 528 if (unlikely(!skb)) { 529 #ifdef CONFIG_MAC80211_HT_DEBUG 530 if (net_ratelimit()) 531 printk(KERN_WARNING "%s: Not enough memory, " 532 "dropping stop BA session", skb->dev->name); 533 #endif 534 return; 535 } 536 ra_tid = (struct ieee80211_ra_tid *) &skb->cb; 537 memcpy(&ra_tid->ra, ra, ETH_ALEN); 538 ra_tid->tid = tid; 539 540 skb->pkt_type = IEEE80211_DELBA_MSG; 541 skb_queue_tail(&local->skb_queue, skb); 542 tasklet_schedule(&local->tasklet); 543 } 544 EXPORT_SYMBOL(ieee80211_stop_tx_ba_cb_irqsafe); 545 546 void ieee80211_process_addba_resp(struct ieee80211_local *local, 547 struct sta_info *sta, 548 struct ieee80211_mgmt *mgmt, 549 size_t len) 550 { 551 struct ieee80211_hw *hw = &local->hw; 552 u16 capab; 553 u16 tid, start_seq_num; 554 u8 *state; 555 556 capab = le16_to_cpu(mgmt->u.action.u.addba_resp.capab); 557 tid = (capab & IEEE80211_ADDBA_PARAM_TID_MASK) >> 2; 558 559 state = &sta->ampdu_mlme.tid_state_tx[tid]; 560 561 spin_lock_bh(&sta->lock); 562 563 if (!(*state & HT_ADDBA_REQUESTED_MSK)) { 564 spin_unlock_bh(&sta->lock); 565 return; 566 } 567 568 if (mgmt->u.action.u.addba_resp.dialog_token != 569 sta->ampdu_mlme.tid_tx[tid]->dialog_token) { 570 spin_unlock_bh(&sta->lock); 571 #ifdef CONFIG_MAC80211_HT_DEBUG 572 printk(KERN_DEBUG "wrong addBA response token, tid %d\n", tid); 573 #endif /* CONFIG_MAC80211_HT_DEBUG */ 574 return; 575 } 576 577 del_timer_sync(&sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer); 578 #ifdef CONFIG_MAC80211_HT_DEBUG 579 printk(KERN_DEBUG "switched off addBA timer for tid %d \n", tid); 580 #endif /* CONFIG_MAC80211_HT_DEBUG */ 581 if (le16_to_cpu(mgmt->u.action.u.addba_resp.status) 582 == WLAN_STATUS_SUCCESS) { 583 *state |= HT_ADDBA_RECEIVED_MSK; 584 sta->ampdu_mlme.addba_req_num[tid] = 0; 585 586 if (*state == HT_AGG_STATE_OPERATIONAL && 587 local->hw.ampdu_queues) 588 ieee80211_wake_queue(hw, sta->tid_to_tx_q[tid]); 589 590 if (local->ops->ampdu_action) { 591 (void)local->ops->ampdu_action(hw, 592 IEEE80211_AMPDU_TX_RESUME, 593 &sta->sta, tid, &start_seq_num); 594 } 595 #ifdef CONFIG_MAC80211_HT_DEBUG 596 printk(KERN_DEBUG "Resuming TX aggregation for tid %d\n", tid); 597 #endif /* CONFIG_MAC80211_HT_DEBUG */ 598 spin_unlock_bh(&sta->lock); 599 } else { 600 sta->ampdu_mlme.addba_req_num[tid]++; 601 /* this will allow the state check in stop_BA_session */ 602 *state = HT_AGG_STATE_OPERATIONAL; 603 spin_unlock_bh(&sta->lock); 604 ieee80211_stop_tx_ba_session(hw, sta->sta.addr, tid, 605 WLAN_BACK_INITIATOR); 606 } 607 } 608