linux/net/mac80211/agg-tx.c
<<
>>
Prefs
   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-2010, 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 <linux/slab.h>
  18#include <linux/export.h>
  19#include <net/mac80211.h>
  20#include "ieee80211_i.h"
  21#include "driver-ops.h"
  22#include "wme.h"
  23
  24/**
  25 * DOC: TX A-MPDU aggregation
  26 *
  27 * Aggregation on the TX side requires setting the hardware flag
  28 * %IEEE80211_HW_AMPDU_AGGREGATION. The driver will then be handed
  29 * packets with a flag indicating A-MPDU aggregation. The driver
  30 * or device is responsible for actually aggregating the frames,
  31 * as well as deciding how many and which to aggregate.
  32 *
  33 * When TX aggregation is started by some subsystem (usually the rate
  34 * control algorithm would be appropriate) by calling the
  35 * ieee80211_start_tx_ba_session() function, the driver will be
  36 * notified via its @ampdu_action function, with the
  37 * %IEEE80211_AMPDU_TX_START action.
  38 *
  39 * In response to that, the driver is later required to call the
  40 * ieee80211_start_tx_ba_cb_irqsafe() function, which will really
  41 * start the aggregation session after the peer has also responded.
  42 * If the peer responds negatively, the session will be stopped
  43 * again right away. Note that it is possible for the aggregation
  44 * session to be stopped before the driver has indicated that it
  45 * is done setting it up, in which case it must not indicate the
  46 * setup completion.
  47 *
  48 * Also note that, since we also need to wait for a response from
  49 * the peer, the driver is notified of the completion of the
  50 * handshake by the %IEEE80211_AMPDU_TX_OPERATIONAL action to the
  51 * @ampdu_action callback.
  52 *
  53 * Similarly, when the aggregation session is stopped by the peer
  54 * or something calling ieee80211_stop_tx_ba_session(), the driver's
  55 * @ampdu_action function will be called with the action
  56 * %IEEE80211_AMPDU_TX_STOP. In this case, the call must not fail,
  57 * and the driver must later call ieee80211_stop_tx_ba_cb_irqsafe().
  58 */
  59
  60static void ieee80211_send_addba_request(struct ieee80211_sub_if_data *sdata,
  61                                         const u8 *da, u16 tid,
  62                                         u8 dialog_token, u16 start_seq_num,
  63                                         u16 agg_size, u16 timeout)
  64{
  65        struct ieee80211_local *local = sdata->local;
  66        struct sk_buff *skb;
  67        struct ieee80211_mgmt *mgmt;
  68        u16 capab;
  69
  70        skb = dev_alloc_skb(sizeof(*mgmt) + local->hw.extra_tx_headroom);
  71
  72        if (!skb)
  73                return;
  74
  75        skb_reserve(skb, local->hw.extra_tx_headroom);
  76        mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24);
  77        memset(mgmt, 0, 24);
  78        memcpy(mgmt->da, da, ETH_ALEN);
  79        memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN);
  80        if (sdata->vif.type == NL80211_IFTYPE_AP ||
  81            sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
  82                memcpy(mgmt->bssid, sdata->vif.addr, ETH_ALEN);
  83        else if (sdata->vif.type == NL80211_IFTYPE_STATION)
  84                memcpy(mgmt->bssid, sdata->u.mgd.bssid, ETH_ALEN);
  85
  86        mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
  87                                          IEEE80211_STYPE_ACTION);
  88
  89        skb_put(skb, 1 + sizeof(mgmt->u.action.u.addba_req));
  90
  91        mgmt->u.action.category = WLAN_CATEGORY_BACK;
  92        mgmt->u.action.u.addba_req.action_code = WLAN_ACTION_ADDBA_REQ;
  93
  94        mgmt->u.action.u.addba_req.dialog_token = dialog_token;
  95        capab = (u16)(1 << 1);          /* bit 1 aggregation policy */
  96        capab |= (u16)(tid << 2);       /* bit 5:2 TID number */
  97        capab |= (u16)(agg_size << 6);  /* bit 15:6 max size of aggergation */
  98
  99        mgmt->u.action.u.addba_req.capab = cpu_to_le16(capab);
 100
 101        mgmt->u.action.u.addba_req.timeout = cpu_to_le16(timeout);
 102        mgmt->u.action.u.addba_req.start_seq_num =
 103                                        cpu_to_le16(start_seq_num << 4);
 104
 105        ieee80211_tx_skb(sdata, skb);
 106}
 107
 108void ieee80211_send_bar(struct ieee80211_vif *vif, u8 *ra, u16 tid, u16 ssn)
 109{
 110        struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
 111        struct ieee80211_local *local = sdata->local;
 112        struct sk_buff *skb;
 113        struct ieee80211_bar *bar;
 114        u16 bar_control = 0;
 115
 116        skb = dev_alloc_skb(sizeof(*bar) + local->hw.extra_tx_headroom);
 117        if (!skb)
 118                return;
 119
 120        skb_reserve(skb, local->hw.extra_tx_headroom);
 121        bar = (struct ieee80211_bar *)skb_put(skb, sizeof(*bar));
 122        memset(bar, 0, sizeof(*bar));
 123        bar->frame_control = cpu_to_le16(IEEE80211_FTYPE_CTL |
 124                                         IEEE80211_STYPE_BACK_REQ);
 125        memcpy(bar->ra, ra, ETH_ALEN);
 126        memcpy(bar->ta, sdata->vif.addr, ETH_ALEN);
 127        bar_control |= (u16)IEEE80211_BAR_CTRL_ACK_POLICY_NORMAL;
 128        bar_control |= (u16)IEEE80211_BAR_CTRL_CBMTID_COMPRESSED_BA;
 129        bar_control |= (u16)(tid << IEEE80211_BAR_CTRL_TID_INFO_SHIFT);
 130        bar->control = cpu_to_le16(bar_control);
 131        bar->start_seq_num = cpu_to_le16(ssn);
 132
 133        IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT;
 134        ieee80211_tx_skb(sdata, skb);
 135}
 136EXPORT_SYMBOL(ieee80211_send_bar);
 137
 138void ieee80211_assign_tid_tx(struct sta_info *sta, int tid,
 139                             struct tid_ampdu_tx *tid_tx)
 140{
 141        lockdep_assert_held(&sta->ampdu_mlme.mtx);
 142        lockdep_assert_held(&sta->lock);
 143        rcu_assign_pointer(sta->ampdu_mlme.tid_tx[tid], tid_tx);
 144}
 145
 146int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid,
 147                                    enum ieee80211_back_parties initiator,
 148                                    bool tx)
 149{
 150        struct ieee80211_local *local = sta->local;
 151        struct tid_ampdu_tx *tid_tx;
 152        int ret;
 153
 154        lockdep_assert_held(&sta->ampdu_mlme.mtx);
 155
 156        spin_lock_bh(&sta->lock);
 157
 158        tid_tx = rcu_dereference_protected_tid_tx(sta, tid);
 159        if (!tid_tx) {
 160                spin_unlock_bh(&sta->lock);
 161                return -ENOENT;
 162        }
 163
 164        /* if we're already stopping ignore any new requests to stop */
 165        if (test_bit(HT_AGG_STATE_STOPPING, &tid_tx->state)) {
 166                spin_unlock_bh(&sta->lock);
 167                return -EALREADY;
 168        }
 169
 170        if (test_bit(HT_AGG_STATE_WANT_START, &tid_tx->state)) {
 171                /* not even started yet! */
 172                ieee80211_assign_tid_tx(sta, tid, NULL);
 173                spin_unlock_bh(&sta->lock);
 174                kfree_rcu(tid_tx, rcu_head);
 175                return 0;
 176        }
 177
 178        set_bit(HT_AGG_STATE_STOPPING, &tid_tx->state);
 179
 180        spin_unlock_bh(&sta->lock);
 181
 182#ifdef CONFIG_MAC80211_HT_DEBUG
 183        printk(KERN_DEBUG "Tx BA session stop requested for %pM tid %u\n",
 184               sta->sta.addr, tid);
 185#endif /* CONFIG_MAC80211_HT_DEBUG */
 186
 187        del_timer_sync(&tid_tx->addba_resp_timer);
 188
 189        /*
 190         * After this packets are no longer handed right through
 191         * to the driver but are put onto tid_tx->pending instead,
 192         * with locking to ensure proper access.
 193         */
 194        clear_bit(HT_AGG_STATE_OPERATIONAL, &tid_tx->state);
 195
 196        /*
 197         * There might be a few packets being processed right now (on
 198         * another CPU) that have already gotten past the aggregation
 199         * check when it was still OPERATIONAL and consequently have
 200         * IEEE80211_TX_CTL_AMPDU set. In that case, this code might
 201         * call into the driver at the same time or even before the
 202         * TX paths calls into it, which could confuse the driver.
 203         *
 204         * Wait for all currently running TX paths to finish before
 205         * telling the driver. New packets will not go through since
 206         * the aggregation session is no longer OPERATIONAL.
 207         */
 208        synchronize_net();
 209
 210        tid_tx->stop_initiator = initiator;
 211        tid_tx->tx_stop = tx;
 212
 213        ret = drv_ampdu_action(local, sta->sdata,
 214                               IEEE80211_AMPDU_TX_STOP,
 215                               &sta->sta, tid, NULL, 0);
 216
 217        /* HW shall not deny going back to legacy */
 218        if (WARN_ON(ret)) {
 219                /*
 220                 * We may have pending packets get stuck in this case...
 221                 * Not bothering with a workaround for now.
 222                 */
 223        }
 224
 225        return ret;
 226}
 227
 228/*
 229 * After sending add Block Ack request we activated a timer until
 230 * add Block Ack response will arrive from the recipient.
 231 * If this timer expires sta_addba_resp_timer_expired will be executed.
 232 */
 233static void sta_addba_resp_timer_expired(unsigned long data)
 234{
 235        /* not an elegant detour, but there is no choice as the timer passes
 236         * only one argument, and both sta_info and TID are needed, so init
 237         * flow in sta_info_create gives the TID as data, while the timer_to_id
 238         * array gives the sta through container_of */
 239        u16 tid = *(u8 *)data;
 240        struct sta_info *sta = container_of((void *)data,
 241                struct sta_info, timer_to_tid[tid]);
 242        struct tid_ampdu_tx *tid_tx;
 243
 244        /* check if the TID waits for addBA response */
 245        rcu_read_lock();
 246        tid_tx = rcu_dereference(sta->ampdu_mlme.tid_tx[tid]);
 247        if (!tid_tx ||
 248            test_bit(HT_AGG_STATE_RESPONSE_RECEIVED, &tid_tx->state)) {
 249                rcu_read_unlock();
 250#ifdef CONFIG_MAC80211_HT_DEBUG
 251                printk(KERN_DEBUG "timer expired on tid %d but we are not "
 252                                "(or no longer) expecting addBA response there\n",
 253                        tid);
 254#endif
 255                return;
 256        }
 257
 258#ifdef CONFIG_MAC80211_HT_DEBUG
 259        printk(KERN_DEBUG "addBA response timer expired on tid %d\n", tid);
 260#endif
 261
 262        ieee80211_stop_tx_ba_session(&sta->sta, tid);
 263        rcu_read_unlock();
 264}
 265
 266static inline int ieee80211_ac_from_tid(int tid)
 267{
 268        return ieee802_1d_to_ac[tid & 7];
 269}
 270
 271/*
 272 * When multiple aggregation sessions on multiple stations
 273 * are being created/destroyed simultaneously, we need to
 274 * refcount the global queue stop caused by that in order
 275 * to not get into a situation where one of the aggregation
 276 * setup or teardown re-enables queues before the other is
 277 * ready to handle that.
 278 *
 279 * These two functions take care of this issue by keeping
 280 * a global "agg_queue_stop" refcount.
 281 */
 282static void __acquires(agg_queue)
 283ieee80211_stop_queue_agg(struct ieee80211_local *local, int tid)
 284{
 285        int queue = ieee80211_ac_from_tid(tid);
 286
 287        if (atomic_inc_return(&local->agg_queue_stop[queue]) == 1)
 288                ieee80211_stop_queue_by_reason(
 289                        &local->hw, queue,
 290                        IEEE80211_QUEUE_STOP_REASON_AGGREGATION);
 291        __acquire(agg_queue);
 292}
 293
 294static void __releases(agg_queue)
 295ieee80211_wake_queue_agg(struct ieee80211_local *local, int tid)
 296{
 297        int queue = ieee80211_ac_from_tid(tid);
 298
 299        if (atomic_dec_return(&local->agg_queue_stop[queue]) == 0)
 300                ieee80211_wake_queue_by_reason(
 301                        &local->hw, queue,
 302                        IEEE80211_QUEUE_STOP_REASON_AGGREGATION);
 303        __release(agg_queue);
 304}
 305
 306/*
 307 * splice packets from the STA's pending to the local pending,
 308 * requires a call to ieee80211_agg_splice_finish later
 309 */
 310static void __acquires(agg_queue)
 311ieee80211_agg_splice_packets(struct ieee80211_local *local,
 312                             struct tid_ampdu_tx *tid_tx, u16 tid)
 313{
 314        int queue = ieee80211_ac_from_tid(tid);
 315        unsigned long flags;
 316
 317        ieee80211_stop_queue_agg(local, tid);
 318
 319        if (WARN(!tid_tx, "TID %d gone but expected when splicing aggregates"
 320                          " from the pending queue\n", tid))
 321                return;
 322
 323        if (!skb_queue_empty(&tid_tx->pending)) {
 324                spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
 325                /* copy over remaining packets */
 326                skb_queue_splice_tail_init(&tid_tx->pending,
 327                                           &local->pending[queue]);
 328                spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
 329        }
 330}
 331
 332static void __releases(agg_queue)
 333ieee80211_agg_splice_finish(struct ieee80211_local *local, u16 tid)
 334{
 335        ieee80211_wake_queue_agg(local, tid);
 336}
 337
 338void ieee80211_tx_ba_session_handle_start(struct sta_info *sta, int tid)
 339{
 340        struct tid_ampdu_tx *tid_tx;
 341        struct ieee80211_local *local = sta->local;
 342        struct ieee80211_sub_if_data *sdata = sta->sdata;
 343        u16 start_seq_num;
 344        int ret;
 345
 346        tid_tx = rcu_dereference_protected_tid_tx(sta, tid);
 347
 348        /*
 349         * Start queuing up packets for this aggregation session.
 350         * We're going to release them once the driver is OK with
 351         * that.
 352         */
 353        clear_bit(HT_AGG_STATE_WANT_START, &tid_tx->state);
 354
 355        /*
 356         * Make sure no packets are being processed. This ensures that
 357         * we have a valid starting sequence number and that in-flight
 358         * packets have been flushed out and no packets for this TID
 359         * will go into the driver during the ampdu_action call.
 360         */
 361        synchronize_net();
 362
 363        start_seq_num = sta->tid_seq[tid] >> 4;
 364
 365        ret = drv_ampdu_action(local, sdata, IEEE80211_AMPDU_TX_START,
 366                               &sta->sta, tid, &start_seq_num, 0);
 367        if (ret) {
 368#ifdef CONFIG_MAC80211_HT_DEBUG
 369                printk(KERN_DEBUG "BA request denied - HW unavailable for"
 370                                        " tid %d\n", tid);
 371#endif
 372                spin_lock_bh(&sta->lock);
 373                ieee80211_agg_splice_packets(local, tid_tx, tid);
 374                ieee80211_assign_tid_tx(sta, tid, NULL);
 375                ieee80211_agg_splice_finish(local, tid);
 376                spin_unlock_bh(&sta->lock);
 377
 378                kfree_rcu(tid_tx, rcu_head);
 379                return;
 380        }
 381
 382        /* activate the timer for the recipient's addBA response */
 383        mod_timer(&tid_tx->addba_resp_timer, jiffies + ADDBA_RESP_INTERVAL);
 384#ifdef CONFIG_MAC80211_HT_DEBUG
 385        printk(KERN_DEBUG "activated addBA response timer on tid %d\n", tid);
 386#endif
 387
 388        spin_lock_bh(&sta->lock);
 389        sta->ampdu_mlme.addba_req_num[tid]++;
 390        spin_unlock_bh(&sta->lock);
 391
 392        /* send AddBA request */
 393        ieee80211_send_addba_request(sdata, sta->sta.addr, tid,
 394                                     tid_tx->dialog_token, start_seq_num,
 395                                     local->hw.max_tx_aggregation_subframes,
 396                                     tid_tx->timeout);
 397}
 398
 399int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid,
 400                                  u16 timeout)
 401{
 402        struct sta_info *sta = container_of(pubsta, struct sta_info, sta);
 403        struct ieee80211_sub_if_data *sdata = sta->sdata;
 404        struct ieee80211_local *local = sdata->local;
 405        struct tid_ampdu_tx *tid_tx;
 406        int ret = 0;
 407
 408        trace_api_start_tx_ba_session(pubsta, tid);
 409
 410        if (WARN_ON(!local->ops->ampdu_action))
 411                return -EINVAL;
 412
 413        if ((tid >= STA_TID_NUM) ||
 414            !(local->hw.flags & IEEE80211_HW_AMPDU_AGGREGATION) ||
 415            (local->hw.flags & IEEE80211_HW_TX_AMPDU_SETUP_IN_HW))
 416                return -EINVAL;
 417
 418#ifdef CONFIG_MAC80211_HT_DEBUG
 419        printk(KERN_DEBUG "Open BA session requested for %pM tid %u\n",
 420               pubsta->addr, tid);
 421#endif /* CONFIG_MAC80211_HT_DEBUG */
 422
 423        /*
 424         * The aggregation code is not prepared to handle
 425         * anything but STA/AP due to the BSSID handling.
 426         * IBSS could work in the code but isn't supported
 427         * by drivers or the standard.
 428         */
 429        if (sdata->vif.type != NL80211_IFTYPE_STATION &&
 430            sdata->vif.type != NL80211_IFTYPE_AP_VLAN &&
 431            sdata->vif.type != NL80211_IFTYPE_AP)
 432                return -EINVAL;
 433
 434        if (test_sta_flag(sta, WLAN_STA_BLOCK_BA)) {
 435#ifdef CONFIG_MAC80211_HT_DEBUG
 436                printk(KERN_DEBUG "BA sessions blocked. "
 437                       "Denying BA session request\n");
 438#endif
 439                return -EINVAL;
 440        }
 441
 442        spin_lock_bh(&sta->lock);
 443
 444        /* we have tried too many times, receiver does not want A-MPDU */
 445        if (sta->ampdu_mlme.addba_req_num[tid] > HT_AGG_MAX_RETRIES) {
 446                ret = -EBUSY;
 447                goto err_unlock_sta;
 448        }
 449
 450        tid_tx = rcu_dereference_protected_tid_tx(sta, tid);
 451        /* check if the TID is not in aggregation flow already */
 452        if (tid_tx || sta->ampdu_mlme.tid_start_tx[tid]) {
 453#ifdef CONFIG_MAC80211_HT_DEBUG
 454                printk(KERN_DEBUG "BA request denied - session is not "
 455                                 "idle on tid %u\n", tid);
 456#endif /* CONFIG_MAC80211_HT_DEBUG */
 457                ret = -EAGAIN;
 458                goto err_unlock_sta;
 459        }
 460
 461        /* prepare A-MPDU MLME for Tx aggregation */
 462        tid_tx = kzalloc(sizeof(struct tid_ampdu_tx), GFP_ATOMIC);
 463        if (!tid_tx) {
 464                ret = -ENOMEM;
 465                goto err_unlock_sta;
 466        }
 467
 468        skb_queue_head_init(&tid_tx->pending);
 469        __set_bit(HT_AGG_STATE_WANT_START, &tid_tx->state);
 470
 471        tid_tx->timeout = timeout;
 472
 473        /* Tx timer */
 474        tid_tx->addba_resp_timer.function = sta_addba_resp_timer_expired;
 475        tid_tx->addba_resp_timer.data = (unsigned long)&sta->timer_to_tid[tid];
 476        init_timer(&tid_tx->addba_resp_timer);
 477
 478        /* assign a dialog token */
 479        sta->ampdu_mlme.dialog_token_allocator++;
 480        tid_tx->dialog_token = sta->ampdu_mlme.dialog_token_allocator;
 481
 482        /*
 483         * Finally, assign it to the start array; the work item will
 484         * collect it and move it to the normal array.
 485         */
 486        sta->ampdu_mlme.tid_start_tx[tid] = tid_tx;
 487
 488        ieee80211_queue_work(&local->hw, &sta->ampdu_mlme.work);
 489
 490        /* this flow continues off the work */
 491 err_unlock_sta:
 492        spin_unlock_bh(&sta->lock);
 493        return ret;
 494}
 495EXPORT_SYMBOL(ieee80211_start_tx_ba_session);
 496
 497static void ieee80211_agg_tx_operational(struct ieee80211_local *local,
 498                                         struct sta_info *sta, u16 tid)
 499{
 500        struct tid_ampdu_tx *tid_tx;
 501
 502        lockdep_assert_held(&sta->ampdu_mlme.mtx);
 503
 504        tid_tx = rcu_dereference_protected_tid_tx(sta, tid);
 505
 506#ifdef CONFIG_MAC80211_HT_DEBUG
 507        printk(KERN_DEBUG "Aggregation is on for tid %d\n", tid);
 508#endif
 509
 510        drv_ampdu_action(local, sta->sdata,
 511                         IEEE80211_AMPDU_TX_OPERATIONAL,
 512                         &sta->sta, tid, NULL, tid_tx->buf_size);
 513
 514        /*
 515         * synchronize with TX path, while splicing the TX path
 516         * should block so it won't put more packets onto pending.
 517         */
 518        spin_lock_bh(&sta->lock);
 519
 520        ieee80211_agg_splice_packets(local, tid_tx, tid);
 521        /*
 522         * Now mark as operational. This will be visible
 523         * in the TX path, and lets it go lock-free in
 524         * the common case.
 525         */
 526        set_bit(HT_AGG_STATE_OPERATIONAL, &tid_tx->state);
 527        ieee80211_agg_splice_finish(local, tid);
 528
 529        spin_unlock_bh(&sta->lock);
 530}
 531
 532void ieee80211_start_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u16 tid)
 533{
 534        struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
 535        struct ieee80211_local *local = sdata->local;
 536        struct sta_info *sta;
 537        struct tid_ampdu_tx *tid_tx;
 538
 539        trace_api_start_tx_ba_cb(sdata, ra, tid);
 540
 541        if (tid >= STA_TID_NUM) {
 542#ifdef CONFIG_MAC80211_HT_DEBUG
 543                printk(KERN_DEBUG "Bad TID value: tid = %d (>= %d)\n",
 544                                tid, STA_TID_NUM);
 545#endif
 546                return;
 547        }
 548
 549        mutex_lock(&local->sta_mtx);
 550        sta = sta_info_get(sdata, ra);
 551        if (!sta) {
 552                mutex_unlock(&local->sta_mtx);
 553#ifdef CONFIG_MAC80211_HT_DEBUG
 554                printk(KERN_DEBUG "Could not find station: %pM\n", ra);
 555#endif
 556                return;
 557        }
 558
 559        mutex_lock(&sta->ampdu_mlme.mtx);
 560        tid_tx = rcu_dereference_protected_tid_tx(sta, tid);
 561
 562        if (WARN_ON(!tid_tx)) {
 563#ifdef CONFIG_MAC80211_HT_DEBUG
 564                printk(KERN_DEBUG "addBA was not requested!\n");
 565#endif
 566                goto unlock;
 567        }
 568
 569        if (WARN_ON(test_and_set_bit(HT_AGG_STATE_DRV_READY, &tid_tx->state)))
 570                goto unlock;
 571
 572        if (test_bit(HT_AGG_STATE_RESPONSE_RECEIVED, &tid_tx->state))
 573                ieee80211_agg_tx_operational(local, sta, tid);
 574
 575 unlock:
 576        mutex_unlock(&sta->ampdu_mlme.mtx);
 577        mutex_unlock(&local->sta_mtx);
 578}
 579
 580void ieee80211_start_tx_ba_cb_irqsafe(struct ieee80211_vif *vif,
 581                                      const u8 *ra, u16 tid)
 582{
 583        struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
 584        struct ieee80211_local *local = sdata->local;
 585        struct ieee80211_ra_tid *ra_tid;
 586        struct sk_buff *skb = dev_alloc_skb(0);
 587
 588        if (unlikely(!skb))
 589                return;
 590
 591        ra_tid = (struct ieee80211_ra_tid *) &skb->cb;
 592        memcpy(&ra_tid->ra, ra, ETH_ALEN);
 593        ra_tid->tid = tid;
 594
 595        skb->pkt_type = IEEE80211_SDATA_QUEUE_AGG_START;
 596        skb_queue_tail(&sdata->skb_queue, skb);
 597        ieee80211_queue_work(&local->hw, &sdata->work);
 598}
 599EXPORT_SYMBOL(ieee80211_start_tx_ba_cb_irqsafe);
 600
 601int __ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid,
 602                                   enum ieee80211_back_parties initiator,
 603                                   bool tx)
 604{
 605        int ret;
 606
 607        mutex_lock(&sta->ampdu_mlme.mtx);
 608
 609        ret = ___ieee80211_stop_tx_ba_session(sta, tid, initiator, tx);
 610
 611        mutex_unlock(&sta->ampdu_mlme.mtx);
 612
 613        return ret;
 614}
 615
 616int ieee80211_stop_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid)
 617{
 618        struct sta_info *sta = container_of(pubsta, struct sta_info, sta);
 619        struct ieee80211_sub_if_data *sdata = sta->sdata;
 620        struct ieee80211_local *local = sdata->local;
 621        struct tid_ampdu_tx *tid_tx;
 622        int ret = 0;
 623
 624        trace_api_stop_tx_ba_session(pubsta, tid);
 625
 626        if (!local->ops->ampdu_action)
 627                return -EINVAL;
 628
 629        if (tid >= STA_TID_NUM)
 630                return -EINVAL;
 631
 632        spin_lock_bh(&sta->lock);
 633        tid_tx = rcu_dereference_protected_tid_tx(sta, tid);
 634
 635        if (!tid_tx) {
 636                ret = -ENOENT;
 637                goto unlock;
 638        }
 639
 640        if (test_bit(HT_AGG_STATE_STOPPING, &tid_tx->state)) {
 641                /* already in progress stopping it */
 642                ret = 0;
 643                goto unlock;
 644        }
 645
 646        set_bit(HT_AGG_STATE_WANT_STOP, &tid_tx->state);
 647        ieee80211_queue_work(&local->hw, &sta->ampdu_mlme.work);
 648
 649 unlock:
 650        spin_unlock_bh(&sta->lock);
 651        return ret;
 652}
 653EXPORT_SYMBOL(ieee80211_stop_tx_ba_session);
 654
 655void ieee80211_stop_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u8 tid)
 656{
 657        struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
 658        struct ieee80211_local *local = sdata->local;
 659        struct sta_info *sta;
 660        struct tid_ampdu_tx *tid_tx;
 661
 662        trace_api_stop_tx_ba_cb(sdata, ra, tid);
 663
 664        if (tid >= STA_TID_NUM) {
 665#ifdef CONFIG_MAC80211_HT_DEBUG
 666                printk(KERN_DEBUG "Bad TID value: tid = %d (>= %d)\n",
 667                                tid, STA_TID_NUM);
 668#endif
 669                return;
 670        }
 671
 672#ifdef CONFIG_MAC80211_HT_DEBUG
 673        printk(KERN_DEBUG "Stopping Tx BA session for %pM tid %d\n",
 674               ra, tid);
 675#endif /* CONFIG_MAC80211_HT_DEBUG */
 676
 677        mutex_lock(&local->sta_mtx);
 678
 679        sta = sta_info_get(sdata, ra);
 680        if (!sta) {
 681#ifdef CONFIG_MAC80211_HT_DEBUG
 682                printk(KERN_DEBUG "Could not find station: %pM\n", ra);
 683#endif
 684                goto unlock;
 685        }
 686
 687        mutex_lock(&sta->ampdu_mlme.mtx);
 688        spin_lock_bh(&sta->lock);
 689        tid_tx = rcu_dereference_protected_tid_tx(sta, tid);
 690
 691        if (!tid_tx || !test_bit(HT_AGG_STATE_STOPPING, &tid_tx->state)) {
 692#ifdef CONFIG_MAC80211_HT_DEBUG
 693                printk(KERN_DEBUG "unexpected callback to A-MPDU stop\n");
 694#endif
 695                goto unlock_sta;
 696        }
 697
 698        if (tid_tx->stop_initiator == WLAN_BACK_INITIATOR && tid_tx->tx_stop)
 699                ieee80211_send_delba(sta->sdata, ra, tid,
 700                        WLAN_BACK_INITIATOR, WLAN_REASON_QSTA_NOT_USE);
 701
 702        /*
 703         * When we get here, the TX path will not be lockless any more wrt.
 704         * aggregation, since the OPERATIONAL bit has long been cleared.
 705         * Thus it will block on getting the lock, if it occurs. So if we
 706         * stop the queue now, we will not get any more packets, and any
 707         * that might be being processed will wait for us here, thereby
 708         * guaranteeing that no packets go to the tid_tx pending queue any
 709         * more.
 710         */
 711
 712        ieee80211_agg_splice_packets(local, tid_tx, tid);
 713
 714        /* future packets must not find the tid_tx struct any more */
 715        ieee80211_assign_tid_tx(sta, tid, NULL);
 716
 717        ieee80211_agg_splice_finish(local, tid);
 718
 719        kfree_rcu(tid_tx, rcu_head);
 720
 721 unlock_sta:
 722        spin_unlock_bh(&sta->lock);
 723        mutex_unlock(&sta->ampdu_mlme.mtx);
 724 unlock:
 725        mutex_unlock(&local->sta_mtx);
 726}
 727
 728void ieee80211_stop_tx_ba_cb_irqsafe(struct ieee80211_vif *vif,
 729                                     const u8 *ra, u16 tid)
 730{
 731        struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
 732        struct ieee80211_local *local = sdata->local;
 733        struct ieee80211_ra_tid *ra_tid;
 734        struct sk_buff *skb = dev_alloc_skb(0);
 735
 736        if (unlikely(!skb))
 737                return;
 738
 739        ra_tid = (struct ieee80211_ra_tid *) &skb->cb;
 740        memcpy(&ra_tid->ra, ra, ETH_ALEN);
 741        ra_tid->tid = tid;
 742
 743        skb->pkt_type = IEEE80211_SDATA_QUEUE_AGG_STOP;
 744        skb_queue_tail(&sdata->skb_queue, skb);
 745        ieee80211_queue_work(&local->hw, &sdata->work);
 746}
 747EXPORT_SYMBOL(ieee80211_stop_tx_ba_cb_irqsafe);
 748
 749
 750void ieee80211_process_addba_resp(struct ieee80211_local *local,
 751                                  struct sta_info *sta,
 752                                  struct ieee80211_mgmt *mgmt,
 753                                  size_t len)
 754{
 755        struct tid_ampdu_tx *tid_tx;
 756        u16 capab, tid;
 757        u8 buf_size;
 758
 759        capab = le16_to_cpu(mgmt->u.action.u.addba_resp.capab);
 760        tid = (capab & IEEE80211_ADDBA_PARAM_TID_MASK) >> 2;
 761        buf_size = (capab & IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK) >> 6;
 762
 763        mutex_lock(&sta->ampdu_mlme.mtx);
 764
 765        tid_tx = rcu_dereference_protected_tid_tx(sta, tid);
 766        if (!tid_tx)
 767                goto out;
 768
 769        if (mgmt->u.action.u.addba_resp.dialog_token != tid_tx->dialog_token) {
 770#ifdef CONFIG_MAC80211_HT_DEBUG
 771                printk(KERN_DEBUG "wrong addBA response token, tid %d\n", tid);
 772#endif
 773                goto out;
 774        }
 775
 776        del_timer_sync(&tid_tx->addba_resp_timer);
 777
 778#ifdef CONFIG_MAC80211_HT_DEBUG
 779        printk(KERN_DEBUG "switched off addBA timer for tid %d\n", tid);
 780#endif
 781
 782        /*
 783         * addba_resp_timer may have fired before we got here, and
 784         * caused WANT_STOP to be set. If the stop then was already
 785         * processed further, STOPPING might be set.
 786         */
 787        if (test_bit(HT_AGG_STATE_WANT_STOP, &tid_tx->state) ||
 788            test_bit(HT_AGG_STATE_STOPPING, &tid_tx->state)) {
 789#ifdef CONFIG_MAC80211_HT_DEBUG
 790                printk(KERN_DEBUG
 791                       "got addBA resp for tid %d but we already gave up\n",
 792                       tid);
 793#endif
 794                goto out;
 795        }
 796
 797        /*
 798         * IEEE 802.11-2007 7.3.1.14:
 799         * In an ADDBA Response frame, when the Status Code field
 800         * is set to 0, the Buffer Size subfield is set to a value
 801         * of at least 1.
 802         */
 803        if (le16_to_cpu(mgmt->u.action.u.addba_resp.status)
 804                        == WLAN_STATUS_SUCCESS && buf_size) {
 805                if (test_and_set_bit(HT_AGG_STATE_RESPONSE_RECEIVED,
 806                                     &tid_tx->state)) {
 807                        /* ignore duplicate response */
 808                        goto out;
 809                }
 810
 811                tid_tx->buf_size = buf_size;
 812
 813                if (test_bit(HT_AGG_STATE_DRV_READY, &tid_tx->state))
 814                        ieee80211_agg_tx_operational(local, sta, tid);
 815
 816                sta->ampdu_mlme.addba_req_num[tid] = 0;
 817        } else {
 818                ___ieee80211_stop_tx_ba_session(sta, tid, WLAN_BACK_INITIATOR,
 819                                                true);
 820        }
 821
 822 out:
 823        mutex_unlock(&sta->ampdu_mlme.mtx);
 824}
 825
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.