Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
ht.c
Go to the documentation of this file.
1 /*
2  * HT handling
3  *
4  * Copyright 2003, Jouni Malinen <[email protected]>
5  * Copyright 2002-2005, Instant802 Networks, Inc.
6  * Copyright 2005-2006, Devicescape Software, Inc.
7  * Copyright 2006-2007 Jiri Benc <[email protected]>
8  * Copyright 2007, Michael Wu <[email protected]>
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/export.h>
18 #include <net/mac80211.h>
19 #include "ieee80211_i.h"
20 #include "rate.h"
21 
22 static void __check_htcap_disable(struct ieee80211_sub_if_data *sdata,
23  struct ieee80211_sta_ht_cap *ht_cap,
24  u16 flag)
25 {
26  __le16 le_flag = cpu_to_le16(flag);
27  if (sdata->u.mgd.ht_capa_mask.cap_info & le_flag) {
28  if (!(sdata->u.mgd.ht_capa.cap_info & le_flag))
29  ht_cap->cap &= ~flag;
30  }
31 }
32 
34  struct ieee80211_sta_ht_cap *ht_cap)
35 {
36  u8 *scaps = (u8 *)(&sdata->u.mgd.ht_capa.mcs.rx_mask);
37  u8 *smask = (u8 *)(&sdata->u.mgd.ht_capa_mask.mcs.rx_mask);
38  int i;
39 
40  if (sdata->vif.type != NL80211_IFTYPE_STATION) {
41  /* AP interfaces call this code when adding new stations,
42  * so just silently ignore non station interfaces.
43  */
44  return;
45  }
46 
47  /* NOTE: If you add more over-rides here, update register_hw
48  * ht_capa_mod_msk logic in main.c as well.
49  * And, if this method can ever change ht_cap.ht_supported, fix
50  * the check in ieee80211_add_ht_ie.
51  */
52 
53  /* check for HT over-rides, MCS rates first. */
54  for (i = 0; i < IEEE80211_HT_MCS_MASK_LEN; i++) {
55  u8 m = smask[i];
56  ht_cap->mcs.rx_mask[i] &= ~m; /* turn off all masked bits */
57  /* Add back rates that are supported */
58  ht_cap->mcs.rx_mask[i] |= (m & scaps[i]);
59  }
60 
61  /* Force removal of HT-40 capabilities? */
62  __check_htcap_disable(sdata, ht_cap, IEEE80211_HT_CAP_SUP_WIDTH_20_40);
63  __check_htcap_disable(sdata, ht_cap, IEEE80211_HT_CAP_SGI_40);
64 
65  /* Allow user to disable the max-AMSDU bit. */
66  __check_htcap_disable(sdata, ht_cap, IEEE80211_HT_CAP_MAX_AMSDU);
67 
68  /* Allow user to decrease AMPDU factor */
69  if (sdata->u.mgd.ht_capa_mask.ampdu_params_info &
71  u8 n = sdata->u.mgd.ht_capa.ampdu_params_info
73  if (n < ht_cap->ampdu_factor)
74  ht_cap->ampdu_factor = n;
75  }
76 
77  /* Allow the user to increase AMPDU density. */
78  if (sdata->u.mgd.ht_capa_mask.ampdu_params_info &
80  u8 n = (sdata->u.mgd.ht_capa.ampdu_params_info &
83  if (n > ht_cap->ampdu_density)
84  ht_cap->ampdu_density = n;
85  }
86 }
87 
88 
90  struct ieee80211_supported_band *sband,
91  struct ieee80211_ht_cap *ht_cap_ie,
92  struct ieee80211_sta_ht_cap *ht_cap)
93 {
94  u8 ampdu_info, tx_mcs_set_cap;
95  int i, max_tx_streams;
96 
97  BUG_ON(!ht_cap);
98 
99  memset(ht_cap, 0, sizeof(*ht_cap));
100 
101  if (!ht_cap_ie || !sband->ht_cap.ht_supported)
102  return;
103 
104  ht_cap->ht_supported = true;
105 
106  /*
107  * The bits listed in this expression should be
108  * the same for the peer and us, if the station
109  * advertises more then we can't use those thus
110  * we mask them out.
111  */
112  ht_cap->cap = le16_to_cpu(ht_cap_ie->cap_info) &
113  (sband->ht_cap.cap |
120  /*
121  * The STBC bits are asymmetric -- if we don't have
122  * TX then mask out the peer's RX and vice versa.
123  */
124  if (!(sband->ht_cap.cap & IEEE80211_HT_CAP_TX_STBC))
125  ht_cap->cap &= ~IEEE80211_HT_CAP_RX_STBC;
126  if (!(sband->ht_cap.cap & IEEE80211_HT_CAP_RX_STBC))
127  ht_cap->cap &= ~IEEE80211_HT_CAP_TX_STBC;
128 
129  ampdu_info = ht_cap_ie->ampdu_params_info;
130  ht_cap->ampdu_factor =
131  ampdu_info & IEEE80211_HT_AMPDU_PARM_FACTOR;
132  ht_cap->ampdu_density =
133  (ampdu_info & IEEE80211_HT_AMPDU_PARM_DENSITY) >> 2;
134 
135  /* own MCS TX capabilities */
136  tx_mcs_set_cap = sband->ht_cap.mcs.tx_params;
137 
138  /* Copy peer MCS TX capabilities, the driver might need them. */
139  ht_cap->mcs.tx_params = ht_cap_ie->mcs.tx_params;
140 
141  /* can we TX with MCS rates? */
142  if (!(tx_mcs_set_cap & IEEE80211_HT_MCS_TX_DEFINED))
143  return;
144 
145  /* Counting from 0, therefore +1 */
146  if (tx_mcs_set_cap & IEEE80211_HT_MCS_TX_RX_DIFF)
147  max_tx_streams =
148  ((tx_mcs_set_cap & IEEE80211_HT_MCS_TX_MAX_STREAMS_MASK)
150  else
151  max_tx_streams = IEEE80211_HT_MCS_TX_MAX_STREAMS;
152 
153  /*
154  * 802.11n-2009 20.3.5 / 20.6 says:
155  * - indices 0 to 7 and 32 are single spatial stream
156  * - 8 to 31 are multiple spatial streams using equal modulation
157  * [8..15 for two streams, 16..23 for three and 24..31 for four]
158  * - remainder are multiple spatial streams using unequal modulation
159  */
160  for (i = 0; i < max_tx_streams; i++)
161  ht_cap->mcs.rx_mask[i] =
162  sband->ht_cap.mcs.rx_mask[i] & ht_cap_ie->mcs.rx_mask[i];
163 
164  if (tx_mcs_set_cap & IEEE80211_HT_MCS_TX_UNEQUAL_MODULATION)
166  i < IEEE80211_HT_MCS_MASK_LEN; i++)
167  ht_cap->mcs.rx_mask[i] =
168  sband->ht_cap.mcs.rx_mask[i] &
169  ht_cap_ie->mcs.rx_mask[i];
170 
171  /* handle MCS rate 32 too */
172  if (sband->ht_cap.mcs.rx_mask[32/8] & ht_cap_ie->mcs.rx_mask[32/8] & 1)
173  ht_cap->mcs.rx_mask[32/8] |= 1;
174 
175  /*
176  * If user has specified capability over-rides, take care
177  * of that here.
178  */
179  ieee80211_apply_htcap_overrides(sdata, ht_cap);
180 }
181 
183 {
184  int i;
185 
186  cancel_work_sync(&sta->ampdu_mlme.work);
187 
188  for (i = 0; i < STA_TID_NUM; i++) {
192  }
193 }
194 
196 {
197  struct sta_info *sta =
198  container_of(work, struct sta_info, ampdu_mlme.work);
199  struct tid_ampdu_tx *tid_tx;
200  int tid;
201 
202  /*
203  * When this flag is set, new sessions should be
204  * blocked, and existing sessions will be torn
205  * down by the code that set the flag, so this
206  * need not run.
207  */
208  if (test_sta_flag(sta, WLAN_STA_BLOCK_BA))
209  return;
210 
211  mutex_lock(&sta->ampdu_mlme.mtx);
212  for (tid = 0; tid < STA_TID_NUM; tid++) {
213  if (test_and_clear_bit(tid, sta->ampdu_mlme.tid_rx_timer_expired))
215  sta, tid, WLAN_BACK_RECIPIENT,
217 
218  if (test_and_clear_bit(tid,
219  sta->ampdu_mlme.tid_rx_stop_requested))
221  sta, tid, WLAN_BACK_RECIPIENT,
223 
224  tid_tx = sta->ampdu_mlme.tid_start_tx[tid];
225  if (tid_tx) {
226  /*
227  * Assign it over to the normal tid_tx array
228  * where it "goes live".
229  */
230  spin_lock_bh(&sta->lock);
231 
232  sta->ampdu_mlme.tid_start_tx[tid] = NULL;
233  /* could there be a race? */
234  if (sta->ampdu_mlme.tid_tx[tid])
235  kfree(tid_tx);
236  else
237  ieee80211_assign_tid_tx(sta, tid, tid_tx);
238  spin_unlock_bh(&sta->lock);
239 
241  continue;
242  }
243 
244  tid_tx = rcu_dereference_protected_tid_tx(sta, tid);
246  &tid_tx->state))
249  true);
250  }
251  mutex_unlock(&sta->ampdu_mlme.mtx);
252 }
253 
255  const u8 *da, u16 tid,
257 {
258  struct ieee80211_local *local = sdata->local;
259  struct sk_buff *skb;
260  struct ieee80211_mgmt *mgmt;
261  u16 params;
262 
263  skb = dev_alloc_skb(sizeof(*mgmt) + local->hw.extra_tx_headroom);
264  if (!skb)
265  return;
266 
267  skb_reserve(skb, local->hw.extra_tx_headroom);
268  mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24);
269  memset(mgmt, 0, 24);
270  memcpy(mgmt->da, da, ETH_ALEN);
271  memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN);
272  if (sdata->vif.type == NL80211_IFTYPE_AP ||
273  sdata->vif.type == NL80211_IFTYPE_AP_VLAN ||
274  sdata->vif.type == NL80211_IFTYPE_MESH_POINT)
275  memcpy(mgmt->bssid, sdata->vif.addr, ETH_ALEN);
276  else if (sdata->vif.type == NL80211_IFTYPE_STATION)
277  memcpy(mgmt->bssid, sdata->u.mgd.bssid, ETH_ALEN);
278  else if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
279  memcpy(mgmt->bssid, sdata->u.ibss.bssid, ETH_ALEN);
280 
283 
284  skb_put(skb, 1 + sizeof(mgmt->u.action.u.delba));
285 
286  mgmt->u.action.category = WLAN_CATEGORY_BACK;
287  mgmt->u.action.u.delba.action_code = WLAN_ACTION_DELBA;
288  params = (u16)(initiator << 11); /* bit 11 initiator */
289  params |= (u16)(tid << 12); /* bit 15:12 TID number */
290 
291  mgmt->u.action.u.delba.params = cpu_to_le16(params);
292  mgmt->u.action.u.delba.reason_code = cpu_to_le16(reason_code);
293 
294  ieee80211_tx_skb_tid(sdata, skb, tid);
295 }
296 
298  struct sta_info *sta,
299  struct ieee80211_mgmt *mgmt, size_t len)
300 {
301  u16 tid, params;
302  u16 initiator;
303 
304  params = le16_to_cpu(mgmt->u.action.u.delba.params);
305  tid = (params & IEEE80211_DELBA_PARAM_TID_MASK) >> 12;
306  initiator = (params & IEEE80211_DELBA_PARAM_INITIATOR_MASK) >> 11;
307 
308  ht_dbg_ratelimited(sdata, "delba from %pM (%s) tid %d reason code %d\n",
309  mgmt->sa, initiator ? "initiator" : "recipient",
310  tid,
311  le16_to_cpu(mgmt->u.action.u.delba.reason_code));
312 
313  if (initiator == WLAN_BACK_INITIATOR)
315  true);
316  else
318  true);
319 }
320 
322  enum ieee80211_smps_mode smps, const u8 *da,
323  const u8 *bssid)
324 {
325  struct ieee80211_local *local = sdata->local;
326  struct sk_buff *skb;
327  struct ieee80211_mgmt *action_frame;
328 
329  /* 27 = header + category + action + smps mode */
330  skb = dev_alloc_skb(27 + local->hw.extra_tx_headroom);
331  if (!skb)
332  return -ENOMEM;
333 
334  skb_reserve(skb, local->hw.extra_tx_headroom);
335  action_frame = (void *)skb_put(skb, 27);
336  memcpy(action_frame->da, da, ETH_ALEN);
337  memcpy(action_frame->sa, sdata->dev->dev_addr, ETH_ALEN);
338  memcpy(action_frame->bssid, bssid, ETH_ALEN);
341  action_frame->u.action.category = WLAN_CATEGORY_HT;
342  action_frame->u.action.u.ht_smps.action = WLAN_HT_ACTION_SMPS;
343  switch (smps) {
346  WARN_ON(1);
347  case IEEE80211_SMPS_OFF:
348  action_frame->u.action.u.ht_smps.smps_control =
350  break;
352  action_frame->u.action.u.ht_smps.smps_control =
354  break;
356  action_frame->u.action.u.ht_smps.smps_control =
358  break;
359  }
360 
361  /* we'll do more on status of this frame */
362  IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_CTL_REQ_TX_STATUS;
363  ieee80211_tx_skb(sdata, skb);
364 
365  return 0;
366 }
367 
369 {
370  struct ieee80211_sub_if_data *sdata =
371  container_of(work, struct ieee80211_sub_if_data,
372  u.mgd.request_smps_work);
373 
374  mutex_lock(&sdata->u.mgd.mtx);
375  __ieee80211_request_smps(sdata, sdata->u.mgd.driver_smps_mode);
376  mutex_unlock(&sdata->u.mgd.mtx);
377 }
378 
380  enum ieee80211_smps_mode smps_mode)
381 {
382  struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
383 
384  if (WARN_ON(vif->type != NL80211_IFTYPE_STATION))
385  return;
386 
387  if (WARN_ON(smps_mode == IEEE80211_SMPS_OFF))
388  smps_mode = IEEE80211_SMPS_AUTOMATIC;
389 
390  sdata->u.mgd.driver_smps_mode = smps_mode;
391 
392  ieee80211_queue_work(&sdata->local->hw,
393  &sdata->u.mgd.request_smps_work);
394 }
395 /* this might change ... don't want non-open drivers using it */