aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2008-03-27 21:01:13 -0400
committerDavid S. Miller <davem@davemloft.net>2008-03-27 21:01:13 -0400
commited85f2c3b2b72bd20f617ac749f5c22be8d0f66e (patch)
treecb077293e1b36a5d6e2a138deb9663078a2d850e /net/mac80211
parentbc09dff198e67a98a82c42000006b39f6d502031 (diff)
parente5225b397308f9eea86327293b73dc88068e0179 (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-2.6.26
Diffstat (limited to 'net/mac80211')
-rw-r--r--net/mac80211/debugfs_sta.c19
-rw-r--r--net/mac80211/ieee80211.c64
-rw-r--r--net/mac80211/ieee80211_i.h50
-rw-r--r--net/mac80211/ieee80211_ioctl.c3
-rw-r--r--net/mac80211/ieee80211_sta.c84
-rw-r--r--net/mac80211/rx.c10
-rw-r--r--net/mac80211/sta_info.c30
-rw-r--r--net/mac80211/sta_info.h49
8 files changed, 182 insertions, 127 deletions
diff --git a/net/mac80211/debugfs_sta.c b/net/mac80211/debugfs_sta.c
index fc2c1a192ed2..256ea880d28b 100644
--- a/net/mac80211/debugfs_sta.c
+++ b/net/mac80211/debugfs_sta.c
@@ -169,27 +169,30 @@ static ssize_t sta_agg_status_read(struct file *file, char __user *userbuf,
169 p += scnprintf(p, sizeof(buf)+buf-p, "\n RX :"); 169 p += scnprintf(p, sizeof(buf)+buf-p, "\n RX :");
170 for (i = 0; i < STA_TID_NUM; i++) 170 for (i = 0; i < STA_TID_NUM; i++)
171 p += scnprintf(p, sizeof(buf)+buf-p, "%5d", 171 p += scnprintf(p, sizeof(buf)+buf-p, "%5d",
172 sta->ampdu_mlme.tid_rx[i].state); 172 sta->ampdu_mlme.tid_state_rx[i]);
173 173
174 p += scnprintf(p, sizeof(buf)+buf-p, "\n DTKN:"); 174 p += scnprintf(p, sizeof(buf)+buf-p, "\n DTKN:");
175 for (i = 0; i < STA_TID_NUM; i++) 175 for (i = 0; i < STA_TID_NUM; i++)
176 p += scnprintf(p, sizeof(buf)+buf-p, "%5d", 176 p += scnprintf(p, sizeof(buf)+buf-p, "%5d",
177 sta->ampdu_mlme.tid_rx[i].dialog_token); 177 sta->ampdu_mlme.tid_state_rx[i]?
178 sta->ampdu_mlme.tid_rx[i]->dialog_token : 0);
178 179
179 p += scnprintf(p, sizeof(buf)+buf-p, "\n TX :"); 180 p += scnprintf(p, sizeof(buf)+buf-p, "\n TX :");
180 for (i = 0; i < STA_TID_NUM; i++) 181 for (i = 0; i < STA_TID_NUM; i++)
181 p += scnprintf(p, sizeof(buf)+buf-p, "%5d", 182 p += scnprintf(p, sizeof(buf)+buf-p, "%5d",
182 sta->ampdu_mlme.tid_tx[i].state); 183 sta->ampdu_mlme.tid_state_tx[i]);
183 184
184 p += scnprintf(p, sizeof(buf)+buf-p, "\n DTKN:"); 185 p += scnprintf(p, sizeof(buf)+buf-p, "\n DTKN:");
185 for (i = 0; i < STA_TID_NUM; i++) 186 for (i = 0; i < STA_TID_NUM; i++)
186 p += scnprintf(p, sizeof(buf)+buf-p, "%5d", 187 p += scnprintf(p, sizeof(buf)+buf-p, "%5d",
187 sta->ampdu_mlme.tid_tx[i].dialog_token); 188 sta->ampdu_mlme.tid_state_tx[i]?
189 sta->ampdu_mlme.tid_tx[i]->dialog_token : 0);
188 190
189 p += scnprintf(p, sizeof(buf)+buf-p, "\n SSN :"); 191 p += scnprintf(p, sizeof(buf)+buf-p, "\n SSN :");
190 for (i = 0; i < STA_TID_NUM; i++) 192 for (i = 0; i < STA_TID_NUM; i++)
191 p += scnprintf(p, sizeof(buf)+buf-p, "%5d", 193 p += scnprintf(p, sizeof(buf)+buf-p, "%5d",
192 sta->ampdu_mlme.tid_tx[i].ssn); 194 sta->ampdu_mlme.tid_state_tx[i]?
195 sta->ampdu_mlme.tid_tx[i]->ssn : 0);
193 196
194 p += scnprintf(p, sizeof(buf)+buf-p, "\n"); 197 p += scnprintf(p, sizeof(buf)+buf-p, "\n");
195 198
@@ -230,11 +233,13 @@ static ssize_t sta_agg_status_write(struct file *file,
230 strcpy(state, "off "); 233 strcpy(state, "off ");
231 ieee80211_sta_stop_rx_ba_session(dev, da, tid_num, 0, 234 ieee80211_sta_stop_rx_ba_session(dev, da, tid_num, 0,
232 WLAN_REASON_QSTA_REQUIRE_SETUP); 235 WLAN_REASON_QSTA_REQUIRE_SETUP);
233 sta->ampdu_mlme.tid_rx[tid_num].buf_size = 0xFF; 236 sta->ampdu_mlme.tid_state_rx[tid_num] |=
237 HT_AGG_STATE_DEBUGFS_CTL;
234 tid_static_rx[tid_num] = 0; 238 tid_static_rx[tid_num] = 0;
235 } else { 239 } else {
236 strcpy(state, "on "); 240 strcpy(state, "on ");
237 sta->ampdu_mlme.tid_rx[tid_num].buf_size = 0x00; 241 sta->ampdu_mlme.tid_state_rx[tid_num] &=
242 ~HT_AGG_STATE_DEBUGFS_CTL;
238 tid_static_rx[tid_num] = 1; 243 tid_static_rx[tid_num] = 1;
239 } 244 }
240 printk(KERN_DEBUG "debugfs - try switching tid %u %s\n", 245 printk(KERN_DEBUG "debugfs - try switching tid %u %s\n",
diff --git a/net/mac80211/ieee80211.c b/net/mac80211/ieee80211.c
index 616ce10d2a38..8c0f782d21e3 100644
--- a/net/mac80211/ieee80211.c
+++ b/net/mac80211/ieee80211.c
@@ -569,12 +569,12 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid)
569 spin_lock_bh(&sta->ampdu_mlme.ampdu_tx); 569 spin_lock_bh(&sta->ampdu_mlme.ampdu_tx);
570 570
571 /* we have tried too many times, receiver does not want A-MPDU */ 571 /* we have tried too many times, receiver does not want A-MPDU */
572 if (sta->ampdu_mlme.tid_tx[tid].addba_req_num > HT_AGG_MAX_RETRIES) { 572 if (sta->ampdu_mlme.addba_req_num[tid] > HT_AGG_MAX_RETRIES) {
573 ret = -EBUSY; 573 ret = -EBUSY;
574 goto start_ba_exit; 574 goto start_ba_exit;
575 } 575 }
576 576
577 state = &sta->ampdu_mlme.tid_tx[tid].state; 577 state = &sta->ampdu_mlme.tid_state_tx[tid];
578 /* check if the TID is not in aggregation flow already */ 578 /* check if the TID is not in aggregation flow already */
579 if (*state != HT_AGG_STATE_IDLE) { 579 if (*state != HT_AGG_STATE_IDLE) {
580#ifdef CONFIG_MAC80211_HT_DEBUG 580#ifdef CONFIG_MAC80211_HT_DEBUG
@@ -585,6 +585,23 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid)
585 goto start_ba_exit; 585 goto start_ba_exit;
586 } 586 }
587 587
588 /* prepare A-MPDU MLME for Tx aggregation */
589 sta->ampdu_mlme.tid_tx[tid] =
590 kmalloc(sizeof(struct tid_ampdu_tx), GFP_ATOMIC);
591 if (!sta->ampdu_mlme.tid_tx[tid]) {
592 if (net_ratelimit())
593 printk(KERN_ERR "allocate tx mlme to tid %d failed\n",
594 tid);
595 ret = -ENOMEM;
596 goto start_ba_exit;
597 }
598 /* Tx timer */
599 sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer.function =
600 sta_addba_resp_timer_expired;
601 sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer.data =
602 (unsigned long)&sta->timer_to_tid[tid];
603 init_timer(&sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer);
604
588 /* ensure that TX flow won't interrupt us 605 /* ensure that TX flow won't interrupt us
589 * until the end of the call to requeue function */ 606 * until the end of the call to requeue function */
590 spin_lock_bh(&local->mdev->queue_lock); 607 spin_lock_bh(&local->mdev->queue_lock);
@@ -596,11 +613,10 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid)
596 * don't switch to aggregation */ 613 * don't switch to aggregation */
597 if (ret) { 614 if (ret) {
598#ifdef CONFIG_MAC80211_HT_DEBUG 615#ifdef CONFIG_MAC80211_HT_DEBUG
599 printk(KERN_DEBUG "BA request denied - no queue available for" 616 printk(KERN_DEBUG "BA request denied - queue unavailable for"
600 " tid %d\n", tid); 617 " tid %d\n", tid);
601#endif /* CONFIG_MAC80211_HT_DEBUG */ 618#endif /* CONFIG_MAC80211_HT_DEBUG */
602 spin_unlock_bh(&local->mdev->queue_lock); 619 goto start_ba_err;
603 goto start_ba_exit;
604 } 620 }
605 sdata = sta->sdata; 621 sdata = sta->sdata;
606 622
@@ -618,38 +634,40 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid)
618 * allocated queue */ 634 * allocated queue */
619 ieee80211_ht_agg_queue_remove(local, sta, tid, 0); 635 ieee80211_ht_agg_queue_remove(local, sta, tid, 0);
620#ifdef CONFIG_MAC80211_HT_DEBUG 636#ifdef CONFIG_MAC80211_HT_DEBUG
621 printk(KERN_DEBUG "BA request denied - HW or queue unavailable" 637 printk(KERN_DEBUG "BA request denied - HW unavailable for"
622 " for tid %d\n", tid); 638 " tid %d\n", tid);
623#endif /* CONFIG_MAC80211_HT_DEBUG */ 639#endif /* CONFIG_MAC80211_HT_DEBUG */
624 spin_unlock_bh(&local->mdev->queue_lock);
625 *state = HT_AGG_STATE_IDLE; 640 *state = HT_AGG_STATE_IDLE;
626 goto start_ba_exit; 641 goto start_ba_err;
627 } 642 }
628 643
629 /* Will put all the packets in the new SW queue */ 644 /* Will put all the packets in the new SW queue */
630 ieee80211_requeue(local, ieee802_1d_to_ac[tid]); 645 ieee80211_requeue(local, ieee802_1d_to_ac[tid]);
631 spin_unlock_bh(&local->mdev->queue_lock); 646 spin_unlock_bh(&local->mdev->queue_lock);
632 647
633 /* We have most probably almost emptied the legacy queue */
634 /* ieee80211_wake_queue(local_to_hw(local), ieee802_1d_to_ac[tid]); */
635
636 /* send an addBA request */ 648 /* send an addBA request */
637 sta->ampdu_mlme.dialog_token_allocator++; 649 sta->ampdu_mlme.dialog_token_allocator++;
638 sta->ampdu_mlme.tid_tx[tid].dialog_token = 650 sta->ampdu_mlme.tid_tx[tid]->dialog_token =
639 sta->ampdu_mlme.dialog_token_allocator; 651 sta->ampdu_mlme.dialog_token_allocator;
640 sta->ampdu_mlme.tid_tx[tid].ssn = start_seq_num; 652 sta->ampdu_mlme.tid_tx[tid]->ssn = start_seq_num;
641 653
642 ieee80211_send_addba_request(sta->sdata->dev, ra, tid, 654 ieee80211_send_addba_request(sta->sdata->dev, ra, tid,
643 sta->ampdu_mlme.tid_tx[tid].dialog_token, 655 sta->ampdu_mlme.tid_tx[tid]->dialog_token,
644 sta->ampdu_mlme.tid_tx[tid].ssn, 656 sta->ampdu_mlme.tid_tx[tid]->ssn,
645 0x40, 5000); 657 0x40, 5000);
646 658
647 /* activate the timer for the recipient's addBA response */ 659 /* activate the timer for the recipient's addBA response */
648 sta->ampdu_mlme.tid_tx[tid].addba_resp_timer.expires = 660 sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer.expires =
649 jiffies + ADDBA_RESP_INTERVAL; 661 jiffies + ADDBA_RESP_INTERVAL;
650 add_timer(&sta->ampdu_mlme.tid_tx[tid].addba_resp_timer); 662 add_timer(&sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer);
651 printk(KERN_DEBUG "activated addBA response timer on tid %d\n", tid); 663 printk(KERN_DEBUG "activated addBA response timer on tid %d\n", tid);
664 goto start_ba_exit;
652 665
666start_ba_err:
667 kfree(sta->ampdu_mlme.tid_tx[tid]);
668 sta->ampdu_mlme.tid_tx[tid] = NULL;
669 spin_unlock_bh(&local->mdev->queue_lock);
670 ret = -EBUSY;
653start_ba_exit: 671start_ba_exit:
654 spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx); 672 spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx);
655 rcu_read_unlock(); 673 rcu_read_unlock();
@@ -683,7 +701,7 @@ int ieee80211_stop_tx_ba_session(struct ieee80211_hw *hw,
683 } 701 }
684 702
685 /* check if the TID is in aggregation */ 703 /* check if the TID is in aggregation */
686 state = &sta->ampdu_mlme.tid_tx[tid].state; 704 state = &sta->ampdu_mlme.tid_state_tx[tid];
687 spin_lock_bh(&sta->ampdu_mlme.ampdu_tx); 705 spin_lock_bh(&sta->ampdu_mlme.ampdu_tx);
688 706
689 if (*state != HT_AGG_STATE_OPERATIONAL) { 707 if (*state != HT_AGG_STATE_OPERATIONAL) {
@@ -741,7 +759,7 @@ void ieee80211_start_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u16 tid)
741 return; 759 return;
742 } 760 }
743 761
744 state = &sta->ampdu_mlme.tid_tx[tid].state; 762 state = &sta->ampdu_mlme.tid_state_tx[tid];
745 spin_lock_bh(&sta->ampdu_mlme.ampdu_tx); 763 spin_lock_bh(&sta->ampdu_mlme.ampdu_tx);
746 764
747 if (!(*state & HT_ADDBA_REQUESTED_MSK)) { 765 if (!(*state & HT_ADDBA_REQUESTED_MSK)) {
@@ -790,7 +808,7 @@ void ieee80211_stop_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u8 tid)
790 rcu_read_unlock(); 808 rcu_read_unlock();
791 return; 809 return;
792 } 810 }
793 state = &sta->ampdu_mlme.tid_tx[tid].state; 811 state = &sta->ampdu_mlme.tid_state_tx[tid];
794 812
795 spin_lock_bh(&sta->ampdu_mlme.ampdu_tx); 813 spin_lock_bh(&sta->ampdu_mlme.ampdu_tx);
796 if ((*state & HT_AGG_STATE_REQ_STOP_BA_MSK) == 0) { 814 if ((*state & HT_AGG_STATE_REQ_STOP_BA_MSK) == 0) {
@@ -819,7 +837,9 @@ void ieee80211_stop_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u8 tid)
819 * necessarily stopped */ 837 * necessarily stopped */
820 netif_schedule(local->mdev); 838 netif_schedule(local->mdev);
821 *state = HT_AGG_STATE_IDLE; 839 *state = HT_AGG_STATE_IDLE;
822 sta->ampdu_mlme.tid_tx[tid].addba_req_num = 0; 840 sta->ampdu_mlme.addba_req_num[tid] = 0;
841 kfree(sta->ampdu_mlme.tid_tx[tid]);
842 sta->ampdu_mlme.tid_tx[tid] = NULL;
823 spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx); 843 spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx);
824 844
825 rcu_read_unlock(); 845 rcu_read_unlock();
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index a6485f01b3c8..7ab806602183 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -73,11 +73,12 @@ struct ieee80211_fragment_entry {
73struct ieee80211_sta_bss { 73struct ieee80211_sta_bss {
74 struct list_head list; 74 struct list_head list;
75 struct ieee80211_sta_bss *hnext; 75 struct ieee80211_sta_bss *hnext;
76 size_t ssid_len;
77
76 atomic_t users; 78 atomic_t users;
77 79
78 u8 bssid[ETH_ALEN]; 80 u8 bssid[ETH_ALEN];
79 u8 ssid[IEEE80211_MAX_SSID_LEN]; 81 u8 ssid[IEEE80211_MAX_SSID_LEN];
80 size_t ssid_len;
81 u16 capability; /* host byte order */ 82 u16 capability; /* host byte order */
82 enum ieee80211_band band; 83 enum ieee80211_band band;
83 int freq; 84 int freq;
@@ -98,8 +99,8 @@ struct ieee80211_sta_bss {
98#define IEEE80211_MAX_SUPP_RATES 32 99#define IEEE80211_MAX_SUPP_RATES 32
99 u8 supp_rates[IEEE80211_MAX_SUPP_RATES]; 100 u8 supp_rates[IEEE80211_MAX_SUPP_RATES];
100 size_t supp_rates_len; 101 size_t supp_rates_len;
101 int beacon_int;
102 u64 timestamp; 102 u64 timestamp;
103 int beacon_int;
103 104
104 int probe_resp; 105 int probe_resp;
105 unsigned long last_update; 106 unsigned long last_update;
@@ -154,9 +155,7 @@ struct ieee80211_tx_data {
154 struct ieee80211_local *local; 155 struct ieee80211_local *local;
155 struct ieee80211_sub_if_data *sdata; 156 struct ieee80211_sub_if_data *sdata;
156 struct sta_info *sta; 157 struct sta_info *sta;
157 u16 fc, ethertype;
158 struct ieee80211_key *key; 158 struct ieee80211_key *key;
159 unsigned int flags;
160 159
161 struct ieee80211_tx_control *control; 160 struct ieee80211_tx_control *control;
162 struct ieee80211_channel *channel; 161 struct ieee80211_channel *channel;
@@ -168,8 +167,11 @@ struct ieee80211_tx_data {
168 167
169 /* Extra fragments (in addition to the first fragment 168 /* Extra fragments (in addition to the first fragment
170 * in skb) */ 169 * in skb) */
171 int num_extra_frag;
172 struct sk_buff **extra_frag; 170 struct sk_buff **extra_frag;
171 int num_extra_frag;
172
173 u16 fc, ethertype;
174 unsigned int flags;
173}; 175};
174 176
175 177
@@ -192,12 +194,12 @@ struct ieee80211_rx_data {
192 struct ieee80211_local *local; 194 struct ieee80211_local *local;
193 struct ieee80211_sub_if_data *sdata; 195 struct ieee80211_sub_if_data *sdata;
194 struct sta_info *sta; 196 struct sta_info *sta;
195 u16 fc, ethertype;
196 struct ieee80211_key *key; 197 struct ieee80211_key *key;
197 unsigned int flags;
198
199 struct ieee80211_rx_status *status; 198 struct ieee80211_rx_status *status;
200 struct ieee80211_rate *rate; 199 struct ieee80211_rate *rate;
200
201 u16 fc, ethertype;
202 unsigned int flags;
201 int sent_ps_buffered; 203 int sent_ps_buffered;
202 int queue; 204 int queue;
203 int load; 205 int load;
@@ -222,9 +224,9 @@ struct ieee80211_tx_packet_data {
222struct ieee80211_tx_stored_packet { 224struct ieee80211_tx_stored_packet {
223 struct ieee80211_tx_control control; 225 struct ieee80211_tx_control control;
224 struct sk_buff *skb; 226 struct sk_buff *skb;
225 int num_extra_frag;
226 struct sk_buff **extra_frag; 227 struct sk_buff **extra_frag;
227 struct ieee80211_rate *last_frag_rate; 228 struct ieee80211_rate *last_frag_rate;
229 int num_extra_frag;
228 unsigned int last_frag_rate_ctrl_probe; 230 unsigned int last_frag_rate_ctrl_probe;
229}; 231};
230 232
@@ -246,8 +248,8 @@ struct ieee80211_if_ap {
246 * bitmap_empty :) 248 * bitmap_empty :)
247 * NB: don't touch this bitmap, use sta_info_{set,clear}_tim_bit */ 249 * NB: don't touch this bitmap, use sta_info_{set,clear}_tim_bit */
248 u8 tim[sizeof(unsigned long) * BITS_TO_LONGS(IEEE80211_MAX_AID + 1)]; 250 u8 tim[sizeof(unsigned long) * BITS_TO_LONGS(IEEE80211_MAX_AID + 1)];
249 atomic_t num_sta_ps; /* number of stations in PS mode */
250 struct sk_buff_head ps_bc_buf; 251 struct sk_buff_head ps_bc_buf;
252 atomic_t num_sta_ps; /* number of stations in PS mode */
251 int dtim_count; 253 int dtim_count;
252 int force_unicast_rateidx; /* forced TX rateidx for unicast frames */ 254 int force_unicast_rateidx; /* forced TX rateidx for unicast frames */
253 int max_ratectrl_rateidx; /* max TX rateidx for rate control */ 255 int max_ratectrl_rateidx; /* max TX rateidx for rate control */
@@ -255,8 +257,8 @@ struct ieee80211_if_ap {
255}; 257};
256 258
257struct ieee80211_if_wds { 259struct ieee80211_if_wds {
258 u8 remote_addr[ETH_ALEN];
259 struct sta_info *sta; 260 struct sta_info *sta;
261 u8 remote_addr[ETH_ALEN];
260}; 262};
261 263
262struct ieee80211_if_vlan { 264struct ieee80211_if_vlan {
@@ -290,12 +292,12 @@ struct mesh_config {
290 u8 dot11MeshTTL; 292 u8 dot11MeshTTL;
291 bool auto_open_plinks; 293 bool auto_open_plinks;
292 /* HWMP parameters */ 294 /* HWMP parameters */
293 u32 dot11MeshHWMPactivePathTimeout;
294 u16 dot11MeshHWMPpreqMinInterval;
295 u16 dot11MeshHWMPnetDiameterTraversalTime;
296 u8 dot11MeshHWMPmaxPREQretries; 295 u8 dot11MeshHWMPmaxPREQretries;
297 u32 path_refresh_time; 296 u32 path_refresh_time;
298 u16 min_discovery_timeout; 297 u16 min_discovery_timeout;
298 u32 dot11MeshHWMPactivePathTimeout;
299 u16 dot11MeshHWMPpreqMinInterval;
300 u16 dot11MeshHWMPnetDiameterTraversalTime;
299}; 301};
300 302
301 303
@@ -314,23 +316,22 @@ struct mesh_config {
314#define IEEE80211_STA_AUTO_CHANNEL_SEL BIT(12) 316#define IEEE80211_STA_AUTO_CHANNEL_SEL BIT(12)
315#define IEEE80211_STA_PRIVACY_INVOKED BIT(13) 317#define IEEE80211_STA_PRIVACY_INVOKED BIT(13)
316struct ieee80211_if_sta { 318struct ieee80211_if_sta {
319 struct timer_list timer;
320 struct work_struct work;
321 u8 bssid[ETH_ALEN], prev_bssid[ETH_ALEN];
322 u8 ssid[IEEE80211_MAX_SSID_LEN];
317 enum { 323 enum {
318 IEEE80211_DISABLED, IEEE80211_AUTHENTICATE, 324 IEEE80211_DISABLED, IEEE80211_AUTHENTICATE,
319 IEEE80211_ASSOCIATE, IEEE80211_ASSOCIATED, 325 IEEE80211_ASSOCIATE, IEEE80211_ASSOCIATED,
320 IEEE80211_IBSS_SEARCH, IEEE80211_IBSS_JOINED, 326 IEEE80211_IBSS_SEARCH, IEEE80211_IBSS_JOINED,
321 IEEE80211_MESH_UP 327 IEEE80211_MESH_UP
322 } state; 328 } state;
323 struct timer_list timer;
324 struct work_struct work;
325 u8 bssid[ETH_ALEN], prev_bssid[ETH_ALEN];
326 u8 ssid[IEEE80211_MAX_SSID_LEN];
327 size_t ssid_len; 329 size_t ssid_len;
328 u8 scan_ssid[IEEE80211_MAX_SSID_LEN]; 330 u8 scan_ssid[IEEE80211_MAX_SSID_LEN];
329 size_t scan_ssid_len; 331 size_t scan_ssid_len;
330#ifdef CONFIG_MAC80211_MESH 332#ifdef CONFIG_MAC80211_MESH
331 struct timer_list mesh_path_timer; 333 struct timer_list mesh_path_timer;
332 u8 mesh_id[IEEE80211_MAX_MESH_ID_LEN]; 334 u8 mesh_id[IEEE80211_MAX_MESH_ID_LEN];
333 bool accepting_plinks;
334 size_t mesh_id_len; 335 size_t mesh_id_len;
335 /* Active Path Selection Protocol Identifier */ 336 /* Active Path Selection Protocol Identifier */
336 u8 mesh_pp_id[4]; 337 u8 mesh_pp_id[4];
@@ -354,6 +355,7 @@ struct ieee80211_if_sta {
354 struct mesh_stats mshstats; 355 struct mesh_stats mshstats;
355 struct mesh_config mshcfg; 356 struct mesh_config mshcfg;
356 u8 mesh_seqnum[3]; 357 u8 mesh_seqnum[3];
358 bool accepting_plinks;
357#endif 359#endif
358 u16 aid; 360 u16 aid;
359 u16 ap_capab, capab; 361 u16 ap_capab, capab;
@@ -364,16 +366,18 @@ struct ieee80211_if_sta {
364 u8 *assocreq_ies, *assocresp_ies; 366 u8 *assocreq_ies, *assocresp_ies;
365 size_t assocreq_ies_len, assocresp_ies_len; 367 size_t assocreq_ies_len, assocresp_ies_len;
366 368
369 struct sk_buff_head skb_queue;
370
367 int auth_tries, assoc_tries; 371 int auth_tries, assoc_tries;
368 372
373 unsigned long request;
374
375 unsigned long last_probe;
376
369 unsigned int flags; 377 unsigned int flags;
370#define IEEE80211_STA_REQ_SCAN 0 378#define IEEE80211_STA_REQ_SCAN 0
371#define IEEE80211_STA_REQ_AUTH 1 379#define IEEE80211_STA_REQ_AUTH 1
372#define IEEE80211_STA_REQ_RUN 2 380#define IEEE80211_STA_REQ_RUN 2
373 unsigned long request;
374 struct sk_buff_head skb_queue;
375
376 unsigned long last_probe;
377 381
378#define IEEE80211_AUTH_ALG_OPEN BIT(0) 382#define IEEE80211_AUTH_ALG_OPEN BIT(0)
379#define IEEE80211_AUTH_ALG_SHARED_KEY BIT(1) 383#define IEEE80211_AUTH_ALG_SHARED_KEY BIT(1)
diff --git a/net/mac80211/ieee80211_ioctl.c b/net/mac80211/ieee80211_ioctl.c
index 5af23d318726..b047eebb6330 100644
--- a/net/mac80211/ieee80211_ioctl.c
+++ b/net/mac80211/ieee80211_ioctl.c
@@ -55,9 +55,6 @@ static int ieee80211_set_encryption(struct net_device *dev, u8 *sta_addr,
55 key = sta->key; 55 key = sta->key;
56 } 56 }
57 57
58 if (!key)
59 return -ENOENT;
60
61 ieee80211_key_free(key); 58 ieee80211_key_free(key);
62 return 0; 59 return 0;
63 } else { 60 } else {
diff --git a/net/mac80211/ieee80211_sta.c b/net/mac80211/ieee80211_sta.c
index cf51ca6804dd..f9cf2f187893 100644
--- a/net/mac80211/ieee80211_sta.c
+++ b/net/mac80211/ieee80211_sta.c
@@ -1216,12 +1216,11 @@ static void ieee80211_sta_process_addba_request(struct net_device *dev,
1216 buf_size = buf_size << sband->ht_info.ampdu_factor; 1216 buf_size = buf_size << sband->ht_info.ampdu_factor;
1217 } 1217 }
1218 1218
1219 tid_agg_rx = &sta->ampdu_mlme.tid_rx[tid];
1220 1219
1221 /* examine state machine */ 1220 /* examine state machine */
1222 spin_lock_bh(&sta->ampdu_mlme.ampdu_rx); 1221 spin_lock_bh(&sta->ampdu_mlme.ampdu_rx);
1223 1222
1224 if (tid_agg_rx->state != HT_AGG_STATE_IDLE) { 1223 if (sta->ampdu_mlme.tid_state_rx[tid] != HT_AGG_STATE_IDLE) {
1225#ifdef CONFIG_MAC80211_HT_DEBUG 1224#ifdef CONFIG_MAC80211_HT_DEBUG
1226 if (net_ratelimit()) 1225 if (net_ratelimit())
1227 printk(KERN_DEBUG "unexpected AddBA Req from " 1226 printk(KERN_DEBUG "unexpected AddBA Req from "
@@ -1231,6 +1230,24 @@ static void ieee80211_sta_process_addba_request(struct net_device *dev,
1231 goto end; 1230 goto end;
1232 } 1231 }
1233 1232
1233 /* prepare A-MPDU MLME for Rx aggregation */
1234 sta->ampdu_mlme.tid_rx[tid] =
1235 kmalloc(sizeof(struct tid_ampdu_rx), GFP_ATOMIC);
1236 if (!sta->ampdu_mlme.tid_rx[tid]) {
1237 if (net_ratelimit())
1238 printk(KERN_ERR "allocate rx mlme to tid %d failed\n",
1239 tid);
1240 goto end;
1241 }
1242 /* rx timer */
1243 sta->ampdu_mlme.tid_rx[tid]->session_timer.function =
1244 sta_rx_agg_session_timer_expired;
1245 sta->ampdu_mlme.tid_rx[tid]->session_timer.data =
1246 (unsigned long)&sta->timer_to_tid[tid];
1247 init_timer(&sta->ampdu_mlme.tid_rx[tid]->session_timer);
1248
1249 tid_agg_rx = sta->ampdu_mlme.tid_rx[tid];
1250
1234 /* prepare reordering buffer */ 1251 /* prepare reordering buffer */
1235 tid_agg_rx->reorder_buf = 1252 tid_agg_rx->reorder_buf =
1236 kmalloc(buf_size * sizeof(struct sk_buf *), GFP_ATOMIC); 1253 kmalloc(buf_size * sizeof(struct sk_buf *), GFP_ATOMIC);
@@ -1238,6 +1255,7 @@ static void ieee80211_sta_process_addba_request(struct net_device *dev,
1238 if (net_ratelimit()) 1255 if (net_ratelimit())
1239 printk(KERN_ERR "can not allocate reordering buffer " 1256 printk(KERN_ERR "can not allocate reordering buffer "
1240 "to tid %d\n", tid); 1257 "to tid %d\n", tid);
1258 kfree(sta->ampdu_mlme.tid_rx[tid]);
1241 goto end; 1259 goto end;
1242 } 1260 }
1243 memset(tid_agg_rx->reorder_buf, 0, 1261 memset(tid_agg_rx->reorder_buf, 0,
@@ -1252,11 +1270,13 @@ static void ieee80211_sta_process_addba_request(struct net_device *dev,
1252 1270
1253 if (ret) { 1271 if (ret) {
1254 kfree(tid_agg_rx->reorder_buf); 1272 kfree(tid_agg_rx->reorder_buf);
1273 kfree(tid_agg_rx);
1274 sta->ampdu_mlme.tid_rx[tid] = NULL;
1255 goto end; 1275 goto end;
1256 } 1276 }
1257 1277
1258 /* change state and send addba resp */ 1278 /* change state and send addba resp */
1259 tid_agg_rx->state = HT_AGG_STATE_OPERATIONAL; 1279 sta->ampdu_mlme.tid_state_rx[tid] = HT_AGG_STATE_OPERATIONAL;
1260 tid_agg_rx->dialog_token = dialog_token; 1280 tid_agg_rx->dialog_token = dialog_token;
1261 tid_agg_rx->ssn = start_seq_num; 1281 tid_agg_rx->ssn = start_seq_num;
1262 tid_agg_rx->head_seq_num = start_seq_num; 1282 tid_agg_rx->head_seq_num = start_seq_num;
@@ -1295,39 +1315,37 @@ static void ieee80211_sta_process_addba_resp(struct net_device *dev,
1295 capab = le16_to_cpu(mgmt->u.action.u.addba_resp.capab); 1315 capab = le16_to_cpu(mgmt->u.action.u.addba_resp.capab);
1296 tid = (capab & IEEE80211_ADDBA_PARAM_TID_MASK) >> 2; 1316 tid = (capab & IEEE80211_ADDBA_PARAM_TID_MASK) >> 2;
1297 1317
1298 state = &sta->ampdu_mlme.tid_tx[tid].state; 1318 state = &sta->ampdu_mlme.tid_state_tx[tid];
1299 1319
1300 spin_lock_bh(&sta->ampdu_mlme.ampdu_tx); 1320 spin_lock_bh(&sta->ampdu_mlme.ampdu_tx);
1301 1321
1322 if (!(*state & HT_ADDBA_REQUESTED_MSK)) {
1323 spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx);
1324 printk(KERN_DEBUG "state not HT_ADDBA_REQUESTED_MSK:"
1325 "%d\n", *state);
1326 goto addba_resp_exit;
1327 }
1328
1302 if (mgmt->u.action.u.addba_resp.dialog_token != 1329 if (mgmt->u.action.u.addba_resp.dialog_token !=
1303 sta->ampdu_mlme.tid_tx[tid].dialog_token) { 1330 sta->ampdu_mlme.tid_tx[tid]->dialog_token) {
1304 spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx); 1331 spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx);
1305#ifdef CONFIG_MAC80211_HT_DEBUG 1332#ifdef CONFIG_MAC80211_HT_DEBUG
1306 printk(KERN_DEBUG "wrong addBA response token, tid %d\n", tid); 1333 printk(KERN_DEBUG "wrong addBA response token, tid %d\n", tid);
1307#endif /* CONFIG_MAC80211_HT_DEBUG */ 1334#endif /* CONFIG_MAC80211_HT_DEBUG */
1308 rcu_read_unlock(); 1335 goto addba_resp_exit;
1309 return;
1310 } 1336 }
1311 1337
1312 del_timer_sync(&sta->ampdu_mlme.tid_tx[tid].addba_resp_timer); 1338 del_timer_sync(&sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer);
1313#ifdef CONFIG_MAC80211_HT_DEBUG 1339#ifdef CONFIG_MAC80211_HT_DEBUG
1314 printk(KERN_DEBUG "switched off addBA timer for tid %d \n", tid); 1340 printk(KERN_DEBUG "switched off addBA timer for tid %d \n", tid);
1315#endif /* CONFIG_MAC80211_HT_DEBUG */ 1341#endif /* CONFIG_MAC80211_HT_DEBUG */
1316 if (le16_to_cpu(mgmt->u.action.u.addba_resp.status) 1342 if (le16_to_cpu(mgmt->u.action.u.addba_resp.status)
1317 == WLAN_STATUS_SUCCESS) { 1343 == WLAN_STATUS_SUCCESS) {
1318 if (!(*state & HT_ADDBA_REQUESTED_MSK)) {
1319 spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx);
1320 printk(KERN_DEBUG "state not HT_ADDBA_REQUESTED_MSK:"
1321 "%d\n", *state);
1322 rcu_read_unlock();
1323 return;
1324 }
1325
1326 if (*state & HT_ADDBA_RECEIVED_MSK) 1344 if (*state & HT_ADDBA_RECEIVED_MSK)
1327 printk(KERN_DEBUG "double addBA response\n"); 1345 printk(KERN_DEBUG "double addBA response\n");
1328 1346
1329 *state |= HT_ADDBA_RECEIVED_MSK; 1347 *state |= HT_ADDBA_RECEIVED_MSK;
1330 sta->ampdu_mlme.tid_tx[tid].addba_req_num = 0; 1348 sta->ampdu_mlme.addba_req_num[tid] = 0;
1331 1349
1332 if (*state == HT_AGG_STATE_OPERATIONAL) { 1350 if (*state == HT_AGG_STATE_OPERATIONAL) {
1333 printk(KERN_DEBUG "Aggregation on for tid %d \n", tid); 1351 printk(KERN_DEBUG "Aggregation on for tid %d \n", tid);
@@ -1339,13 +1357,15 @@ static void ieee80211_sta_process_addba_resp(struct net_device *dev,
1339 } else { 1357 } else {
1340 printk(KERN_DEBUG "recipient rejected agg: tid %d \n", tid); 1358 printk(KERN_DEBUG "recipient rejected agg: tid %d \n", tid);
1341 1359
1342 sta->ampdu_mlme.tid_tx[tid].addba_req_num++; 1360 sta->ampdu_mlme.addba_req_num[tid]++;
1343 /* this will allow the state check in stop_BA_session */ 1361 /* this will allow the state check in stop_BA_session */
1344 *state = HT_AGG_STATE_OPERATIONAL; 1362 *state = HT_AGG_STATE_OPERATIONAL;
1345 spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx); 1363 spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx);
1346 ieee80211_stop_tx_ba_session(hw, sta->addr, tid, 1364 ieee80211_stop_tx_ba_session(hw, sta->addr, tid,
1347 WLAN_BACK_INITIATOR); 1365 WLAN_BACK_INITIATOR);
1348 } 1366 }
1367
1368addba_resp_exit:
1349 rcu_read_unlock(); 1369 rcu_read_unlock();
1350} 1370}
1351 1371
@@ -1411,13 +1431,13 @@ void ieee80211_sta_stop_rx_ba_session(struct net_device *dev, u8 *ra, u16 tid,
1411 1431
1412 /* check if TID is in operational state */ 1432 /* check if TID is in operational state */
1413 spin_lock_bh(&sta->ampdu_mlme.ampdu_rx); 1433 spin_lock_bh(&sta->ampdu_mlme.ampdu_rx);
1414 if (sta->ampdu_mlme.tid_rx[tid].state 1434 if (sta->ampdu_mlme.tid_state_rx[tid]
1415 != HT_AGG_STATE_OPERATIONAL) { 1435 != HT_AGG_STATE_OPERATIONAL) {
1416 spin_unlock_bh(&sta->ampdu_mlme.ampdu_rx); 1436 spin_unlock_bh(&sta->ampdu_mlme.ampdu_rx);
1417 rcu_read_unlock(); 1437 rcu_read_unlock();
1418 return; 1438 return;
1419 } 1439 }
1420 sta->ampdu_mlme.tid_rx[tid].state = 1440 sta->ampdu_mlme.tid_state_rx[tid] =
1421 HT_AGG_STATE_REQ_STOP_BA_MSK | 1441 HT_AGG_STATE_REQ_STOP_BA_MSK |
1422 (initiator << HT_AGG_STATE_INITIATOR_SHIFT); 1442 (initiator << HT_AGG_STATE_INITIATOR_SHIFT);
1423 spin_unlock_bh(&sta->ampdu_mlme.ampdu_rx); 1443 spin_unlock_bh(&sta->ampdu_mlme.ampdu_rx);
@@ -1434,25 +1454,27 @@ void ieee80211_sta_stop_rx_ba_session(struct net_device *dev, u8 *ra, u16 tid,
1434 1454
1435 /* shutdown timer has not expired */ 1455 /* shutdown timer has not expired */
1436 if (initiator != WLAN_BACK_TIMER) 1456 if (initiator != WLAN_BACK_TIMER)
1437 del_timer_sync(&sta->ampdu_mlme.tid_rx[tid]. 1457 del_timer_sync(&sta->ampdu_mlme.tid_rx[tid]->session_timer);
1438 session_timer);
1439 1458
1440 /* check if this is a self generated aggregation halt */ 1459 /* check if this is a self generated aggregation halt */
1441 if (initiator == WLAN_BACK_RECIPIENT || initiator == WLAN_BACK_TIMER) 1460 if (initiator == WLAN_BACK_RECIPIENT || initiator == WLAN_BACK_TIMER)
1442 ieee80211_send_delba(dev, ra, tid, 0, reason); 1461 ieee80211_send_delba(dev, ra, tid, 0, reason);
1443 1462
1444 /* free the reordering buffer */ 1463 /* free the reordering buffer */
1445 for (i = 0; i < sta->ampdu_mlme.tid_rx[tid].buf_size; i++) { 1464 for (i = 0; i < sta->ampdu_mlme.tid_rx[tid]->buf_size; i++) {
1446 if (sta->ampdu_mlme.tid_rx[tid].reorder_buf[i]) { 1465 if (sta->ampdu_mlme.tid_rx[tid]->reorder_buf[i]) {
1447 /* release the reordered frames */ 1466 /* release the reordered frames */
1448 dev_kfree_skb(sta->ampdu_mlme.tid_rx[tid].reorder_buf[i]); 1467 dev_kfree_skb(sta->ampdu_mlme.tid_rx[tid]->reorder_buf[i]);
1449 sta->ampdu_mlme.tid_rx[tid].stored_mpdu_num--; 1468 sta->ampdu_mlme.tid_rx[tid]->stored_mpdu_num--;
1450 sta->ampdu_mlme.tid_rx[tid].reorder_buf[i] = NULL; 1469 sta->ampdu_mlme.tid_rx[tid]->reorder_buf[i] = NULL;
1451 } 1470 }
1452 } 1471 }
1453 kfree(sta->ampdu_mlme.tid_rx[tid].reorder_buf); 1472 /* free resources */
1473 kfree(sta->ampdu_mlme.tid_rx[tid]->reorder_buf);
1474 kfree(sta->ampdu_mlme.tid_rx[tid]);
1475 sta->ampdu_mlme.tid_rx[tid] = NULL;
1476 sta->ampdu_mlme.tid_state_rx[tid] = HT_AGG_STATE_IDLE;
1454 1477
1455 sta->ampdu_mlme.tid_rx[tid].state = HT_AGG_STATE_IDLE;
1456 rcu_read_unlock(); 1478 rcu_read_unlock();
1457} 1479}
1458 1480
@@ -1491,7 +1513,7 @@ static void ieee80211_sta_process_delba(struct net_device *dev,
1491 WLAN_BACK_INITIATOR, 0); 1513 WLAN_BACK_INITIATOR, 0);
1492 else { /* WLAN_BACK_RECIPIENT */ 1514 else { /* WLAN_BACK_RECIPIENT */
1493 spin_lock_bh(&sta->ampdu_mlme.ampdu_tx); 1515 spin_lock_bh(&sta->ampdu_mlme.ampdu_tx);
1494 sta->ampdu_mlme.tid_tx[tid].state = 1516 sta->ampdu_mlme.tid_state_tx[tid] =
1495 HT_AGG_STATE_OPERATIONAL; 1517 HT_AGG_STATE_OPERATIONAL;
1496 spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx); 1518 spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx);
1497 ieee80211_stop_tx_ba_session(&local->hw, sta->addr, tid, 1519 ieee80211_stop_tx_ba_session(&local->hw, sta->addr, tid,
@@ -1528,7 +1550,7 @@ void sta_addba_resp_timer_expired(unsigned long data)
1528 return; 1550 return;
1529 } 1551 }
1530 1552
1531 state = &sta->ampdu_mlme.tid_tx[tid].state; 1553 state = &sta->ampdu_mlme.tid_state_tx[tid];
1532 /* check if the TID waits for addBA response */ 1554 /* check if the TID waits for addBA response */
1533 spin_lock_bh(&sta->ampdu_mlme.ampdu_tx); 1555 spin_lock_bh(&sta->ampdu_mlme.ampdu_tx);
1534 if (!(*state & HT_ADDBA_REQUESTED_MSK)) { 1556 if (!(*state & HT_ADDBA_REQUESTED_MSK)) {
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 644d2774469d..d9c6ed5be4fc 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -1514,9 +1514,10 @@ ieee80211_rx_h_ctrl(struct ieee80211_rx_data *rx)
1514 if (!rx->sta) 1514 if (!rx->sta)
1515 return RX_CONTINUE; 1515 return RX_CONTINUE;
1516 tid = le16_to_cpu(bar->control) >> 12; 1516 tid = le16_to_cpu(bar->control) >> 12;
1517 tid_agg_rx = &(rx->sta->ampdu_mlme.tid_rx[tid]); 1517 if (rx->sta->ampdu_mlme.tid_state_rx[tid]
1518 if (tid_agg_rx->state != HT_AGG_STATE_OPERATIONAL) 1518 != HT_AGG_STATE_OPERATIONAL)
1519 return RX_CONTINUE; 1519 return RX_CONTINUE;
1520 tid_agg_rx = rx->sta->ampdu_mlme.tid_rx[tid];
1520 1521
1521 start_seq_num = le16_to_cpu(bar->start_seq_num) >> 4; 1522 start_seq_num = le16_to_cpu(bar->start_seq_num) >> 4;
1522 1523
@@ -2123,11 +2124,12 @@ static u8 ieee80211_rx_reorder_ampdu(struct ieee80211_local *local,
2123 2124
2124 qc = skb->data + ieee80211_get_hdrlen(fc) - QOS_CONTROL_LEN; 2125 qc = skb->data + ieee80211_get_hdrlen(fc) - QOS_CONTROL_LEN;
2125 tid = qc[0] & QOS_CONTROL_TID_MASK; 2126 tid = qc[0] & QOS_CONTROL_TID_MASK;
2126 tid_agg_rx = &(sta->ampdu_mlme.tid_rx[tid]);
2127 2127
2128 if (tid_agg_rx->state != HT_AGG_STATE_OPERATIONAL) 2128 if (sta->ampdu_mlme.tid_state_rx[tid] != HT_AGG_STATE_OPERATIONAL)
2129 goto end_reorder; 2129 goto end_reorder;
2130 2130
2131 tid_agg_rx = sta->ampdu_mlme.tid_rx[tid];
2132
2131 /* null data frames are excluded */ 2133 /* null data frames are excluded */
2132 if (unlikely(fc & IEEE80211_STYPE_NULLFUNC)) 2134 if (unlikely(fc & IEEE80211_STYPE_NULLFUNC))
2133 goto end_reorder; 2135 goto end_reorder;
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index 3b84c16cf054..f708367092d1 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -170,9 +170,16 @@ void sta_info_destroy(struct sta_info *sta)
170 dev_kfree_skb_any(skb); 170 dev_kfree_skb_any(skb);
171 171
172 for (i = 0; i < STA_TID_NUM; i++) { 172 for (i = 0; i < STA_TID_NUM; i++) {
173 del_timer_sync(&sta->ampdu_mlme.tid_rx[i].session_timer); 173 spin_lock_bh(&sta->ampdu_mlme.ampdu_rx);
174 del_timer_sync(&sta->ampdu_mlme.tid_tx[i].addba_resp_timer); 174 if (sta->ampdu_mlme.tid_rx[i])
175 del_timer_sync(&sta->ampdu_mlme.tid_rx[i]->session_timer);
176 spin_unlock_bh(&sta->ampdu_mlme.ampdu_rx);
177 spin_lock_bh(&sta->ampdu_mlme.ampdu_tx);
178 if (sta->ampdu_mlme.tid_tx[i])
179 del_timer_sync(&sta->ampdu_mlme.tid_tx[i]->addba_resp_timer);
180 spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx);
175 } 181 }
182
176 rate_control_free_sta(sta->rate_ctrl, sta->rate_ctrl_priv); 183 rate_control_free_sta(sta->rate_ctrl, sta->rate_ctrl_priv);
177 rate_control_put(sta->rate_ctrl); 184 rate_control_put(sta->rate_ctrl);
178 185
@@ -227,18 +234,13 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata,
227 sta->timer_to_tid[i] = i; 234 sta->timer_to_tid[i] = i;
228 /* tid to tx queue: initialize according to HW (0 is valid) */ 235 /* tid to tx queue: initialize according to HW (0 is valid) */
229 sta->tid_to_tx_q[i] = local->hw.queues; 236 sta->tid_to_tx_q[i] = local->hw.queues;
230 /* rx timers */ 237 /* rx */
231 sta->ampdu_mlme.tid_rx[i].session_timer.function = 238 sta->ampdu_mlme.tid_state_rx[i] = HT_AGG_STATE_IDLE;
232 sta_rx_agg_session_timer_expired; 239 sta->ampdu_mlme.tid_rx[i] = NULL;
233 sta->ampdu_mlme.tid_rx[i].session_timer.data = 240 /* tx */
234 (unsigned long)&sta->timer_to_tid[i]; 241 sta->ampdu_mlme.tid_state_tx[i] = HT_AGG_STATE_IDLE;
235 init_timer(&sta->ampdu_mlme.tid_rx[i].session_timer); 242 sta->ampdu_mlme.tid_tx[i] = NULL;
236 /* tx timers */ 243 sta->ampdu_mlme.addba_req_num[i] = 0;
237 sta->ampdu_mlme.tid_tx[i].addba_resp_timer.function =
238 sta_addba_resp_timer_expired;
239 sta->ampdu_mlme.tid_tx[i].addba_resp_timer.data =
240 (unsigned long)&sta->timer_to_tid[i];
241 init_timer(&sta->ampdu_mlme.tid_tx[i].addba_resp_timer);
242 } 244 }
243 skb_queue_head_init(&sta->ps_tx_buf); 245 skb_queue_head_init(&sta->ps_tx_buf);
244 skb_queue_head_init(&sta->tx_filtered); 246 skb_queue_head_init(&sta->tx_filtered);
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h
index f166c8039f2b..5e39a4164b9b 100644
--- a/net/mac80211/sta_info.h
+++ b/net/mac80211/sta_info.h
@@ -63,47 +63,42 @@ enum ieee80211_sta_info_flags {
63#define HT_AGG_STATE_OPERATIONAL (HT_ADDBA_REQUESTED_MSK | \ 63#define HT_AGG_STATE_OPERATIONAL (HT_ADDBA_REQUESTED_MSK | \
64 HT_ADDBA_DRV_READY_MSK | \ 64 HT_ADDBA_DRV_READY_MSK | \
65 HT_ADDBA_RECEIVED_MSK) 65 HT_ADDBA_RECEIVED_MSK)
66#define HT_AGG_STATE_DEBUGFS_CTL BIT(7)
66 67
67/** 68/**
68 * struct tid_ampdu_tx - TID aggregation information (Tx). 69 * struct tid_ampdu_tx - TID aggregation information (Tx).
69 * 70 *
70 * @state: TID's state in session state machine.
71 * @dialog_token: dialog token for aggregation session
72 * @ssn: Starting Sequence Number expected to be aggregated.
73 * @addba_resp_timer: timer for peer's response to addba request 71 * @addba_resp_timer: timer for peer's response to addba request
74 * @addba_req_num: number of times addBA request has been sent. 72 * @ssn: Starting Sequence Number expected to be aggregated.
73 * @dialog_token: dialog token for aggregation session
75 */ 74 */
76struct tid_ampdu_tx { 75struct tid_ampdu_tx {
77 u8 state;
78 u8 dialog_token;
79 u16 ssn;
80 struct timer_list addba_resp_timer; 76 struct timer_list addba_resp_timer;
81 u8 addba_req_num; 77 u16 ssn;
78 u8 dialog_token;
82}; 79};
83 80
84/** 81/**
85 * struct tid_ampdu_rx - TID aggregation information (Rx). 82 * struct tid_ampdu_rx - TID aggregation information (Rx).
86 * 83 *
87 * @state: TID's state in session state machine. 84 * @reorder_buf: buffer to reorder incoming aggregated MPDUs
88 * @dialog_token: dialog token for aggregation session 85 * @session_timer: check if peer keeps Tx-ing on the TID (by timeout value)
86 * @head_seq_num: head sequence number in reordering buffer.
87 * @stored_mpdu_num: number of MPDUs in reordering buffer
89 * @ssn: Starting Sequence Number expected to be aggregated. 88 * @ssn: Starting Sequence Number expected to be aggregated.
90 * @buf_size: buffer size for incoming A-MPDUs 89 * @buf_size: buffer size for incoming A-MPDUs
91 * @timeout: reset timer value. 90 * @timeout: reset timer value.
92 * @head_seq_num: head sequence number in reordering buffer. 91 * @dialog_token: dialog token for aggregation session
93 * @stored_mpdu_num: number of MPDUs in reordering buffer
94 * @reorder_buf: buffer to reorder incoming aggregated MPDUs
95 * @session_timer: check if peer keeps Tx-ing on the TID (by timeout value)
96 */ 92 */
97struct tid_ampdu_rx { 93struct tid_ampdu_rx {
98 u8 state; 94 struct sk_buff **reorder_buf;
99 u8 dialog_token; 95 struct timer_list session_timer;
96 u16 head_seq_num;
97 u16 stored_mpdu_num;
100 u16 ssn; 98 u16 ssn;
101 u16 buf_size; 99 u16 buf_size;
102 u16 timeout; 100 u16 timeout;
103 u16 head_seq_num; 101 u8 dialog_token;
104 u16 stored_mpdu_num;
105 struct sk_buff **reorder_buf;
106 struct timer_list session_timer;
107}; 102};
108 103
109/** 104/**
@@ -132,16 +127,24 @@ enum plink_state {
132/** 127/**
133 * struct sta_ampdu_mlme - STA aggregation information. 128 * struct sta_ampdu_mlme - STA aggregation information.
134 * 129 *
130 * @tid_state_rx: TID's state in Rx session state machine.
135 * @tid_rx: aggregation info for Rx per TID 131 * @tid_rx: aggregation info for Rx per TID
136 * @tid_tx: aggregation info for Tx per TID
137 * @ampdu_rx: for locking sections in aggregation Rx flow 132 * @ampdu_rx: for locking sections in aggregation Rx flow
133 * @tid_state_tx: TID's state in Tx session state machine.
134 * @tid_tx: aggregation info for Tx per TID
135 * @addba_req_num: number of times addBA request has been sent.
138 * @ampdu_tx: for locking sectionsi in aggregation Tx flow 136 * @ampdu_tx: for locking sectionsi in aggregation Tx flow
139 * @dialog_token_allocator: dialog token enumerator for each new session; 137 * @dialog_token_allocator: dialog token enumerator for each new session;
140 */ 138 */
141struct sta_ampdu_mlme { 139struct sta_ampdu_mlme {
142 struct tid_ampdu_rx tid_rx[STA_TID_NUM]; 140 /* rx */
143 struct tid_ampdu_tx tid_tx[STA_TID_NUM]; 141 u8 tid_state_rx[STA_TID_NUM];
142 struct tid_ampdu_rx *tid_rx[STA_TID_NUM];
144 spinlock_t ampdu_rx; 143 spinlock_t ampdu_rx;
144 /* tx */
145 u8 tid_state_tx[STA_TID_NUM];
146 struct tid_ampdu_tx *tid_tx[STA_TID_NUM];
147 u8 addba_req_num[STA_TID_NUM];
145 spinlock_t ampdu_tx; 148 spinlock_t ampdu_tx;
146 u8 dialog_token_allocator; 149 u8 dialog_token_allocator;
147}; 150};