aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2009-12-25 19:34:56 -0500
committerDavid S. Miller <davem@davemloft.net>2009-12-25 19:34:56 -0500
commitd346f49d0badd80aa9fc699fa9c6d5b23e778eb6 (patch)
tree9e9698ffe7966fbe7ce924a30843f87cdfa2646e
parentd87fd25d5ac4cd044e21b749a8f6cac90f093c71 (diff)
parentb6ce5c33001b1dc83e6a1a6f30c5dccccea651b6 (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6
-rw-r--r--Documentation/networking/regulatory.txt24
-rw-r--r--drivers/net/wireless/ath/ar9170/ar9170.h9
-rw-r--r--drivers/net/wireless/ath/ar9170/hw.h1
-rw-r--r--drivers/net/wireless/ath/ar9170/mac.c2
-rw-r--r--drivers/net/wireless/ath/ar9170/main.c102
-rw-r--r--drivers/net/wireless/ath/ar9170/usb.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/ath9k.h1
-rw-r--r--drivers/net/wireless/ath/ath9k/debug.c38
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.c40
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.h2
-rw-r--r--drivers/net/wireless/ath/ath9k/main.c21
-rw-r--r--drivers/net/wireless/ath/ath9k/rc.h4
-rw-r--r--drivers/net/wireless/hostap/hostap_hw.c9
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-1000.c4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945.h3
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965.c3
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-5000.c10
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-6000.c8
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.c251
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-calib.c7
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-commands.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.c128
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.h10
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-debug.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-debugfs.c105
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-dev.h30
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-devtrace.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-devtrace.h44
-rw-r--r--drivers/net/wireless/iwlwifi/iwl3945-base.c101
-rw-r--r--drivers/net/wireless/iwmc3200wifi/rx.c71
-rw-r--r--drivers/net/wireless/libertas/Kconfig6
-rw-r--r--drivers/net/wireless/libertas/Makefile2
-rw-r--r--drivers/net/wireless/libertas/assoc.c17
-rw-r--r--drivers/net/wireless/libertas/cmd.c22
-rw-r--r--drivers/net/wireless/libertas/cmd.h12
-rw-r--r--drivers/net/wireless/libertas/cmdresp.c16
-rw-r--r--drivers/net/wireless/libertas/defs.h7
-rw-r--r--drivers/net/wireless/libertas/dev.h7
-rw-r--r--drivers/net/wireless/libertas/ethtool.c2
-rw-r--r--drivers/net/wireless/libertas/main.c42
-rw-r--r--drivers/net/wireless/libertas/mesh.c29
-rw-r--r--drivers/net/wireless/libertas/mesh.h32
-rw-r--r--drivers/net/wireless/libertas/scan.c2
-rw-r--r--drivers/net/wireless/libertas/tx.c2
-rw-r--r--drivers/net/wireless/libertas/wext.c26
-rw-r--r--drivers/net/wireless/mac80211_hwsim.c85
-rw-r--r--drivers/net/wireless/rndis_wlan.c42
-rw-r--r--drivers/net/wireless/rt2x00/rt2800pci.c6
-rw-r--r--drivers/net/wireless/rt2x00/rt2800usb.c45
-rw-r--r--drivers/net/wireless/rt2x00/rt2800usb.h90
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00.h6
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00dev.c10
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00pci.c3
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00queue.c79
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00queue.h5
-rw-r--r--drivers/net/wireless/rt2x00/rt73usb.c1
-rw-r--r--drivers/net/wireless/rtl818x/rtl8180_dev.c1
-rw-r--r--drivers/net/wireless/wl12xx/wl1251.h1
-rw-r--r--drivers/net/wireless/wl12xx/wl1251_acx.c69
-rw-r--r--drivers/net/wireless/wl12xx/wl1251_acx.h87
-rw-r--r--drivers/net/wireless/wl12xx/wl1251_debugfs.c23
-rw-r--r--drivers/net/wireless/wl12xx/wl1251_init.c5
-rw-r--r--drivers/net/wireless/wl12xx/wl1251_init.h47
-rw-r--r--drivers/net/wireless/wl12xx/wl1251_main.c50
-rw-r--r--drivers/net/wireless/wl12xx/wl1251_ps.c9
-rw-r--r--drivers/net/wireless/wl12xx/wl1251_rx.c2
-rw-r--r--drivers/net/wireless/wl12xx/wl1251_tx.c9
-rw-r--r--drivers/net/wireless/wl12xx/wl1251_tx.h17
-rw-r--r--drivers/net/wireless/zd1211rw/zd_usb.c14
-rw-r--r--include/linux/ieee80211.h30
-rw-r--r--include/net/cfg80211.h22
-rw-r--r--include/net/mac80211.h61
-rw-r--r--net/mac80211/Kconfig12
-rw-r--r--net/mac80211/agg-rx.c15
-rw-r--r--net/mac80211/agg-tx.c25
-rw-r--r--net/mac80211/cfg.c112
-rw-r--r--net/mac80211/debugfs_key.c2
-rw-r--r--net/mac80211/debugfs_netdev.c166
-rw-r--r--net/mac80211/debugfs_netdev.h9
-rw-r--r--net/mac80211/debugfs_sta.c64
-rw-r--r--net/mac80211/driver-ops.h29
-rw-r--r--net/mac80211/driver-trace.h42
-rw-r--r--net/mac80211/ht.c53
-rw-r--r--net/mac80211/ibss.c34
-rw-r--r--net/mac80211/ieee80211_i.h21
-rw-r--r--net/mac80211/iface.c62
-rw-r--r--net/mac80211/key.c6
-rw-r--r--net/mac80211/key.h8
-rw-r--r--net/mac80211/main.c50
-rw-r--r--net/mac80211/mesh.c4
-rw-r--r--net/mac80211/mesh_hwmp.c20
-rw-r--r--net/mac80211/mesh_pathtbl.c6
-rw-r--r--net/mac80211/mesh_plink.c6
-rw-r--r--net/mac80211/mlme.c192
-rw-r--r--net/mac80211/pm.c4
-rw-r--r--net/mac80211/rx.c295
-rw-r--r--net/mac80211/scan.c2
-rw-r--r--net/mac80211/spectmgmt.c4
-rw-r--r--net/mac80211/sta_info.c32
-rw-r--r--net/mac80211/sta_info.h29
-rw-r--r--net/mac80211/status.c46
-rw-r--r--net/mac80211/tkip.c38
-rw-r--r--net/mac80211/tx.c42
-rw-r--r--net/mac80211/util.c104
-rw-r--r--net/wireless/.gitignore1
-rw-r--r--net/wireless/Kconfig16
-rw-r--r--net/wireless/Makefile6
-rw-r--r--net/wireless/core.h2
-rw-r--r--net/wireless/db.txt17
-rw-r--r--net/wireless/genregdb.awk118
-rw-r--r--net/wireless/mlme.c11
-rw-r--r--net/wireless/nl80211.c37
-rw-r--r--net/wireless/reg.c120
-rw-r--r--net/wireless/regdb.h7
-rw-r--r--net/wireless/util.c132
-rw-r--r--net/wireless/wext-compat.c5
117 files changed, 2965 insertions, 1122 deletions
diff --git a/Documentation/networking/regulatory.txt b/Documentation/networking/regulatory.txt
index ee31369e9e5b..9551622d0a7b 100644
--- a/Documentation/networking/regulatory.txt
+++ b/Documentation/networking/regulatory.txt
@@ -188,3 +188,27 @@ Then in some part of your code after your wiphy has been registered:
188 &mydriver_jp_regdom.reg_rules[i], 188 &mydriver_jp_regdom.reg_rules[i],
189 sizeof(struct ieee80211_reg_rule)); 189 sizeof(struct ieee80211_reg_rule));
190 regulatory_struct_hint(rd); 190 regulatory_struct_hint(rd);
191
192Statically compiled regulatory database
193---------------------------------------
194
195In most situations the userland solution using CRDA as described
196above is the preferred solution. However in some cases a set of
197rules built into the kernel itself may be desirable. To account
198for this situation, a configuration option has been provided
199(i.e. CONFIG_CFG80211_INTERNAL_REGDB). With this option enabled,
200the wireless database information contained in net/wireless/db.txt is
201used to generate a data structure encoded in net/wireless/regdb.c.
202That option also enables code in net/wireless/reg.c which queries
203the data in regdb.c as an alternative to using CRDA.
204
205The file net/wireless/db.txt should be kept up-to-date with the db.txt
206file available in the git repository here:
207
208 git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-regdb.git
209
210Again, most users in most situations should be using the CRDA package
211provided with their distribution, and in most other situations users
212should be building and using CRDA on their own rather than using
213this option. If you are not absolutely sure that you should be using
214CONFIG_CFG80211_INTERNAL_REGDB then _DO_NOT_USE_IT_.
diff --git a/drivers/net/wireless/ath/ar9170/ar9170.h b/drivers/net/wireless/ath/ar9170/ar9170.h
index 9f9459860d82..b99a8c2053d8 100644
--- a/drivers/net/wireless/ath/ar9170/ar9170.h
+++ b/drivers/net/wireless/ath/ar9170/ar9170.h
@@ -109,7 +109,6 @@ struct ar9170_rxstream_mpdu_merge {
109 bool has_plcp; 109 bool has_plcp;
110}; 110};
111 111
112#define AR9170_NUM_MAX_BA_RETRY 5
113#define AR9170_NUM_TID 16 112#define AR9170_NUM_TID 16
114#define WME_BA_BMP_SIZE 64 113#define WME_BA_BMP_SIZE 64
115#define AR9170_NUM_MAX_AGG_LEN (2 * WME_BA_BMP_SIZE) 114#define AR9170_NUM_MAX_AGG_LEN (2 * WME_BA_BMP_SIZE)
@@ -143,7 +142,6 @@ struct ar9170_sta_tid {
143 u16 tid; 142 u16 tid;
144 enum ar9170_tid_state state; 143 enum ar9170_tid_state state;
145 bool active; 144 bool active;
146 u8 retry;
147}; 145};
148 146
149#define AR9170_QUEUE_TIMEOUT 64 147#define AR9170_QUEUE_TIMEOUT 64
@@ -154,6 +152,8 @@ struct ar9170_sta_tid {
154 152
155#define AR9170_NUM_TX_STATUS 128 153#define AR9170_NUM_TX_STATUS 128
156#define AR9170_NUM_TX_AGG_MAX 30 154#define AR9170_NUM_TX_AGG_MAX 30
155#define AR9170_NUM_TX_LIMIT_HARD AR9170_TXQ_DEPTH
156#define AR9170_NUM_TX_LIMIT_SOFT (AR9170_TXQ_DEPTH - 10)
157 157
158struct ar9170 { 158struct ar9170 {
159 struct ieee80211_hw *hw; 159 struct ieee80211_hw *hw;
@@ -248,13 +248,8 @@ struct ar9170_sta_info {
248 unsigned int ampdu_max_len; 248 unsigned int ampdu_max_len;
249}; 249};
250 250
251#define AR9170_TX_FLAG_WAIT_FOR_ACK BIT(0)
252#define AR9170_TX_FLAG_NO_ACK BIT(1)
253#define AR9170_TX_FLAG_BLOCK_ACK BIT(2)
254
255struct ar9170_tx_info { 251struct ar9170_tx_info {
256 unsigned long timeout; 252 unsigned long timeout;
257 unsigned int flags;
258}; 253};
259 254
260#define IS_STARTED(a) (((struct ar9170 *)a)->state >= AR9170_STARTED) 255#define IS_STARTED(a) (((struct ar9170 *)a)->state >= AR9170_STARTED)
diff --git a/drivers/net/wireless/ath/ar9170/hw.h b/drivers/net/wireless/ath/ar9170/hw.h
index 701ddb7d8400..0a1d4c28e68a 100644
--- a/drivers/net/wireless/ath/ar9170/hw.h
+++ b/drivers/net/wireless/ath/ar9170/hw.h
@@ -276,6 +276,7 @@ struct ar9170_tx_control {
276#define AR9170_TX_MAC_RATE_PROBE 0x8000 276#define AR9170_TX_MAC_RATE_PROBE 0x8000
277 277
278/* either-or */ 278/* either-or */
279#define AR9170_TX_PHY_MOD_MASK 0x00000003
279#define AR9170_TX_PHY_MOD_CCK 0x00000000 280#define AR9170_TX_PHY_MOD_CCK 0x00000000
280#define AR9170_TX_PHY_MOD_OFDM 0x00000001 281#define AR9170_TX_PHY_MOD_OFDM 0x00000001
281#define AR9170_TX_PHY_MOD_HT 0x00000002 282#define AR9170_TX_PHY_MOD_HT 0x00000002
diff --git a/drivers/net/wireless/ath/ar9170/mac.c b/drivers/net/wireless/ath/ar9170/mac.c
index ddc8c09dc79e..857e86104295 100644
--- a/drivers/net/wireless/ath/ar9170/mac.c
+++ b/drivers/net/wireless/ath/ar9170/mac.c
@@ -117,7 +117,7 @@ int ar9170_set_qos(struct ar9170 *ar)
117 ar9170_regwrite(AR9170_MAC_REG_AC1_AC0_TXOP, 117 ar9170_regwrite(AR9170_MAC_REG_AC1_AC0_TXOP,
118 ar->edcf[0].txop | ar->edcf[1].txop << 16); 118 ar->edcf[0].txop | ar->edcf[1].txop << 16);
119 ar9170_regwrite(AR9170_MAC_REG_AC3_AC2_TXOP, 119 ar9170_regwrite(AR9170_MAC_REG_AC3_AC2_TXOP,
120 ar->edcf[1].txop | ar->edcf[3].txop << 16); 120 ar->edcf[2].txop | ar->edcf[3].txop << 16);
121 121
122 ar9170_regwrite_finish(); 122 ar9170_regwrite_finish();
123 123
diff --git a/drivers/net/wireless/ath/ar9170/main.c b/drivers/net/wireless/ath/ar9170/main.c
index f9d6db8d013e..20f04ab2b13e 100644
--- a/drivers/net/wireless/ath/ar9170/main.c
+++ b/drivers/net/wireless/ath/ar9170/main.c
@@ -194,12 +194,15 @@ static inline u16 ar9170_get_seq(struct sk_buff *skb)
194 return ar9170_get_seq_h((void *) txc->frame_data); 194 return ar9170_get_seq_h((void *) txc->frame_data);
195} 195}
196 196
197static inline u16 ar9170_get_tid_h(struct ieee80211_hdr *hdr)
198{
199 return (ieee80211_get_qos_ctl(hdr))[0] & IEEE80211_QOS_CTL_TID_MASK;
200}
201
197static inline u16 ar9170_get_tid(struct sk_buff *skb) 202static inline u16 ar9170_get_tid(struct sk_buff *skb)
198{ 203{
199 struct ar9170_tx_control *txc = (void *) skb->data; 204 struct ar9170_tx_control *txc = (void *) skb->data;
200 struct ieee80211_hdr *hdr = (void *) txc->frame_data; 205 return ar9170_get_tid_h((struct ieee80211_hdr *) txc->frame_data);
201
202 return (ieee80211_get_qos_ctl(hdr))[0] & IEEE80211_QOS_CTL_TID_MASK;
203} 206}
204 207
205#define GET_NEXT_SEQ(seq) ((seq + 1) & 0x0fff) 208#define GET_NEXT_SEQ(seq) ((seq + 1) & 0x0fff)
@@ -213,10 +216,10 @@ static void ar9170_print_txheader(struct ar9170 *ar, struct sk_buff *skb)
213 struct ar9170_tx_info *arinfo = (void *) txinfo->rate_driver_data; 216 struct ar9170_tx_info *arinfo = (void *) txinfo->rate_driver_data;
214 struct ieee80211_hdr *hdr = (void *) txc->frame_data; 217 struct ieee80211_hdr *hdr = (void *) txc->frame_data;
215 218
216 printk(KERN_DEBUG "%s: => FRAME [skb:%p, q:%d, DA:[%pM] flags:%x s:%d " 219 printk(KERN_DEBUG "%s: => FRAME [skb:%p, q:%d, DA:[%pM] s:%d "
217 "mac_ctrl:%04x, phy_ctrl:%08x, timeout:[%d ms]]\n", 220 "mac_ctrl:%04x, phy_ctrl:%08x, timeout:[%d ms]]\n",
218 wiphy_name(ar->hw->wiphy), skb, skb_get_queue_mapping(skb), 221 wiphy_name(ar->hw->wiphy), skb, skb_get_queue_mapping(skb),
219 ieee80211_get_DA(hdr), arinfo->flags, ar9170_get_seq_h(hdr), 222 ieee80211_get_DA(hdr), ar9170_get_seq_h(hdr),
220 le16_to_cpu(txc->mac_control), le32_to_cpu(txc->phy_control), 223 le16_to_cpu(txc->mac_control), le32_to_cpu(txc->phy_control),
221 jiffies_to_msecs(arinfo->timeout - jiffies)); 224 jiffies_to_msecs(arinfo->timeout - jiffies));
222} 225}
@@ -430,7 +433,7 @@ void ar9170_tx_callback(struct ar9170 *ar, struct sk_buff *skb)
430 spin_lock_irqsave(&ar->tx_stats_lock, flags); 433 spin_lock_irqsave(&ar->tx_stats_lock, flags);
431 ar->tx_stats[queue].len--; 434 ar->tx_stats[queue].len--;
432 435
433 if (skb_queue_empty(&ar->tx_pending[queue])) { 436 if (ar->tx_stats[queue].len < AR9170_NUM_TX_LIMIT_SOFT) {
434#ifdef AR9170_QUEUE_STOP_DEBUG 437#ifdef AR9170_QUEUE_STOP_DEBUG
435 printk(KERN_DEBUG "%s: wake queue %d\n", 438 printk(KERN_DEBUG "%s: wake queue %d\n",
436 wiphy_name(ar->hw->wiphy), queue); 439 wiphy_name(ar->hw->wiphy), queue);
@@ -440,22 +443,17 @@ void ar9170_tx_callback(struct ar9170 *ar, struct sk_buff *skb)
440 } 443 }
441 spin_unlock_irqrestore(&ar->tx_stats_lock, flags); 444 spin_unlock_irqrestore(&ar->tx_stats_lock, flags);
442 445
443 if (arinfo->flags & AR9170_TX_FLAG_BLOCK_ACK) { 446 if (info->flags & IEEE80211_TX_CTL_NO_ACK) {
444 ar9170_tx_ampdu_callback(ar, skb);
445 } else if (arinfo->flags & AR9170_TX_FLAG_WAIT_FOR_ACK) {
446 arinfo->timeout = jiffies +
447 msecs_to_jiffies(AR9170_TX_TIMEOUT);
448
449 skb_queue_tail(&ar->tx_status[queue], skb);
450 } else if (arinfo->flags & AR9170_TX_FLAG_NO_ACK) {
451 ar9170_tx_status(ar, skb, AR9170_TX_STATUS_FAILED); 447 ar9170_tx_status(ar, skb, AR9170_TX_STATUS_FAILED);
452 } else { 448 } else {
453#ifdef AR9170_QUEUE_DEBUG 449 if (info->flags & IEEE80211_TX_CTL_AMPDU) {
454 printk(KERN_DEBUG "%s: unsupported frame flags!\n", 450 ar9170_tx_ampdu_callback(ar, skb);
455 wiphy_name(ar->hw->wiphy)); 451 } else {
456 ar9170_print_txheader(ar, skb); 452 arinfo->timeout = jiffies +
457#endif /* AR9170_QUEUE_DEBUG */ 453 msecs_to_jiffies(AR9170_TX_TIMEOUT);
458 dev_kfree_skb_any(skb); 454
455 skb_queue_tail(&ar->tx_status[queue], skb);
456 }
459 } 457 }
460 458
461 if (!ar->tx_stats[queue].len && 459 if (!ar->tx_stats[queue].len &&
@@ -1407,17 +1405,6 @@ static int ar9170_tx_prepare(struct ar9170 *ar, struct sk_buff *skb)
1407 1405
1408 if (!(info->flags & IEEE80211_TX_CTL_NO_ACK) && 1406 if (!(info->flags & IEEE80211_TX_CTL_NO_ACK) &&
1409 (is_valid_ether_addr(ieee80211_get_DA(hdr)))) { 1407 (is_valid_ether_addr(ieee80211_get_DA(hdr)))) {
1410 if (info->flags & IEEE80211_TX_CTL_AMPDU) {
1411 if (unlikely(!info->control.sta))
1412 goto err_out;
1413
1414 txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_AGGR);
1415 arinfo->flags = AR9170_TX_FLAG_BLOCK_ACK;
1416
1417 goto out;
1418 }
1419
1420 txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_RATE_PROBE);
1421 /* 1408 /*
1422 * WARNING: 1409 * WARNING:
1423 * Putting the QoS queue bits into an unexplored territory is 1410 * Putting the QoS queue bits into an unexplored territory is
@@ -1431,12 +1418,17 @@ static int ar9170_tx_prepare(struct ar9170 *ar, struct sk_buff *skb)
1431 1418
1432 txc->phy_control |= 1419 txc->phy_control |=
1433 cpu_to_le32(queue << AR9170_TX_PHY_QOS_SHIFT); 1420 cpu_to_le32(queue << AR9170_TX_PHY_QOS_SHIFT);
1434 arinfo->flags = AR9170_TX_FLAG_WAIT_FOR_ACK; 1421
1435 } else { 1422 if (info->flags & IEEE80211_TX_CTL_AMPDU) {
1436 arinfo->flags = AR9170_TX_FLAG_NO_ACK; 1423 if (unlikely(!info->control.sta))
1424 goto err_out;
1425
1426 txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_AGGR);
1427 } else {
1428 txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_RATE_PROBE);
1429 }
1437 } 1430 }
1438 1431
1439out:
1440 return 0; 1432 return 0;
1441 1433
1442err_out: 1434err_out:
@@ -1671,8 +1663,7 @@ static bool ar9170_tx_ampdu(struct ar9170 *ar)
1671 * tell the FW/HW that this is the last frame, 1663 * tell the FW/HW that this is the last frame,
1672 * that way it will wait for the immediate block ack. 1664 * that way it will wait for the immediate block ack.
1673 */ 1665 */
1674 if (likely(skb_peek_tail(&agg))) 1666 ar9170_tx_indicate_immba(ar, skb_peek_tail(&agg));
1675 ar9170_tx_indicate_immba(ar, skb_peek_tail(&agg));
1676 1667
1677#ifdef AR9170_TXAGG_DEBUG 1668#ifdef AR9170_TXAGG_DEBUG
1678 printk(KERN_DEBUG "%s: generated A-MPDU looks like this:\n", 1669 printk(KERN_DEBUG "%s: generated A-MPDU looks like this:\n",
@@ -1716,6 +1707,21 @@ static void ar9170_tx(struct ar9170 *ar)
1716 1707
1717 for (i = 0; i < __AR9170_NUM_TXQ; i++) { 1708 for (i = 0; i < __AR9170_NUM_TXQ; i++) {
1718 spin_lock_irqsave(&ar->tx_stats_lock, flags); 1709 spin_lock_irqsave(&ar->tx_stats_lock, flags);
1710 frames = min(ar->tx_stats[i].limit - ar->tx_stats[i].len,
1711 skb_queue_len(&ar->tx_pending[i]));
1712
1713 if (remaining_space < frames) {
1714#ifdef AR9170_QUEUE_DEBUG
1715 printk(KERN_DEBUG "%s: tx quota reached queue:%d, "
1716 "remaining slots:%d, needed:%d\n",
1717 wiphy_name(ar->hw->wiphy), i, remaining_space,
1718 frames);
1719#endif /* AR9170_QUEUE_DEBUG */
1720 frames = remaining_space;
1721 }
1722
1723 ar->tx_stats[i].len += frames;
1724 ar->tx_stats[i].count += frames;
1719 if (ar->tx_stats[i].len >= ar->tx_stats[i].limit) { 1725 if (ar->tx_stats[i].len >= ar->tx_stats[i].limit) {
1720#ifdef AR9170_QUEUE_DEBUG 1726#ifdef AR9170_QUEUE_DEBUG
1721 printk(KERN_DEBUG "%s: queue %d full\n", 1727 printk(KERN_DEBUG "%s: queue %d full\n",
@@ -1733,25 +1739,8 @@ static void ar9170_tx(struct ar9170 *ar)
1733 __ar9170_dump_txstats(ar); 1739 __ar9170_dump_txstats(ar);
1734#endif /* AR9170_QUEUE_STOP_DEBUG */ 1740#endif /* AR9170_QUEUE_STOP_DEBUG */
1735 ieee80211_stop_queue(ar->hw, i); 1741 ieee80211_stop_queue(ar->hw, i);
1736 spin_unlock_irqrestore(&ar->tx_stats_lock, flags);
1737 continue;
1738 } 1742 }
1739 1743
1740 frames = min(ar->tx_stats[i].limit - ar->tx_stats[i].len,
1741 skb_queue_len(&ar->tx_pending[i]));
1742
1743 if (remaining_space < frames) {
1744#ifdef AR9170_QUEUE_DEBUG
1745 printk(KERN_DEBUG "%s: tx quota reached queue:%d, "
1746 "remaining slots:%d, needed:%d\n",
1747 wiphy_name(ar->hw->wiphy), i, remaining_space,
1748 frames);
1749#endif /* AR9170_QUEUE_DEBUG */
1750 frames = remaining_space;
1751 }
1752
1753 ar->tx_stats[i].len += frames;
1754 ar->tx_stats[i].count += frames;
1755 spin_unlock_irqrestore(&ar->tx_stats_lock, flags); 1744 spin_unlock_irqrestore(&ar->tx_stats_lock, flags);
1756 1745
1757 if (!frames) 1746 if (!frames)
@@ -1773,7 +1762,7 @@ static void ar9170_tx(struct ar9170 *ar)
1773 arinfo->timeout = jiffies + 1762 arinfo->timeout = jiffies +
1774 msecs_to_jiffies(AR9170_TX_TIMEOUT); 1763 msecs_to_jiffies(AR9170_TX_TIMEOUT);
1775 1764
1776 if (arinfo->flags == AR9170_TX_FLAG_BLOCK_ACK) 1765 if (info->flags & IEEE80211_TX_CTL_AMPDU)
1777 atomic_inc(&ar->tx_ampdu_pending); 1766 atomic_inc(&ar->tx_ampdu_pending);
1778 1767
1779#ifdef AR9170_QUEUE_DEBUG 1768#ifdef AR9170_QUEUE_DEBUG
@@ -1784,7 +1773,7 @@ static void ar9170_tx(struct ar9170 *ar)
1784 1773
1785 err = ar->tx(ar, skb); 1774 err = ar->tx(ar, skb);
1786 if (unlikely(err)) { 1775 if (unlikely(err)) {
1787 if (arinfo->flags == AR9170_TX_FLAG_BLOCK_ACK) 1776 if (info->flags & IEEE80211_TX_CTL_AMPDU)
1788 atomic_dec(&ar->tx_ampdu_pending); 1777 atomic_dec(&ar->tx_ampdu_pending);
1789 1778
1790 frames_failed++; 1779 frames_failed++;
@@ -2366,7 +2355,6 @@ static void ar9170_sta_notify(struct ieee80211_hw *hw,
2366 sta_info->agg[i].state = AR9170_TID_STATE_SHUTDOWN; 2355 sta_info->agg[i].state = AR9170_TID_STATE_SHUTDOWN;
2367 sta_info->agg[i].active = false; 2356 sta_info->agg[i].active = false;
2368 sta_info->agg[i].ssn = 0; 2357 sta_info->agg[i].ssn = 0;
2369 sta_info->agg[i].retry = 0;
2370 sta_info->agg[i].tid = i; 2358 sta_info->agg[i].tid = i;
2371 INIT_LIST_HEAD(&sta_info->agg[i].list); 2359 INIT_LIST_HEAD(&sta_info->agg[i].list);
2372 skb_queue_head_init(&sta_info->agg[i].queue); 2360 skb_queue_head_init(&sta_info->agg[i].queue);
diff --git a/drivers/net/wireless/ath/ar9170/usb.c b/drivers/net/wireless/ath/ar9170/usb.c
index e0799d924057..0f361186b78f 100644
--- a/drivers/net/wireless/ath/ar9170/usb.c
+++ b/drivers/net/wireless/ath/ar9170/usb.c
@@ -84,6 +84,8 @@ static struct usb_device_id ar9170_usb_ids[] = {
84 { USB_DEVICE(0x0cde, 0x0023) }, 84 { USB_DEVICE(0x0cde, 0x0023) },
85 /* Z-Com UB82 ABG */ 85 /* Z-Com UB82 ABG */
86 { USB_DEVICE(0x0cde, 0x0026) }, 86 { USB_DEVICE(0x0cde, 0x0026) },
87 /* Sphairon Homelink 1202 */
88 { USB_DEVICE(0x0cde, 0x0027) },
87 /* Arcadyan WN7512 */ 89 /* Arcadyan WN7512 */
88 { USB_DEVICE(0x083a, 0xf522) }, 90 { USB_DEVICE(0x083a, 0xf522) },
89 /* Planex GWUS300 */ 91 /* Planex GWUS300 */
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index e2cef2ff5d8f..9f1f523e02eb 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -453,7 +453,6 @@ struct ath_softc {
453 int irq; 453 int irq;
454 spinlock_t sc_resetlock; 454 spinlock_t sc_resetlock;
455 spinlock_t sc_serial_rw; 455 spinlock_t sc_serial_rw;
456 spinlock_t ani_lock;
457 spinlock_t sc_pm_lock; 456 spinlock_t sc_pm_lock;
458 struct mutex mutex; 457 struct mutex mutex;
459 458
diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c
index b66f72dbf7b9..592f1b70f55a 100644
--- a/drivers/net/wireless/ath/ath9k/debug.c
+++ b/drivers/net/wireless/ath/ath9k/debug.c
@@ -289,23 +289,49 @@ static ssize_t read_file_rcstat(struct file *file, char __user *user_buf,
289 if (sc->cur_rate_table == NULL) 289 if (sc->cur_rate_table == NULL)
290 return 0; 290 return 0;
291 291
292 max = 80 + sc->cur_rate_table->rate_cnt * 64; 292 max = 80 + sc->cur_rate_table->rate_cnt * 1024;
293 buf = kmalloc(max + 1, GFP_KERNEL); 293 buf = kmalloc(max + 1, GFP_KERNEL);
294 if (buf == NULL) 294 if (buf == NULL)
295 return 0; 295 return 0;
296 buf[max] = 0; 296 buf[max] = 0;
297 297
298 len += sprintf(buf, "%5s %15s %8s %9s %3s\n\n", "Rate", "Success", 298 len += sprintf(buf, "%6s %6s %6s "
299 "Retries", "XRetries", "PER"); 299 "%10s %10s %10s %10s\n",
300 "HT", "MCS", "Rate",
301 "Success", "Retries", "XRetries", "PER");
300 302
301 for (i = 0; i < sc->cur_rate_table->rate_cnt; i++) { 303 for (i = 0; i < sc->cur_rate_table->rate_cnt; i++) {
302 u32 ratekbps = sc->cur_rate_table->info[i].ratekbps; 304 u32 ratekbps = sc->cur_rate_table->info[i].ratekbps;
303 struct ath_rc_stats *stats = &sc->debug.stats.rcstats[i]; 305 struct ath_rc_stats *stats = &sc->debug.stats.rcstats[i];
306 char mcs[5];
307 char htmode[5];
308 int used_mcs = 0, used_htmode = 0;
309
310 if (WLAN_RC_PHY_HT(sc->cur_rate_table->info[i].phy)) {
311 used_mcs = snprintf(mcs, 5, "%d",
312 sc->cur_rate_table->info[i].ratecode);
313
314 if (WLAN_RC_PHY_40(sc->cur_rate_table->info[i].phy))
315 used_htmode = snprintf(htmode, 5, "HT40");
316 else if (WLAN_RC_PHY_20(sc->cur_rate_table->info[i].phy))
317 used_htmode = snprintf(htmode, 5, "HT20");
318 else
319 used_htmode = snprintf(htmode, 5, "????");
320 }
321
322 mcs[used_mcs] = '\0';
323 htmode[used_htmode] = '\0';
304 324
305 len += snprintf(buf + len, max - len, 325 len += snprintf(buf + len, max - len,
306 "%3u.%d: %8u %8u %8u %8u\n", ratekbps / 1000, 326 "%6s %6s %3u.%d: "
307 (ratekbps % 1000) / 100, stats->success, 327 "%10u %10u %10u %10u\n",
308 stats->retries, stats->xretries, 328 htmode,
329 mcs,
330 ratekbps / 1000,
331 (ratekbps % 1000) / 100,
332 stats->success,
333 stats->retries,
334 stats->xretries,
309 stats->per); 335 stats->per);
310 } 336 }
311 337
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 2ec61f08cfdb..9474f9f6d400 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -343,30 +343,6 @@ static bool ath9k_hw_chip_test(struct ath_hw *ah)
343 return true; 343 return true;
344} 344}
345 345
346static const char *ath9k_hw_devname(u16 devid)
347{
348 switch (devid) {
349 case AR5416_DEVID_PCI:
350 return "Atheros 5416";
351 case AR5416_DEVID_PCIE:
352 return "Atheros 5418";
353 case AR9160_DEVID_PCI:
354 return "Atheros 9160";
355 case AR5416_AR9100_DEVID:
356 return "Atheros 9100";
357 case AR9280_DEVID_PCI:
358 case AR9280_DEVID_PCIE:
359 return "Atheros 9280";
360 case AR9285_DEVID_PCIE:
361 return "Atheros 9285";
362 case AR5416_DEVID_AR9287_PCI:
363 case AR5416_DEVID_AR9287_PCIE:
364 return "Atheros 9287";
365 }
366
367 return NULL;
368}
369
370static void ath9k_hw_init_config(struct ath_hw *ah) 346static void ath9k_hw_init_config(struct ath_hw *ah)
371{ 347{
372 int i; 348 int i;
@@ -392,7 +368,7 @@ static void ath9k_hw_init_config(struct ath_hw *ah)
392 ah->config.spurchans[i][1] = AR_NO_SPUR; 368 ah->config.spurchans[i][1] = AR_NO_SPUR;
393 } 369 }
394 370
395 ah->config.intr_mitigation = true; 371 ah->config.rx_intr_mitigation = true;
396 372
397 /* 373 /*
398 * We need this for PCI devices only (Cardbus, PCI, miniPCI) 374 * We need this for PCI devices only (Cardbus, PCI, miniPCI)
@@ -1184,7 +1160,7 @@ static void ath9k_hw_init_interrupt_masks(struct ath_hw *ah,
1184 AR_IMR_RXORN | 1160 AR_IMR_RXORN |
1185 AR_IMR_BCNMISC; 1161 AR_IMR_BCNMISC;
1186 1162
1187 if (ah->config.intr_mitigation) 1163 if (ah->config.rx_intr_mitigation)
1188 ah->mask_reg |= AR_IMR_RXINTM | AR_IMR_RXMINTR; 1164 ah->mask_reg |= AR_IMR_RXINTM | AR_IMR_RXMINTR;
1189 else 1165 else
1190 ah->mask_reg |= AR_IMR_RXOK; 1166 ah->mask_reg |= AR_IMR_RXOK;
@@ -1266,12 +1242,6 @@ static void ath9k_hw_init_user_settings(struct ath_hw *ah)
1266 ath9k_hw_set_global_txtimeout(ah, ah->globaltxtimeout); 1242 ath9k_hw_set_global_txtimeout(ah, ah->globaltxtimeout);
1267} 1243}
1268 1244
1269const char *ath9k_hw_probe(u16 vendorid, u16 devid)
1270{
1271 return vendorid == ATHEROS_VENDOR_ID ?
1272 ath9k_hw_devname(devid) : NULL;
1273}
1274
1275void ath9k_hw_detach(struct ath_hw *ah) 1245void ath9k_hw_detach(struct ath_hw *ah)
1276{ 1246{
1277 struct ath_common *common = ath9k_hw_common(ah); 1247 struct ath_common *common = ath9k_hw_common(ah);
@@ -2121,7 +2091,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
2121 2091
2122 REG_WRITE(ah, AR_OBS, 8); 2092 REG_WRITE(ah, AR_OBS, 8);
2123 2093
2124 if (ah->config.intr_mitigation) { 2094 if (ah->config.rx_intr_mitigation) {
2125 REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_LAST, 500); 2095 REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_LAST, 500);
2126 REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_FIRST, 2000); 2096 REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_FIRST, 2000);
2127 } 2097 }
@@ -2781,7 +2751,7 @@ bool ath9k_hw_getisr(struct ath_hw *ah, enum ath9k_int *masked)
2781 2751
2782 *masked = isr & ATH9K_INT_COMMON; 2752 *masked = isr & ATH9K_INT_COMMON;
2783 2753
2784 if (ah->config.intr_mitigation) { 2754 if (ah->config.rx_intr_mitigation) {
2785 if (isr & (AR_ISR_RXMINTR | AR_ISR_RXINTM)) 2755 if (isr & (AR_ISR_RXMINTR | AR_ISR_RXINTM))
2786 *masked |= ATH9K_INT_RX; 2756 *masked |= ATH9K_INT_RX;
2787 } 2757 }
@@ -2914,7 +2884,7 @@ enum ath9k_int ath9k_hw_set_interrupts(struct ath_hw *ah, enum ath9k_int ints)
2914 } 2884 }
2915 if (ints & ATH9K_INT_RX) { 2885 if (ints & ATH9K_INT_RX) {
2916 mask |= AR_IMR_RXERR; 2886 mask |= AR_IMR_RXERR;
2917 if (ah->config.intr_mitigation) 2887 if (ah->config.rx_intr_mitigation)
2918 mask |= AR_IMR_RXMINTR | AR_IMR_RXINTM; 2888 mask |= AR_IMR_RXMINTR | AR_IMR_RXINTM;
2919 else 2889 else
2920 mask |= AR_IMR_RXOK | AR_IMR_RXDESC; 2890 mask |= AR_IMR_RXOK | AR_IMR_RXDESC;
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index e2b0c73a616f..8849450dc591 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -212,7 +212,7 @@ struct ath9k_ops_config {
212 u32 cck_trig_low; 212 u32 cck_trig_low;
213 u32 enable_ani; 213 u32 enable_ani;
214 int serialize_regmode; 214 int serialize_regmode;
215 bool intr_mitigation; 215 bool rx_intr_mitigation;
216#define SPUR_DISABLE 0 216#define SPUR_DISABLE 0
217#define SPUR_ENABLE_IOCTL 1 217#define SPUR_ENABLE_IOCTL 1
218#define SPUR_ENABLE_EEPROM 2 218#define SPUR_ENABLE_EEPROM 2
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 9e68c1a8aef0..3f5b887d0fcd 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -363,14 +363,6 @@ static void ath_ani_calibrate(unsigned long data)
363 short_cal_interval = (ah->opmode == NL80211_IFTYPE_AP) ? 363 short_cal_interval = (ah->opmode == NL80211_IFTYPE_AP) ?
364 ATH_AP_SHORT_CALINTERVAL : ATH_STA_SHORT_CALINTERVAL; 364 ATH_AP_SHORT_CALINTERVAL : ATH_STA_SHORT_CALINTERVAL;
365 365
366 /*
367 * don't calibrate when we're scanning.
368 * we are most likely not on our home channel.
369 */
370 spin_lock(&sc->ani_lock);
371 if (sc->sc_flags & SC_OP_SCANNING)
372 goto set_timer;
373
374 /* Only calibrate if awake */ 366 /* Only calibrate if awake */
375 if (sc->sc_ah->power_mode != ATH9K_PM_AWAKE) 367 if (sc->sc_ah->power_mode != ATH9K_PM_AWAKE)
376 goto set_timer; 368 goto set_timer;
@@ -437,7 +429,6 @@ static void ath_ani_calibrate(unsigned long data)
437 ath9k_ps_restore(sc); 429 ath9k_ps_restore(sc);
438 430
439set_timer: 431set_timer:
440 spin_unlock(&sc->ani_lock);
441 /* 432 /*
442 * Set timer interval based on previous results. 433 * Set timer interval based on previous results.
443 * The interval must be the shortest necessary to satisfy ANI, 434 * The interval must be the shortest necessary to satisfy ANI,
@@ -1610,7 +1601,6 @@ static int ath_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid,
1610 spin_lock_init(&sc->wiphy_lock); 1601 spin_lock_init(&sc->wiphy_lock);
1611 spin_lock_init(&sc->sc_resetlock); 1602 spin_lock_init(&sc->sc_resetlock);
1612 spin_lock_init(&sc->sc_serial_rw); 1603 spin_lock_init(&sc->sc_serial_rw);
1613 spin_lock_init(&sc->ani_lock);
1614 spin_lock_init(&sc->sc_pm_lock); 1604 spin_lock_init(&sc->sc_pm_lock);
1615 mutex_init(&sc->mutex); 1605 mutex_init(&sc->mutex);
1616 tasklet_init(&sc->intr_tq, ath9k_tasklet, (unsigned long)sc); 1606 tasklet_init(&sc->intr_tq, ath9k_tasklet, (unsigned long)sc);
@@ -3119,6 +3109,7 @@ static void ath9k_sw_scan_start(struct ieee80211_hw *hw)
3119{ 3109{
3120 struct ath_wiphy *aphy = hw->priv; 3110 struct ath_wiphy *aphy = hw->priv;
3121 struct ath_softc *sc = aphy->sc; 3111 struct ath_softc *sc = aphy->sc;
3112 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
3122 3113
3123 mutex_lock(&sc->mutex); 3114 mutex_lock(&sc->mutex);
3124 if (ath9k_wiphy_scanning(sc)) { 3115 if (ath9k_wiphy_scanning(sc)) {
@@ -3134,10 +3125,9 @@ static void ath9k_sw_scan_start(struct ieee80211_hw *hw)
3134 3125
3135 aphy->state = ATH_WIPHY_SCAN; 3126 aphy->state = ATH_WIPHY_SCAN;
3136 ath9k_wiphy_pause_all_forced(sc, aphy); 3127 ath9k_wiphy_pause_all_forced(sc, aphy);
3137
3138 spin_lock_bh(&sc->ani_lock);
3139 sc->sc_flags |= SC_OP_SCANNING; 3128 sc->sc_flags |= SC_OP_SCANNING;
3140 spin_unlock_bh(&sc->ani_lock); 3129 del_timer_sync(&common->ani.timer);
3130 cancel_delayed_work_sync(&sc->tx_complete_work);
3141 mutex_unlock(&sc->mutex); 3131 mutex_unlock(&sc->mutex);
3142} 3132}
3143 3133
@@ -3145,13 +3135,14 @@ static void ath9k_sw_scan_complete(struct ieee80211_hw *hw)
3145{ 3135{
3146 struct ath_wiphy *aphy = hw->priv; 3136 struct ath_wiphy *aphy = hw->priv;
3147 struct ath_softc *sc = aphy->sc; 3137 struct ath_softc *sc = aphy->sc;
3138 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
3148 3139
3149 mutex_lock(&sc->mutex); 3140 mutex_lock(&sc->mutex);
3150 spin_lock_bh(&sc->ani_lock);
3151 aphy->state = ATH_WIPHY_ACTIVE; 3141 aphy->state = ATH_WIPHY_ACTIVE;
3152 sc->sc_flags &= ~SC_OP_SCANNING; 3142 sc->sc_flags &= ~SC_OP_SCANNING;
3153 sc->sc_flags |= SC_OP_FULL_RESET; 3143 sc->sc_flags |= SC_OP_FULL_RESET;
3154 spin_unlock_bh(&sc->ani_lock); 3144 ath_start_ani(common);
3145 ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, 0);
3155 ath_beacon_config(sc, NULL); 3146 ath_beacon_config(sc, NULL);
3156 mutex_unlock(&sc->mutex); 3147 mutex_unlock(&sc->mutex);
3157} 3148}
diff --git a/drivers/net/wireless/ath/ath9k/rc.h b/drivers/net/wireless/ath/ath9k/rc.h
index 9eb96f506998..4f6d6fd442f4 100644
--- a/drivers/net/wireless/ath/ath9k/rc.h
+++ b/drivers/net/wireless/ath/ath9k/rc.h
@@ -57,6 +57,10 @@ enum {
57 || (_phy == WLAN_RC_PHY_HT_40_DS) \ 57 || (_phy == WLAN_RC_PHY_HT_40_DS) \
58 || (_phy == WLAN_RC_PHY_HT_20_DS_HGI) \ 58 || (_phy == WLAN_RC_PHY_HT_20_DS_HGI) \
59 || (_phy == WLAN_RC_PHY_HT_40_DS_HGI)) 59 || (_phy == WLAN_RC_PHY_HT_40_DS_HGI))
60#define WLAN_RC_PHY_20(_phy) ((_phy == WLAN_RC_PHY_HT_20_SS) \
61 || (_phy == WLAN_RC_PHY_HT_20_DS) \
62 || (_phy == WLAN_RC_PHY_HT_20_SS_HGI) \
63 || (_phy == WLAN_RC_PHY_HT_20_DS_HGI))
60#define WLAN_RC_PHY_40(_phy) ((_phy == WLAN_RC_PHY_HT_40_SS) \ 64#define WLAN_RC_PHY_40(_phy) ((_phy == WLAN_RC_PHY_HT_40_SS) \
61 || (_phy == WLAN_RC_PHY_HT_40_DS) \ 65 || (_phy == WLAN_RC_PHY_HT_40_DS) \
62 || (_phy == WLAN_RC_PHY_HT_40_SS_HGI) \ 66 || (_phy == WLAN_RC_PHY_HT_40_SS_HGI) \
diff --git a/drivers/net/wireless/hostap/hostap_hw.c b/drivers/net/wireless/hostap/hostap_hw.c
index ff9b5c882184..d70732819423 100644
--- a/drivers/net/wireless/hostap/hostap_hw.c
+++ b/drivers/net/wireless/hostap/hostap_hw.c
@@ -2618,6 +2618,15 @@ static irqreturn_t prism2_interrupt(int irq, void *dev_id)
2618 int events = 0; 2618 int events = 0;
2619 u16 ev; 2619 u16 ev;
2620 2620
2621 /* Detect early interrupt before driver is fully configued */
2622 if (!dev->base_addr) {
2623 if (net_ratelimit()) {
2624 printk(KERN_DEBUG "%s: Interrupt, but dev not configured\n",
2625 dev->name);
2626 }
2627 return IRQ_HANDLED;
2628 }
2629
2621 iface = netdev_priv(dev); 2630 iface = netdev_priv(dev);
2622 local = iface->local; 2631 local = iface->local;
2623 2632
diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c
index 8414178bcff4..0db1fda94a65 100644
--- a/drivers/net/wireless/iwlwifi/iwl-1000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-1000.c
@@ -105,6 +105,7 @@ static struct iwl_lib_ops iwl1000_lib = {
105 .load_ucode = iwl5000_load_ucode, 105 .load_ucode = iwl5000_load_ucode,
106 .dump_nic_event_log = iwl_dump_nic_event_log, 106 .dump_nic_event_log = iwl_dump_nic_event_log,
107 .dump_nic_error_log = iwl_dump_nic_error_log, 107 .dump_nic_error_log = iwl_dump_nic_error_log,
108 .dump_csr = iwl_dump_csr,
108 .init_alive_start = iwl5000_init_alive_start, 109 .init_alive_start = iwl5000_init_alive_start,
109 .alive_notify = iwl5000_alive_notify, 110 .alive_notify = iwl5000_alive_notify,
110 .send_tx_power = iwl5000_send_tx_power, 111 .send_tx_power = iwl5000_send_tx_power,
@@ -140,7 +141,7 @@ static struct iwl_lib_ops iwl1000_lib = {
140 }, 141 },
141}; 142};
142 143
143static struct iwl_ops iwl1000_ops = { 144static const struct iwl_ops iwl1000_ops = {
144 .ucode = &iwl5000_ucode, 145 .ucode = &iwl5000_ucode,
145 .lib = &iwl1000_lib, 146 .lib = &iwl1000_lib,
146 .hcmd = &iwl5000_hcmd, 147 .hcmd = &iwl5000_hcmd,
@@ -173,7 +174,6 @@ struct iwl_cfg iwl1000_bgn_cfg = {
173 .use_rts_for_ht = true, /* use rts/cts protection */ 174 .use_rts_for_ht = true, /* use rts/cts protection */
174 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, 175 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
175 .support_ct_kill_exit = true, 176 .support_ct_kill_exit = true,
176 .sm_ps_mode = WLAN_HT_CAP_SM_PS_DISABLED,
177}; 177};
178 178
179struct iwl_cfg iwl1000_bg_cfg = { 179struct iwl_cfg iwl1000_bg_cfg = {
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c
index e413bd35bc41..d1bab141508a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.c
@@ -2810,7 +2810,7 @@ static struct iwl_hcmd_utils_ops iwl3945_hcmd_utils = {
2810 .rts_tx_cmd_flag = iwlcore_rts_tx_cmd_flag, 2810 .rts_tx_cmd_flag = iwlcore_rts_tx_cmd_flag,
2811}; 2811};
2812 2812
2813static struct iwl_ops iwl3945_ops = { 2813static const struct iwl_ops iwl3945_ops = {
2814 .ucode = &iwl3945_ucode, 2814 .ucode = &iwl3945_ucode,
2815 .lib = &iwl3945_lib, 2815 .lib = &iwl3945_lib,
2816 .hcmd = &iwl3945_hcmd, 2816 .hcmd = &iwl3945_hcmd,
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.h b/drivers/net/wireless/iwlwifi/iwl-3945.h
index ecc23ec1f6a4..28f6eb5f2cba 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.h
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.h
@@ -227,7 +227,8 @@ extern void iwl3945_rx_replenish(void *data);
227extern void iwl3945_rx_queue_reset(struct iwl_priv *priv, struct iwl_rx_queue *rxq); 227extern void iwl3945_rx_queue_reset(struct iwl_priv *priv, struct iwl_rx_queue *rxq);
228extern unsigned int iwl3945_fill_beacon_frame(struct iwl_priv *priv, 228extern unsigned int iwl3945_fill_beacon_frame(struct iwl_priv *priv,
229 struct ieee80211_hdr *hdr,int left); 229 struct ieee80211_hdr *hdr,int left);
230extern void iwl3945_dump_nic_event_log(struct iwl_priv *priv, bool full_log); 230extern int iwl3945_dump_nic_event_log(struct iwl_priv *priv, bool full_log,
231 char **buf, bool display);
231extern void iwl3945_dump_nic_error_log(struct iwl_priv *priv); 232extern void iwl3945_dump_nic_error_log(struct iwl_priv *priv);
232 233
233/* 234/*
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c
index 484c5fdf7c2a..78706ce8b7ae 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965.c
@@ -2208,7 +2208,7 @@ static struct iwl_lib_ops iwl4965_lib = {
2208 }, 2208 },
2209}; 2209};
2210 2210
2211static struct iwl_ops iwl4965_ops = { 2211static const struct iwl_ops iwl4965_ops = {
2212 .ucode = &iwl4965_ucode, 2212 .ucode = &iwl4965_ucode,
2213 .lib = &iwl4965_lib, 2213 .lib = &iwl4965_lib,
2214 .hcmd = &iwl4965_hcmd, 2214 .hcmd = &iwl4965_hcmd,
@@ -2239,7 +2239,6 @@ struct iwl_cfg iwl4965_agn_cfg = {
2239 .broken_powersave = true, 2239 .broken_powersave = true,
2240 .led_compensation = 61, 2240 .led_compensation = 61,
2241 .chain_noise_num_beacons = IWL4965_CAL_NUM_BEACONS, 2241 .chain_noise_num_beacons = IWL4965_CAL_NUM_BEACONS,
2242 .sm_ps_mode = WLAN_HT_CAP_SM_PS_DISABLED,
2243}; 2242};
2244 2243
2245/* Module firmware */ 2244/* Module firmware */
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c
index 33a5866538e7..ec6b27689fa8 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
@@ -1466,6 +1466,7 @@ struct iwl_lib_ops iwl5000_lib = {
1466 .is_valid_rtc_data_addr = iwl5000_hw_valid_rtc_data_addr, 1466 .is_valid_rtc_data_addr = iwl5000_hw_valid_rtc_data_addr,
1467 .dump_nic_event_log = iwl_dump_nic_event_log, 1467 .dump_nic_event_log = iwl_dump_nic_event_log,
1468 .dump_nic_error_log = iwl_dump_nic_error_log, 1468 .dump_nic_error_log = iwl_dump_nic_error_log,
1469 .dump_csr = iwl_dump_csr,
1469 .load_ucode = iwl5000_load_ucode, 1470 .load_ucode = iwl5000_load_ucode,
1470 .init_alive_start = iwl5000_init_alive_start, 1471 .init_alive_start = iwl5000_init_alive_start,
1471 .alive_notify = iwl5000_alive_notify, 1472 .alive_notify = iwl5000_alive_notify,
@@ -1518,6 +1519,7 @@ static struct iwl_lib_ops iwl5150_lib = {
1518 .is_valid_rtc_data_addr = iwl5000_hw_valid_rtc_data_addr, 1519 .is_valid_rtc_data_addr = iwl5000_hw_valid_rtc_data_addr,
1519 .dump_nic_event_log = iwl_dump_nic_event_log, 1520 .dump_nic_event_log = iwl_dump_nic_event_log,
1520 .dump_nic_error_log = iwl_dump_nic_error_log, 1521 .dump_nic_error_log = iwl_dump_nic_error_log,
1522 .dump_csr = iwl_dump_csr,
1521 .load_ucode = iwl5000_load_ucode, 1523 .load_ucode = iwl5000_load_ucode,
1522 .init_alive_start = iwl5000_init_alive_start, 1524 .init_alive_start = iwl5000_init_alive_start,
1523 .alive_notify = iwl5000_alive_notify, 1525 .alive_notify = iwl5000_alive_notify,
@@ -1555,7 +1557,7 @@ static struct iwl_lib_ops iwl5150_lib = {
1555 }, 1557 },
1556}; 1558};
1557 1559
1558static struct iwl_ops iwl5000_ops = { 1560static const struct iwl_ops iwl5000_ops = {
1559 .ucode = &iwl5000_ucode, 1561 .ucode = &iwl5000_ucode,
1560 .lib = &iwl5000_lib, 1562 .lib = &iwl5000_lib,
1561 .hcmd = &iwl5000_hcmd, 1563 .hcmd = &iwl5000_hcmd,
@@ -1563,7 +1565,7 @@ static struct iwl_ops iwl5000_ops = {
1563 .led = &iwlagn_led_ops, 1565 .led = &iwlagn_led_ops,
1564}; 1566};
1565 1567
1566static struct iwl_ops iwl5150_ops = { 1568static const struct iwl_ops iwl5150_ops = {
1567 .ucode = &iwl5000_ucode, 1569 .ucode = &iwl5000_ucode,
1568 .lib = &iwl5150_lib, 1570 .lib = &iwl5150_lib,
1569 .hcmd = &iwl5000_hcmd, 1571 .hcmd = &iwl5000_hcmd,
@@ -1599,7 +1601,6 @@ struct iwl_cfg iwl5300_agn_cfg = {
1599 .ht_greenfield_support = true, 1601 .ht_greenfield_support = true,
1600 .led_compensation = 51, 1602 .led_compensation = 51,
1601 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, 1603 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
1602 .sm_ps_mode = WLAN_HT_CAP_SM_PS_DISABLED,
1603}; 1604};
1604 1605
1605struct iwl_cfg iwl5100_bgn_cfg = { 1606struct iwl_cfg iwl5100_bgn_cfg = {
@@ -1668,7 +1669,6 @@ struct iwl_cfg iwl5100_agn_cfg = {
1668 .ht_greenfield_support = true, 1669 .ht_greenfield_support = true,
1669 .led_compensation = 51, 1670 .led_compensation = 51,
1670 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, 1671 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
1671 .sm_ps_mode = WLAN_HT_CAP_SM_PS_DISABLED,
1672}; 1672};
1673 1673
1674struct iwl_cfg iwl5350_agn_cfg = { 1674struct iwl_cfg iwl5350_agn_cfg = {
@@ -1692,7 +1692,6 @@ struct iwl_cfg iwl5350_agn_cfg = {
1692 .ht_greenfield_support = true, 1692 .ht_greenfield_support = true,
1693 .led_compensation = 51, 1693 .led_compensation = 51,
1694 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, 1694 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
1695 .sm_ps_mode = WLAN_HT_CAP_SM_PS_DISABLED,
1696}; 1695};
1697 1696
1698struct iwl_cfg iwl5150_agn_cfg = { 1697struct iwl_cfg iwl5150_agn_cfg = {
@@ -1716,7 +1715,6 @@ struct iwl_cfg iwl5150_agn_cfg = {
1716 .ht_greenfield_support = true, 1715 .ht_greenfield_support = true,
1717 .led_compensation = 51, 1716 .led_compensation = 51,
1718 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, 1717 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
1719 .sm_ps_mode = WLAN_HT_CAP_SM_PS_DISABLED,
1720}; 1718};
1721 1719
1722struct iwl_cfg iwl5150_abg_cfg = { 1720struct iwl_cfg iwl5150_abg_cfg = {
diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c
index 74e571049273..a5a0ed4817a4 100644
--- a/drivers/net/wireless/iwlwifi/iwl-6000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-6000.c
@@ -215,6 +215,7 @@ static struct iwl_lib_ops iwl6000_lib = {
215 .load_ucode = iwl5000_load_ucode, 215 .load_ucode = iwl5000_load_ucode,
216 .dump_nic_event_log = iwl_dump_nic_event_log, 216 .dump_nic_event_log = iwl_dump_nic_event_log,
217 .dump_nic_error_log = iwl_dump_nic_error_log, 217 .dump_nic_error_log = iwl_dump_nic_error_log,
218 .dump_csr = iwl_dump_csr,
218 .init_alive_start = iwl5000_init_alive_start, 219 .init_alive_start = iwl5000_init_alive_start,
219 .alive_notify = iwl5000_alive_notify, 220 .alive_notify = iwl5000_alive_notify,
220 .send_tx_power = iwl5000_send_tx_power, 221 .send_tx_power = iwl5000_send_tx_power,
@@ -252,7 +253,7 @@ static struct iwl_lib_ops iwl6000_lib = {
252 }, 253 },
253}; 254};
254 255
255static struct iwl_ops iwl6000_ops = { 256static const struct iwl_ops iwl6000_ops = {
256 .ucode = &iwl5000_ucode, 257 .ucode = &iwl5000_ucode,
257 .lib = &iwl6000_lib, 258 .lib = &iwl6000_lib,
258 .hcmd = &iwl5000_hcmd, 259 .hcmd = &iwl5000_hcmd,
@@ -267,7 +268,7 @@ static struct iwl_hcmd_utils_ops iwl6050_hcmd_utils = {
267 .calc_rssi = iwl5000_calc_rssi, 268 .calc_rssi = iwl5000_calc_rssi,
268}; 269};
269 270
270static struct iwl_ops iwl6050_ops = { 271static const struct iwl_ops iwl6050_ops = {
271 .ucode = &iwl5000_ucode, 272 .ucode = &iwl5000_ucode,
272 .lib = &iwl6000_lib, 273 .lib = &iwl6000_lib,
273 .hcmd = &iwl5000_hcmd, 274 .hcmd = &iwl5000_hcmd,
@@ -306,7 +307,6 @@ struct iwl_cfg iwl6000i_2agn_cfg = {
306 .supports_idle = true, 307 .supports_idle = true,
307 .adv_thermal_throttle = true, 308 .adv_thermal_throttle = true,
308 .support_ct_kill_exit = true, 309 .support_ct_kill_exit = true,
309 .sm_ps_mode = WLAN_HT_CAP_SM_PS_DISABLED,
310}; 310};
311 311
312struct iwl_cfg iwl6000i_2abg_cfg = { 312struct iwl_cfg iwl6000i_2abg_cfg = {
@@ -395,7 +395,6 @@ struct iwl_cfg iwl6050_2agn_cfg = {
395 .supports_idle = true, 395 .supports_idle = true,
396 .adv_thermal_throttle = true, 396 .adv_thermal_throttle = true,
397 .support_ct_kill_exit = true, 397 .support_ct_kill_exit = true,
398 .sm_ps_mode = WLAN_HT_CAP_SM_PS_DYNAMIC,
399}; 398};
400 399
401struct iwl_cfg iwl6050_2abg_cfg = { 400struct iwl_cfg iwl6050_2abg_cfg = {
@@ -455,7 +454,6 @@ struct iwl_cfg iwl6000_3agn_cfg = {
455 .supports_idle = true, 454 .supports_idle = true,
456 .adv_thermal_throttle = true, 455 .adv_thermal_throttle = true,
457 .support_ct_kill_exit = true, 456 .support_ct_kill_exit = true,
458 .sm_ps_mode = WLAN_HT_CAP_SM_PS_DISABLED,
459}; 457};
460 458
461MODULE_FIRMWARE(IWL6000_MODULE_FIRMWARE(IWL6000_UCODE_API_MAX)); 459MODULE_FIRMWARE(IWL6000_MODULE_FIRMWARE(IWL6000_UCODE_API_MAX));
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index 1c9866daf815..771b03c1c7c5 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -657,6 +657,131 @@ static void iwl_bg_statistics_periodic(unsigned long data)
657 iwl_send_statistics_request(priv, CMD_ASYNC, false); 657 iwl_send_statistics_request(priv, CMD_ASYNC, false);
658} 658}
659 659
660
661static void iwl_print_cont_event_trace(struct iwl_priv *priv, u32 base,
662 u32 start_idx, u32 num_events,
663 u32 mode)
664{
665 u32 i;
666 u32 ptr; /* SRAM byte address of log data */
667 u32 ev, time, data; /* event log data */
668 unsigned long reg_flags;
669
670 if (mode == 0)
671 ptr = base + (4 * sizeof(u32)) + (start_idx * 2 * sizeof(u32));
672 else
673 ptr = base + (4 * sizeof(u32)) + (start_idx * 3 * sizeof(u32));
674
675 /* Make sure device is powered up for SRAM reads */
676 spin_lock_irqsave(&priv->reg_lock, reg_flags);
677 if (iwl_grab_nic_access(priv)) {
678 spin_unlock_irqrestore(&priv->reg_lock, reg_flags);
679 return;
680 }
681
682 /* Set starting address; reads will auto-increment */
683 _iwl_write_direct32(priv, HBUS_TARG_MEM_RADDR, ptr);
684 rmb();
685
686 /*
687 * "time" is actually "data" for mode 0 (no timestamp).
688 * place event id # at far right for easier visual parsing.
689 */
690 for (i = 0; i < num_events; i++) {
691 ev = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT);
692 time = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT);
693 if (mode == 0) {
694 trace_iwlwifi_dev_ucode_cont_event(priv,
695 0, time, ev);
696 } else {
697 data = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT);
698 trace_iwlwifi_dev_ucode_cont_event(priv,
699 time, data, ev);
700 }
701 }
702 /* Allow device to power down */
703 iwl_release_nic_access(priv);
704 spin_unlock_irqrestore(&priv->reg_lock, reg_flags);
705}
706
707void iwl_continuous_event_trace(struct iwl_priv *priv)
708{
709 u32 capacity; /* event log capacity in # entries */
710 u32 base; /* SRAM byte address of event log header */
711 u32 mode; /* 0 - no timestamp, 1 - timestamp recorded */
712 u32 num_wraps; /* # times uCode wrapped to top of log */
713 u32 next_entry; /* index of next entry to be written by uCode */
714
715 if (priv->ucode_type == UCODE_INIT)
716 base = le32_to_cpu(priv->card_alive_init.error_event_table_ptr);
717 else
718 base = le32_to_cpu(priv->card_alive.log_event_table_ptr);
719 if (priv->cfg->ops->lib->is_valid_rtc_data_addr(base)) {
720 capacity = iwl_read_targ_mem(priv, base);
721 num_wraps = iwl_read_targ_mem(priv, base + (2 * sizeof(u32)));
722 mode = iwl_read_targ_mem(priv, base + (1 * sizeof(u32)));
723 next_entry = iwl_read_targ_mem(priv, base + (3 * sizeof(u32)));
724 } else
725 return;
726
727 if (num_wraps == priv->event_log.num_wraps) {
728 iwl_print_cont_event_trace(priv,
729 base, priv->event_log.next_entry,
730 next_entry - priv->event_log.next_entry,
731 mode);
732 priv->event_log.non_wraps_count++;
733 } else {
734 if ((num_wraps - priv->event_log.num_wraps) > 1)
735 priv->event_log.wraps_more_count++;
736 else
737 priv->event_log.wraps_once_count++;
738 trace_iwlwifi_dev_ucode_wrap_event(priv,
739 num_wraps - priv->event_log.num_wraps,
740 next_entry, priv->event_log.next_entry);
741 if (next_entry < priv->event_log.next_entry) {
742 iwl_print_cont_event_trace(priv, base,
743 priv->event_log.next_entry,
744 capacity - priv->event_log.next_entry,
745 mode);
746
747 iwl_print_cont_event_trace(priv, base, 0,
748 next_entry, mode);
749 } else {
750 iwl_print_cont_event_trace(priv, base,
751 next_entry, capacity - next_entry,
752 mode);
753
754 iwl_print_cont_event_trace(priv, base, 0,
755 next_entry, mode);
756 }
757 }
758 priv->event_log.num_wraps = num_wraps;
759 priv->event_log.next_entry = next_entry;
760}
761
762/**
763 * iwl_bg_ucode_trace - Timer callback to log ucode event
764 *
765 * The timer is continually set to execute every
766 * UCODE_TRACE_PERIOD milliseconds after the last timer expired
767 * this function is to perform continuous uCode event logging operation
768 * if enabled
769 */
770static void iwl_bg_ucode_trace(unsigned long data)
771{
772 struct iwl_priv *priv = (struct iwl_priv *)data;
773
774 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
775 return;
776
777 if (priv->event_log.ucode_trace) {
778 iwl_continuous_event_trace(priv);
779 /* Reschedule the timer to occur in UCODE_TRACE_PERIOD */
780 mod_timer(&priv->ucode_trace,
781 jiffies + msecs_to_jiffies(UCODE_TRACE_PERIOD));
782 }
783}
784
660static void iwl_rx_beacon_notif(struct iwl_priv *priv, 785static void iwl_rx_beacon_notif(struct iwl_priv *priv,
661 struct iwl_rx_mem_buffer *rxb) 786 struct iwl_rx_mem_buffer *rxb)
662{ 787{
@@ -689,12 +814,14 @@ static void iwl_rx_card_state_notif(struct iwl_priv *priv,
689 u32 flags = le32_to_cpu(pkt->u.card_state_notif.flags); 814 u32 flags = le32_to_cpu(pkt->u.card_state_notif.flags);
690 unsigned long status = priv->status; 815 unsigned long status = priv->status;
691 816
692 IWL_DEBUG_RF_KILL(priv, "Card state received: HW:%s SW:%s\n", 817 IWL_DEBUG_RF_KILL(priv, "Card state received: HW:%s SW:%s CT:%s\n",
693 (flags & HW_CARD_DISABLED) ? "Kill" : "On", 818 (flags & HW_CARD_DISABLED) ? "Kill" : "On",
694 (flags & SW_CARD_DISABLED) ? "Kill" : "On"); 819 (flags & SW_CARD_DISABLED) ? "Kill" : "On",
820 (flags & CT_CARD_DISABLED) ?
821 "Reached" : "Not reached");
695 822
696 if (flags & (SW_CARD_DISABLED | HW_CARD_DISABLED | 823 if (flags & (SW_CARD_DISABLED | HW_CARD_DISABLED |
697 RF_CARD_DISABLED)) { 824 CT_CARD_DISABLED)) {
698 825
699 iwl_write32(priv, CSR_UCODE_DRV_GP1_SET, 826 iwl_write32(priv, CSR_UCODE_DRV_GP1_SET,
700 CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED); 827 CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED);
@@ -708,10 +835,10 @@ static void iwl_rx_card_state_notif(struct iwl_priv *priv,
708 iwl_write_direct32(priv, HBUS_TARG_MBX_C, 835 iwl_write_direct32(priv, HBUS_TARG_MBX_C,
709 HBUS_TARG_MBX_C_REG_BIT_CMD_BLOCKED); 836 HBUS_TARG_MBX_C_REG_BIT_CMD_BLOCKED);
710 } 837 }
711 if (flags & RF_CARD_DISABLED) 838 if (flags & CT_CARD_DISABLED)
712 iwl_tt_enter_ct_kill(priv); 839 iwl_tt_enter_ct_kill(priv);
713 } 840 }
714 if (!(flags & RF_CARD_DISABLED)) 841 if (!(flags & CT_CARD_DISABLED))
715 iwl_tt_exit_ct_kill(priv); 842 iwl_tt_exit_ct_kill(priv);
716 843
717 if (flags & HW_CARD_DISABLED) 844 if (flags & HW_CARD_DISABLED)
@@ -1705,8 +1832,9 @@ void iwl_dump_nic_error_log(struct iwl_priv *priv)
1705 * iwl_print_event_log - Dump error event log to syslog 1832 * iwl_print_event_log - Dump error event log to syslog
1706 * 1833 *
1707 */ 1834 */
1708static void iwl_print_event_log(struct iwl_priv *priv, u32 start_idx, 1835static int iwl_print_event_log(struct iwl_priv *priv, u32 start_idx,
1709 u32 num_events, u32 mode) 1836 u32 num_events, u32 mode,
1837 int pos, char **buf, size_t bufsz)
1710{ 1838{
1711 u32 i; 1839 u32 i;
1712 u32 base; /* SRAM byte address of event log header */ 1840 u32 base; /* SRAM byte address of event log header */
@@ -1716,7 +1844,7 @@ static void iwl_print_event_log(struct iwl_priv *priv, u32 start_idx,
1716 unsigned long reg_flags; 1844 unsigned long reg_flags;
1717 1845
1718 if (num_events == 0) 1846 if (num_events == 0)
1719 return; 1847 return pos;
1720 if (priv->ucode_type == UCODE_INIT) 1848 if (priv->ucode_type == UCODE_INIT)
1721 base = le32_to_cpu(priv->card_alive_init.log_event_table_ptr); 1849 base = le32_to_cpu(priv->card_alive_init.log_event_table_ptr);
1722 else 1850 else
@@ -1744,27 +1872,44 @@ static void iwl_print_event_log(struct iwl_priv *priv, u32 start_idx,
1744 time = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT); 1872 time = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT);
1745 if (mode == 0) { 1873 if (mode == 0) {
1746 /* data, ev */ 1874 /* data, ev */
1747 trace_iwlwifi_dev_ucode_event(priv, 0, time, ev); 1875 if (bufsz) {
1748 IWL_ERR(priv, "EVT_LOG:0x%08x:%04u\n", time, ev); 1876 pos += scnprintf(*buf + pos, bufsz - pos,
1877 "EVT_LOG:0x%08x:%04u\n",
1878 time, ev);
1879 } else {
1880 trace_iwlwifi_dev_ucode_event(priv, 0,
1881 time, ev);
1882 IWL_ERR(priv, "EVT_LOG:0x%08x:%04u\n",
1883 time, ev);
1884 }
1749 } else { 1885 } else {
1750 data = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT); 1886 data = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT);
1751 IWL_ERR(priv, "EVT_LOGT:%010u:0x%08x:%04u\n", 1887 if (bufsz) {
1888 pos += scnprintf(*buf + pos, bufsz - pos,
1889 "EVT_LOGT:%010u:0x%08x:%04u\n",
1890 time, data, ev);
1891 } else {
1892 IWL_ERR(priv, "EVT_LOGT:%010u:0x%08x:%04u\n",
1752 time, data, ev); 1893 time, data, ev);
1753 trace_iwlwifi_dev_ucode_event(priv, time, data, ev); 1894 trace_iwlwifi_dev_ucode_event(priv, time,
1895 data, ev);
1896 }
1754 } 1897 }
1755 } 1898 }
1756 1899
1757 /* Allow device to power down */ 1900 /* Allow device to power down */
1758 iwl_release_nic_access(priv); 1901 iwl_release_nic_access(priv);
1759 spin_unlock_irqrestore(&priv->reg_lock, reg_flags); 1902 spin_unlock_irqrestore(&priv->reg_lock, reg_flags);
1903 return pos;
1760} 1904}
1761 1905
1762/** 1906/**
1763 * iwl_print_last_event_logs - Dump the newest # of event log to syslog 1907 * iwl_print_last_event_logs - Dump the newest # of event log to syslog
1764 */ 1908 */
1765static void iwl_print_last_event_logs(struct iwl_priv *priv, u32 capacity, 1909static int iwl_print_last_event_logs(struct iwl_priv *priv, u32 capacity,
1766 u32 num_wraps, u32 next_entry, 1910 u32 num_wraps, u32 next_entry,
1767 u32 size, u32 mode) 1911 u32 size, u32 mode,
1912 int pos, char **buf, size_t bufsz)
1768{ 1913{
1769 /* 1914 /*
1770 * display the newest DEFAULT_LOG_ENTRIES entries 1915 * display the newest DEFAULT_LOG_ENTRIES entries
@@ -1772,21 +1917,26 @@ static void iwl_print_last_event_logs(struct iwl_priv *priv, u32 capacity,
1772 */ 1917 */
1773 if (num_wraps) { 1918 if (num_wraps) {
1774 if (next_entry < size) { 1919 if (next_entry < size) {
1775 iwl_print_event_log(priv, 1920 pos = iwl_print_event_log(priv,
1776 capacity - (size - next_entry), 1921 capacity - (size - next_entry),
1777 size - next_entry, mode); 1922 size - next_entry, mode,
1778 iwl_print_event_log(priv, 0, 1923 pos, buf, bufsz);
1779 next_entry, mode); 1924 pos = iwl_print_event_log(priv, 0,
1925 next_entry, mode,
1926 pos, buf, bufsz);
1780 } else 1927 } else
1781 iwl_print_event_log(priv, next_entry - size, 1928 pos = iwl_print_event_log(priv, next_entry - size,
1782 size, mode); 1929 size, mode, pos, buf, bufsz);
1783 } else { 1930 } else {
1784 if (next_entry < size) 1931 if (next_entry < size) {
1785 iwl_print_event_log(priv, 0, next_entry, mode); 1932 pos = iwl_print_event_log(priv, 0, next_entry,
1786 else 1933 mode, pos, buf, bufsz);
1787 iwl_print_event_log(priv, next_entry - size, 1934 } else {
1788 size, mode); 1935 pos = iwl_print_event_log(priv, next_entry - size,
1936 size, mode, pos, buf, bufsz);
1937 }
1789 } 1938 }
1939 return pos;
1790} 1940}
1791 1941
1792/* For sanity check only. Actual size is determined by uCode, typ. 512 */ 1942/* For sanity check only. Actual size is determined by uCode, typ. 512 */
@@ -1794,7 +1944,8 @@ static void iwl_print_last_event_logs(struct iwl_priv *priv, u32 capacity,
1794 1944
1795#define DEFAULT_DUMP_EVENT_LOG_ENTRIES (20) 1945#define DEFAULT_DUMP_EVENT_LOG_ENTRIES (20)
1796 1946
1797void iwl_dump_nic_event_log(struct iwl_priv *priv, bool full_log) 1947int iwl_dump_nic_event_log(struct iwl_priv *priv, bool full_log,
1948 char **buf, bool display)
1798{ 1949{
1799 u32 base; /* SRAM byte address of event log header */ 1950 u32 base; /* SRAM byte address of event log header */
1800 u32 capacity; /* event log capacity in # entries */ 1951 u32 capacity; /* event log capacity in # entries */
@@ -1802,6 +1953,8 @@ void iwl_dump_nic_event_log(struct iwl_priv *priv, bool full_log)
1802 u32 num_wraps; /* # times uCode wrapped to top of log */ 1953 u32 num_wraps; /* # times uCode wrapped to top of log */
1803 u32 next_entry; /* index of next entry to be written by uCode */ 1954 u32 next_entry; /* index of next entry to be written by uCode */
1804 u32 size; /* # entries that we'll print */ 1955 u32 size; /* # entries that we'll print */
1956 int pos = 0;
1957 size_t bufsz = 0;
1805 1958
1806 if (priv->ucode_type == UCODE_INIT) 1959 if (priv->ucode_type == UCODE_INIT)
1807 base = le32_to_cpu(priv->card_alive_init.log_event_table_ptr); 1960 base = le32_to_cpu(priv->card_alive_init.log_event_table_ptr);
@@ -1812,7 +1965,7 @@ void iwl_dump_nic_event_log(struct iwl_priv *priv, bool full_log)
1812 IWL_ERR(priv, 1965 IWL_ERR(priv,
1813 "Invalid event log pointer 0x%08X for %s uCode\n", 1966 "Invalid event log pointer 0x%08X for %s uCode\n",
1814 base, (priv->ucode_type == UCODE_INIT) ? "Init" : "RT"); 1967 base, (priv->ucode_type == UCODE_INIT) ? "Init" : "RT");
1815 return; 1968 return pos;
1816 } 1969 }
1817 1970
1818 /* event log header */ 1971 /* event log header */
@@ -1838,7 +1991,7 @@ void iwl_dump_nic_event_log(struct iwl_priv *priv, bool full_log)
1838 /* bail out if nothing in log */ 1991 /* bail out if nothing in log */
1839 if (size == 0) { 1992 if (size == 0) {
1840 IWL_ERR(priv, "Start IWL Event Log Dump: nothing in log\n"); 1993 IWL_ERR(priv, "Start IWL Event Log Dump: nothing in log\n");
1841 return; 1994 return pos;
1842 } 1995 }
1843 1996
1844#ifdef CONFIG_IWLWIFI_DEBUG 1997#ifdef CONFIG_IWLWIFI_DEBUG
@@ -1853,6 +2006,15 @@ void iwl_dump_nic_event_log(struct iwl_priv *priv, bool full_log)
1853 size); 2006 size);
1854 2007
1855#ifdef CONFIG_IWLWIFI_DEBUG 2008#ifdef CONFIG_IWLWIFI_DEBUG
2009 if (display) {
2010 if (full_log)
2011 bufsz = capacity * 48;
2012 else
2013 bufsz = size * 48;
2014 *buf = kmalloc(bufsz, GFP_KERNEL);
2015 if (!*buf)
2016 return pos;
2017 }
1856 if ((iwl_get_debug_level(priv) & IWL_DL_FW_ERRORS) || full_log) { 2018 if ((iwl_get_debug_level(priv) & IWL_DL_FW_ERRORS) || full_log) {
1857 /* 2019 /*
1858 * if uCode has wrapped back to top of log, 2020 * if uCode has wrapped back to top of log,
@@ -1860,17 +2022,22 @@ void iwl_dump_nic_event_log(struct iwl_priv *priv, bool full_log)
1860 * i.e the next one that uCode would fill. 2022 * i.e the next one that uCode would fill.
1861 */ 2023 */
1862 if (num_wraps) 2024 if (num_wraps)
1863 iwl_print_event_log(priv, next_entry, 2025 pos = iwl_print_event_log(priv, next_entry,
1864 capacity - next_entry, mode); 2026 capacity - next_entry, mode,
2027 pos, buf, bufsz);
1865 /* (then/else) start at top of log */ 2028 /* (then/else) start at top of log */
1866 iwl_print_event_log(priv, 0, next_entry, mode); 2029 pos = iwl_print_event_log(priv, 0,
2030 next_entry, mode, pos, buf, bufsz);
1867 } else 2031 } else
1868 iwl_print_last_event_logs(priv, capacity, num_wraps, 2032 pos = iwl_print_last_event_logs(priv, capacity, num_wraps,
1869 next_entry, size, mode); 2033 next_entry, size, mode,
2034 pos, buf, bufsz);
1870#else 2035#else
1871 iwl_print_last_event_logs(priv, capacity, num_wraps, 2036 pos = iwl_print_last_event_logs(priv, capacity, num_wraps,
1872 next_entry, size, mode); 2037 next_entry, size, mode,
2038 pos, buf, bufsz);
1873#endif 2039#endif
2040 return pos;
1874} 2041}
1875 2042
1876/** 2043/**
@@ -2456,6 +2623,10 @@ static int iwl_setup_mac(struct iwl_priv *priv)
2456 hw->flags |= IEEE80211_HW_SUPPORTS_PS | 2623 hw->flags |= IEEE80211_HW_SUPPORTS_PS |
2457 IEEE80211_HW_SUPPORTS_DYNAMIC_PS; 2624 IEEE80211_HW_SUPPORTS_DYNAMIC_PS;
2458 2625
2626 if (priv->cfg->sku & IWL_SKU_N)
2627 hw->flags |= IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS |
2628 IEEE80211_HW_SUPPORTS_STATIC_SMPS;
2629
2459 hw->sta_data_size = sizeof(struct iwl_station_priv); 2630 hw->sta_data_size = sizeof(struct iwl_station_priv);
2460 hw->wiphy->interface_modes = 2631 hw->wiphy->interface_modes =
2461 BIT(NL80211_IFTYPE_STATION) | 2632 BIT(NL80211_IFTYPE_STATION) |
@@ -3126,6 +3297,10 @@ static void iwl_setup_deferred_work(struct iwl_priv *priv)
3126 priv->statistics_periodic.data = (unsigned long)priv; 3297 priv->statistics_periodic.data = (unsigned long)priv;
3127 priv->statistics_periodic.function = iwl_bg_statistics_periodic; 3298 priv->statistics_periodic.function = iwl_bg_statistics_periodic;
3128 3299
3300 init_timer(&priv->ucode_trace);
3301 priv->ucode_trace.data = (unsigned long)priv;
3302 priv->ucode_trace.function = iwl_bg_ucode_trace;
3303
3129 if (!priv->cfg->use_isr_legacy) 3304 if (!priv->cfg->use_isr_legacy)
3130 tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long)) 3305 tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long))
3131 iwl_irq_tasklet, (unsigned long)priv); 3306 iwl_irq_tasklet, (unsigned long)priv);
@@ -3144,6 +3319,7 @@ static void iwl_cancel_deferred_work(struct iwl_priv *priv)
3144 cancel_delayed_work(&priv->alive_start); 3319 cancel_delayed_work(&priv->alive_start);
3145 cancel_work_sync(&priv->beacon_update); 3320 cancel_work_sync(&priv->beacon_update);
3146 del_timer_sync(&priv->statistics_periodic); 3321 del_timer_sync(&priv->statistics_periodic);
3322 del_timer_sync(&priv->ucode_trace);
3147} 3323}
3148 3324
3149static void iwl_init_hw_rates(struct iwl_priv *priv, 3325static void iwl_init_hw_rates(struct iwl_priv *priv,
@@ -3188,6 +3364,7 @@ static int iwl_init_drv(struct iwl_priv *priv)
3188 priv->band = IEEE80211_BAND_2GHZ; 3364 priv->band = IEEE80211_BAND_2GHZ;
3189 3365
3190 priv->iw_mode = NL80211_IFTYPE_STATION; 3366 priv->iw_mode = NL80211_IFTYPE_STATION;
3367 priv->current_ht_config.smps = IEEE80211_SMPS_STATIC;
3191 3368
3192 /* Choose which receivers/antennas to use */ 3369 /* Choose which receivers/antennas to use */
3193 if (priv->cfg->ops->hcmd->set_rxon_chain) 3370 if (priv->cfg->ops->hcmd->set_rxon_chain)
diff --git a/drivers/net/wireless/iwlwifi/iwl-calib.c b/drivers/net/wireless/iwlwifi/iwl-calib.c
index 95a57b36a7ea..dc61906290e8 100644
--- a/drivers/net/wireless/iwlwifi/iwl-calib.c
+++ b/drivers/net/wireless/iwlwifi/iwl-calib.c
@@ -414,7 +414,6 @@ static int iwl_sens_auto_corr_ofdm(struct iwl_priv *priv,
414/* Prepare a SENSITIVITY_CMD, send to uCode if values have changed */ 414/* Prepare a SENSITIVITY_CMD, send to uCode if values have changed */
415static int iwl_sensitivity_write(struct iwl_priv *priv) 415static int iwl_sensitivity_write(struct iwl_priv *priv)
416{ 416{
417 int ret = 0;
418 struct iwl_sensitivity_cmd cmd ; 417 struct iwl_sensitivity_cmd cmd ;
419 struct iwl_sensitivity_data *data = NULL; 418 struct iwl_sensitivity_data *data = NULL;
420 struct iwl_host_cmd cmd_out = { 419 struct iwl_host_cmd cmd_out = {
@@ -477,11 +476,7 @@ static int iwl_sensitivity_write(struct iwl_priv *priv)
477 memcpy(&(priv->sensitivity_tbl[0]), &(cmd.table[0]), 476 memcpy(&(priv->sensitivity_tbl[0]), &(cmd.table[0]),
478 sizeof(u16)*HD_TABLE_SIZE); 477 sizeof(u16)*HD_TABLE_SIZE);
479 478
480 ret = iwl_send_cmd(priv, &cmd_out); 479 return iwl_send_cmd(priv, &cmd_out);
481 if (ret)
482 IWL_ERR(priv, "SENSITIVITY_CMD failed\n");
483
484 return ret;
485} 480}
486 481
487void iwl_init_sensitivity(struct iwl_priv *priv) 482void iwl_init_sensitivity(struct iwl_priv *priv)
diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h
index e91507531923..28f3800c560e 100644
--- a/drivers/net/wireless/iwlwifi/iwl-commands.h
+++ b/drivers/net/wireless/iwlwifi/iwl-commands.h
@@ -2510,7 +2510,7 @@ struct iwl_card_state_notif {
2510 2510
2511#define HW_CARD_DISABLED 0x01 2511#define HW_CARD_DISABLED 0x01
2512#define SW_CARD_DISABLED 0x02 2512#define SW_CARD_DISABLED 0x02
2513#define RF_CARD_DISABLED 0x04 2513#define CT_CARD_DISABLED 0x04
2514#define RXON_CARD_DISABLED 0x10 2514#define RXON_CARD_DISABLED 0x10
2515 2515
2516struct iwl_ct_kill_config { 2516struct iwl_ct_kill_config {
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index 574d36658702..e3b96b48b7fe 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -450,8 +450,6 @@ static void iwlcore_init_ht_hw_capab(const struct iwl_priv *priv,
450 if (priv->cfg->ht_greenfield_support) 450 if (priv->cfg->ht_greenfield_support)
451 ht_info->cap |= IEEE80211_HT_CAP_GRN_FLD; 451 ht_info->cap |= IEEE80211_HT_CAP_GRN_FLD;
452 ht_info->cap |= IEEE80211_HT_CAP_SGI_20; 452 ht_info->cap |= IEEE80211_HT_CAP_SGI_20;
453 ht_info->cap |= (IEEE80211_HT_CAP_SM_PS &
454 (priv->cfg->sm_ps_mode << 2));
455 max_bit_rate = MAX_BIT_RATE_20_MHZ; 453 max_bit_rate = MAX_BIT_RATE_20_MHZ;
456 if (priv->hw_params.ht40_channel & BIT(band)) { 454 if (priv->hw_params.ht40_channel & BIT(band)) {
457 ht_info->cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40; 455 ht_info->cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40;
@@ -636,7 +634,7 @@ EXPORT_SYMBOL(iwlcore_rts_tx_cmd_flag);
636 634
637static bool is_single_rx_stream(struct iwl_priv *priv) 635static bool is_single_rx_stream(struct iwl_priv *priv)
638{ 636{
639 return !priv->current_ht_config.is_ht || 637 return priv->current_ht_config.smps == IEEE80211_SMPS_STATIC ||
640 priv->current_ht_config.single_chain_sufficient; 638 priv->current_ht_config.single_chain_sufficient;
641} 639}
642 640
@@ -1003,28 +1001,18 @@ static int iwl_get_active_rx_chain_count(struct iwl_priv *priv)
1003 */ 1001 */
1004static int iwl_get_idle_rx_chain_count(struct iwl_priv *priv, int active_cnt) 1002static int iwl_get_idle_rx_chain_count(struct iwl_priv *priv, int active_cnt)
1005{ 1003{
1006 int idle_cnt = active_cnt; 1004 /* # Rx chains when idling, depending on SMPS mode */
1007 bool is_cam = !test_bit(STATUS_POWER_PMI, &priv->status); 1005 switch (priv->current_ht_config.smps) {
1008 1006 case IEEE80211_SMPS_STATIC:
1009 /* # Rx chains when idling and maybe trying to save power */ 1007 case IEEE80211_SMPS_DYNAMIC:
1010 switch (priv->cfg->sm_ps_mode) { 1008 return IWL_NUM_IDLE_CHAINS_SINGLE;
1011 case WLAN_HT_CAP_SM_PS_STATIC: 1009 case IEEE80211_SMPS_OFF:
1012 idle_cnt = (is_cam) ? active_cnt : IWL_NUM_IDLE_CHAINS_SINGLE; 1010 return active_cnt;
1013 break;
1014 case WLAN_HT_CAP_SM_PS_DYNAMIC:
1015 idle_cnt = (is_cam) ? IWL_NUM_IDLE_CHAINS_DUAL :
1016 IWL_NUM_IDLE_CHAINS_SINGLE;
1017 break;
1018 case WLAN_HT_CAP_SM_PS_DISABLED:
1019 break;
1020 case WLAN_HT_CAP_SM_PS_INVALID:
1021 default: 1011 default:
1022 IWL_ERR(priv, "invalid sm_ps mode %u\n", 1012 WARN(1, "invalid SMPS mode %d",
1023 priv->cfg->sm_ps_mode); 1013 priv->current_ht_config.smps);
1024 WARN_ON(1); 1014 return active_cnt;
1025 break;
1026 } 1015 }
1027 return idle_cnt;
1028} 1016}
1029 1017
1030/* up to 4 chains */ 1018/* up to 4 chains */
@@ -1363,7 +1351,9 @@ void iwl_irq_handle_error(struct iwl_priv *priv)
1363 clear_bit(STATUS_HCMD_ACTIVE, &priv->status); 1351 clear_bit(STATUS_HCMD_ACTIVE, &priv->status);
1364 1352
1365 priv->cfg->ops->lib->dump_nic_error_log(priv); 1353 priv->cfg->ops->lib->dump_nic_error_log(priv);
1366 priv->cfg->ops->lib->dump_nic_event_log(priv, false); 1354 if (priv->cfg->ops->lib->dump_csr)
1355 priv->cfg->ops->lib->dump_csr(priv);
1356 priv->cfg->ops->lib->dump_nic_event_log(priv, false, NULL, false);
1367#ifdef CONFIG_IWLWIFI_DEBUG 1357#ifdef CONFIG_IWLWIFI_DEBUG
1368 if (iwl_get_debug_level(priv) & IWL_DL_FW_ERRORS) 1358 if (iwl_get_debug_level(priv) & IWL_DL_FW_ERRORS)
1369 iwl_print_rx_config_cmd(priv); 1359 iwl_print_rx_config_cmd(priv);
@@ -2684,6 +2674,21 @@ int iwl_mac_config(struct ieee80211_hw *hw, u32 changed)
2684 IWL_DEBUG_MAC80211(priv, "leave - scanning\n"); 2674 IWL_DEBUG_MAC80211(priv, "leave - scanning\n");
2685 } 2675 }
2686 2676
2677 if (changed & (IEEE80211_CONF_CHANGE_SMPS |
2678 IEEE80211_CONF_CHANGE_CHANNEL)) {
2679 /* mac80211 uses static for non-HT which is what we want */
2680 priv->current_ht_config.smps = conf->smps_mode;
2681
2682 /*
2683 * Recalculate chain counts.
2684 *
2685 * If monitor mode is enabled then mac80211 will
2686 * set up the SM PS mode to OFF if an HT channel is
2687 * configured.
2688 */
2689 if (priv->cfg->ops->hcmd->set_rxon_chain)
2690 priv->cfg->ops->hcmd->set_rxon_chain(priv);
2691 }
2687 2692
2688 /* during scanning mac80211 will delay channel setting until 2693 /* during scanning mac80211 will delay channel setting until
2689 * scan finish with changed = 0 2694 * scan finish with changed = 0
@@ -2780,10 +2785,6 @@ int iwl_mac_config(struct ieee80211_hw *hw, u32 changed)
2780 iwl_set_tx_power(priv, conf->power_level, false); 2785 iwl_set_tx_power(priv, conf->power_level, false);
2781 } 2786 }
2782 2787
2783 /* call to ensure that 4965 rx_chain is set properly in monitor mode */
2784 if (priv->cfg->ops->hcmd->set_rxon_chain)
2785 priv->cfg->ops->hcmd->set_rxon_chain(priv);
2786
2787 if (!iwl_is_ready(priv)) { 2788 if (!iwl_is_ready(priv)) {
2788 IWL_DEBUG_MAC80211(priv, "leave - not ready\n"); 2789 IWL_DEBUG_MAC80211(priv, "leave - not ready\n");
2789 goto out; 2790 goto out;
@@ -3191,6 +3192,77 @@ void iwl_update_stats(struct iwl_priv *priv, bool is_tx, __le16 fc, u16 len)
3191EXPORT_SYMBOL(iwl_update_stats); 3192EXPORT_SYMBOL(iwl_update_stats);
3192#endif 3193#endif
3193 3194
3195const static char *get_csr_string(int cmd)
3196{
3197 switch (cmd) {
3198 IWL_CMD(CSR_HW_IF_CONFIG_REG);
3199 IWL_CMD(CSR_INT_COALESCING);
3200 IWL_CMD(CSR_INT);
3201 IWL_CMD(CSR_INT_MASK);
3202 IWL_CMD(CSR_FH_INT_STATUS);
3203 IWL_CMD(CSR_GPIO_IN);
3204 IWL_CMD(CSR_RESET);
3205 IWL_CMD(CSR_GP_CNTRL);
3206 IWL_CMD(CSR_HW_REV);
3207 IWL_CMD(CSR_EEPROM_REG);
3208 IWL_CMD(CSR_EEPROM_GP);
3209 IWL_CMD(CSR_OTP_GP_REG);
3210 IWL_CMD(CSR_GIO_REG);
3211 IWL_CMD(CSR_GP_UCODE_REG);
3212 IWL_CMD(CSR_GP_DRIVER_REG);
3213 IWL_CMD(CSR_UCODE_DRV_GP1);
3214 IWL_CMD(CSR_UCODE_DRV_GP2);
3215 IWL_CMD(CSR_LED_REG);
3216 IWL_CMD(CSR_DRAM_INT_TBL_REG);
3217 IWL_CMD(CSR_GIO_CHICKEN_BITS);
3218 IWL_CMD(CSR_ANA_PLL_CFG);
3219 IWL_CMD(CSR_HW_REV_WA_REG);
3220 IWL_CMD(CSR_DBG_HPET_MEM_REG);
3221 default:
3222 return "UNKNOWN";
3223
3224 }
3225}
3226
3227void iwl_dump_csr(struct iwl_priv *priv)
3228{
3229 int i;
3230 u32 csr_tbl[] = {
3231 CSR_HW_IF_CONFIG_REG,
3232 CSR_INT_COALESCING,
3233 CSR_INT,
3234 CSR_INT_MASK,
3235 CSR_FH_INT_STATUS,
3236 CSR_GPIO_IN,
3237 CSR_RESET,
3238 CSR_GP_CNTRL,
3239 CSR_HW_REV,
3240 CSR_EEPROM_REG,
3241 CSR_EEPROM_GP,
3242 CSR_OTP_GP_REG,
3243 CSR_GIO_REG,
3244 CSR_GP_UCODE_REG,
3245 CSR_GP_DRIVER_REG,
3246 CSR_UCODE_DRV_GP1,
3247 CSR_UCODE_DRV_GP2,
3248 CSR_LED_REG,
3249 CSR_DRAM_INT_TBL_REG,
3250 CSR_GIO_CHICKEN_BITS,
3251 CSR_ANA_PLL_CFG,
3252 CSR_HW_REV_WA_REG,
3253 CSR_DBG_HPET_MEM_REG
3254 };
3255 IWL_ERR(priv, "CSR values:\n");
3256 IWL_ERR(priv, "(2nd byte of CSR_INT_COALESCING is "
3257 "CSR_INT_PERIODIC_REG)\n");
3258 for (i = 0; i < ARRAY_SIZE(csr_tbl); i++) {
3259 IWL_ERR(priv, " %25s: 0X%08x\n",
3260 get_csr_string(csr_tbl[i]),
3261 iwl_read32(priv, csr_tbl[i]));
3262 }
3263}
3264EXPORT_SYMBOL(iwl_dump_csr);
3265
3194#ifdef CONFIG_PM 3266#ifdef CONFIG_PM
3195 3267
3196int iwl_pci_suspend(struct pci_dev *pdev, pm_message_t state) 3268int iwl_pci_suspend(struct pci_dev *pdev, pm_message_t state)
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index 27ca859e7453..308f679ef81c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -169,8 +169,10 @@ struct iwl_lib_ops {
169 int (*is_valid_rtc_data_addr)(u32 addr); 169 int (*is_valid_rtc_data_addr)(u32 addr);
170 /* 1st ucode load */ 170 /* 1st ucode load */
171 int (*load_ucode)(struct iwl_priv *priv); 171 int (*load_ucode)(struct iwl_priv *priv);
172 void (*dump_nic_event_log)(struct iwl_priv *priv, bool full_log); 172 int (*dump_nic_event_log)(struct iwl_priv *priv,
173 bool full_log, char **buf, bool display);
173 void (*dump_nic_error_log)(struct iwl_priv *priv); 174 void (*dump_nic_error_log)(struct iwl_priv *priv);
175 void (*dump_csr)(struct iwl_priv *priv);
174 int (*set_channel_switch)(struct iwl_priv *priv, u16 channel); 176 int (*set_channel_switch)(struct iwl_priv *priv, u16 channel);
175 /* power management */ 177 /* power management */
176 struct iwl_apm_ops apm_ops; 178 struct iwl_apm_ops apm_ops;
@@ -230,7 +232,6 @@ struct iwl_mod_params {
230 * @chain_noise_num_beacons: number of beacons used to compute chain noise 232 * @chain_noise_num_beacons: number of beacons used to compute chain noise
231 * @adv_thermal_throttle: support advance thermal throttle 233 * @adv_thermal_throttle: support advance thermal throttle
232 * @support_ct_kill_exit: support ct kill exit condition 234 * @support_ct_kill_exit: support ct kill exit condition
233 * @sm_ps_mode: spatial multiplexing power save mode
234 * @support_wimax_coexist: support wimax/wifi co-exist 235 * @support_wimax_coexist: support wimax/wifi co-exist
235 * 236 *
236 * We enable the driver to be backward compatible wrt API version. The 237 * We enable the driver to be backward compatible wrt API version. The
@@ -287,7 +288,6 @@ struct iwl_cfg {
287 const bool supports_idle; 288 const bool supports_idle;
288 bool adv_thermal_throttle; 289 bool adv_thermal_throttle;
289 bool support_ct_kill_exit; 290 bool support_ct_kill_exit;
290 u8 sm_ps_mode;
291 const bool support_wimax_coexist; 291 const bool support_wimax_coexist;
292}; 292};
293 293
@@ -581,7 +581,9 @@ int iwl_pci_resume(struct pci_dev *pdev);
581* Error Handling Debugging 581* Error Handling Debugging
582******************************************************/ 582******************************************************/
583void iwl_dump_nic_error_log(struct iwl_priv *priv); 583void iwl_dump_nic_error_log(struct iwl_priv *priv);
584void iwl_dump_nic_event_log(struct iwl_priv *priv, bool full_log); 584int iwl_dump_nic_event_log(struct iwl_priv *priv,
585 bool full_log, char **buf, bool display);
586void iwl_dump_csr(struct iwl_priv *priv);
585#ifdef CONFIG_IWLWIFI_DEBUG 587#ifdef CONFIG_IWLWIFI_DEBUG
586void iwl_print_rx_config_cmd(struct iwl_priv *priv); 588void iwl_print_rx_config_cmd(struct iwl_priv *priv);
587#else 589#else
diff --git a/drivers/net/wireless/iwlwifi/iwl-debug.h b/drivers/net/wireless/iwlwifi/iwl-debug.h
index d61293ab67c9..58e0462cafa3 100644
--- a/drivers/net/wireless/iwlwifi/iwl-debug.h
+++ b/drivers/net/wireless/iwlwifi/iwl-debug.h
@@ -109,6 +109,8 @@ struct iwl_debugfs {
109 struct dentry *file_power_save_status; 109 struct dentry *file_power_save_status;
110 struct dentry *file_clear_ucode_statistics; 110 struct dentry *file_clear_ucode_statistics;
111 struct dentry *file_clear_traffic_statistics; 111 struct dentry *file_clear_traffic_statistics;
112 struct dentry *file_csr;
113 struct dentry *file_ucode_tracing;
112 } dbgfs_debug_files; 114 } dbgfs_debug_files;
113 u32 sram_offset; 115 u32 sram_offset;
114 u32 sram_len; 116 u32 sram_len;
diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
index 21e0f6699daf..ee5aed12a4b1 100644
--- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
@@ -420,6 +420,23 @@ static ssize_t iwl_dbgfs_nvm_read(struct file *file,
420 return ret; 420 return ret;
421} 421}
422 422
423static ssize_t iwl_dbgfs_log_event_read(struct file *file,
424 char __user *user_buf,
425 size_t count, loff_t *ppos)
426{
427 struct iwl_priv *priv = file->private_data;
428 char *buf;
429 int pos = 0;
430 ssize_t ret = -ENOMEM;
431
432 pos = priv->cfg->ops->lib->dump_nic_event_log(priv, true, &buf, true);
433 if (pos && buf) {
434 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
435 kfree(buf);
436 }
437 return ret;
438}
439
423static ssize_t iwl_dbgfs_log_event_write(struct file *file, 440static ssize_t iwl_dbgfs_log_event_write(struct file *file,
424 const char __user *user_buf, 441 const char __user *user_buf,
425 size_t count, loff_t *ppos) 442 size_t count, loff_t *ppos)
@@ -436,7 +453,8 @@ static ssize_t iwl_dbgfs_log_event_write(struct file *file,
436 if (sscanf(buf, "%d", &event_log_flag) != 1) 453 if (sscanf(buf, "%d", &event_log_flag) != 1)
437 return -EFAULT; 454 return -EFAULT;
438 if (event_log_flag == 1) 455 if (event_log_flag == 1)
439 priv->cfg->ops->lib->dump_nic_event_log(priv, true); 456 priv->cfg->ops->lib->dump_nic_event_log(priv, true,
457 NULL, false);
440 458
441 return count; 459 return count;
442} 460}
@@ -859,7 +877,7 @@ static ssize_t iwl_dbgfs_current_sleep_command_read(struct file *file,
859} 877}
860 878
861DEBUGFS_READ_WRITE_FILE_OPS(sram); 879DEBUGFS_READ_WRITE_FILE_OPS(sram);
862DEBUGFS_WRITE_FILE_OPS(log_event); 880DEBUGFS_READ_WRITE_FILE_OPS(log_event);
863DEBUGFS_READ_FILE_OPS(nvm); 881DEBUGFS_READ_FILE_OPS(nvm);
864DEBUGFS_READ_FILE_OPS(stations); 882DEBUGFS_READ_FILE_OPS(stations);
865DEBUGFS_READ_FILE_OPS(channels); 883DEBUGFS_READ_FILE_OPS(channels);
@@ -1845,6 +1863,80 @@ static ssize_t iwl_dbgfs_clear_ucode_statistics_write(struct file *file,
1845 return count; 1863 return count;
1846} 1864}
1847 1865
1866static ssize_t iwl_dbgfs_csr_write(struct file *file,
1867 const char __user *user_buf,
1868 size_t count, loff_t *ppos)
1869{
1870 struct iwl_priv *priv = file->private_data;
1871 char buf[8];
1872 int buf_size;
1873 int csr;
1874
1875 memset(buf, 0, sizeof(buf));
1876 buf_size = min(count, sizeof(buf) - 1);
1877 if (copy_from_user(buf, user_buf, buf_size))
1878 return -EFAULT;
1879 if (sscanf(buf, "%d", &csr) != 1)
1880 return -EFAULT;
1881
1882 if (priv->cfg->ops->lib->dump_csr)
1883 priv->cfg->ops->lib->dump_csr(priv);
1884
1885 return count;
1886}
1887
1888static ssize_t iwl_dbgfs_ucode_tracing_read(struct file *file,
1889 char __user *user_buf,
1890 size_t count, loff_t *ppos) {
1891
1892 struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
1893 int pos = 0;
1894 char buf[128];
1895 const size_t bufsz = sizeof(buf);
1896 ssize_t ret;
1897
1898 pos += scnprintf(buf + pos, bufsz - pos, "ucode trace timer is %s\n",
1899 priv->event_log.ucode_trace ? "On" : "Off");
1900 pos += scnprintf(buf + pos, bufsz - pos, "non_wraps_count:\t\t %u\n",
1901 priv->event_log.non_wraps_count);
1902 pos += scnprintf(buf + pos, bufsz - pos, "wraps_once_count:\t\t %u\n",
1903 priv->event_log.wraps_once_count);
1904 pos += scnprintf(buf + pos, bufsz - pos, "wraps_more_count:\t\t %u\n",
1905 priv->event_log.wraps_more_count);
1906
1907 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1908 return ret;
1909}
1910
1911static ssize_t iwl_dbgfs_ucode_tracing_write(struct file *file,
1912 const char __user *user_buf,
1913 size_t count, loff_t *ppos)
1914{
1915 struct iwl_priv *priv = file->private_data;
1916 char buf[8];
1917 int buf_size;
1918 int trace;
1919
1920 memset(buf, 0, sizeof(buf));
1921 buf_size = min(count, sizeof(buf) - 1);
1922 if (copy_from_user(buf, user_buf, buf_size))
1923 return -EFAULT;
1924 if (sscanf(buf, "%d", &trace) != 1)
1925 return -EFAULT;
1926
1927 if (trace) {
1928 priv->event_log.ucode_trace = true;
1929 /* schedule the ucode timer to occur in UCODE_TRACE_PERIOD */
1930 mod_timer(&priv->ucode_trace,
1931 jiffies + msecs_to_jiffies(UCODE_TRACE_PERIOD));
1932 } else {
1933 priv->event_log.ucode_trace = false;
1934 del_timer_sync(&priv->ucode_trace);
1935 }
1936
1937 return count;
1938}
1939
1848DEBUGFS_READ_FILE_OPS(rx_statistics); 1940DEBUGFS_READ_FILE_OPS(rx_statistics);
1849DEBUGFS_READ_FILE_OPS(tx_statistics); 1941DEBUGFS_READ_FILE_OPS(tx_statistics);
1850DEBUGFS_READ_WRITE_FILE_OPS(traffic_log); 1942DEBUGFS_READ_WRITE_FILE_OPS(traffic_log);
@@ -1859,6 +1951,8 @@ DEBUGFS_READ_FILE_OPS(tx_power);
1859DEBUGFS_READ_FILE_OPS(power_save_status); 1951DEBUGFS_READ_FILE_OPS(power_save_status);
1860DEBUGFS_WRITE_FILE_OPS(clear_ucode_statistics); 1952DEBUGFS_WRITE_FILE_OPS(clear_ucode_statistics);
1861DEBUGFS_WRITE_FILE_OPS(clear_traffic_statistics); 1953DEBUGFS_WRITE_FILE_OPS(clear_traffic_statistics);
1954DEBUGFS_WRITE_FILE_OPS(csr);
1955DEBUGFS_READ_WRITE_FILE_OPS(ucode_tracing);
1862 1956
1863/* 1957/*
1864 * Create the debugfs files and directories 1958 * Create the debugfs files and directories
@@ -1889,7 +1983,7 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name)
1889 DEBUGFS_ADD_DIR(debug, dbgfs->dir_drv); 1983 DEBUGFS_ADD_DIR(debug, dbgfs->dir_drv);
1890 DEBUGFS_ADD_FILE(nvm, data, S_IRUSR); 1984 DEBUGFS_ADD_FILE(nvm, data, S_IRUSR);
1891 DEBUGFS_ADD_FILE(sram, data, S_IWUSR | S_IRUSR); 1985 DEBUGFS_ADD_FILE(sram, data, S_IWUSR | S_IRUSR);
1892 DEBUGFS_ADD_FILE(log_event, data, S_IWUSR); 1986 DEBUGFS_ADD_FILE(log_event, data, S_IWUSR | S_IRUSR);
1893 DEBUGFS_ADD_FILE(stations, data, S_IRUSR); 1987 DEBUGFS_ADD_FILE(stations, data, S_IRUSR);
1894 DEBUGFS_ADD_FILE(channels, data, S_IRUSR); 1988 DEBUGFS_ADD_FILE(channels, data, S_IRUSR);
1895 DEBUGFS_ADD_FILE(status, data, S_IRUSR); 1989 DEBUGFS_ADD_FILE(status, data, S_IRUSR);
@@ -1909,12 +2003,14 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name)
1909 DEBUGFS_ADD_FILE(power_save_status, debug, S_IRUSR); 2003 DEBUGFS_ADD_FILE(power_save_status, debug, S_IRUSR);
1910 DEBUGFS_ADD_FILE(clear_ucode_statistics, debug, S_IWUSR); 2004 DEBUGFS_ADD_FILE(clear_ucode_statistics, debug, S_IWUSR);
1911 DEBUGFS_ADD_FILE(clear_traffic_statistics, debug, S_IWUSR); 2005 DEBUGFS_ADD_FILE(clear_traffic_statistics, debug, S_IWUSR);
2006 DEBUGFS_ADD_FILE(csr, debug, S_IWUSR);
1912 if ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) != CSR_HW_REV_TYPE_3945) { 2007 if ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) != CSR_HW_REV_TYPE_3945) {
1913 DEBUGFS_ADD_FILE(ucode_rx_stats, debug, S_IRUSR); 2008 DEBUGFS_ADD_FILE(ucode_rx_stats, debug, S_IRUSR);
1914 DEBUGFS_ADD_FILE(ucode_tx_stats, debug, S_IRUSR); 2009 DEBUGFS_ADD_FILE(ucode_tx_stats, debug, S_IRUSR);
1915 DEBUGFS_ADD_FILE(ucode_general_stats, debug, S_IRUSR); 2010 DEBUGFS_ADD_FILE(ucode_general_stats, debug, S_IRUSR);
1916 DEBUGFS_ADD_FILE(sensitivity, debug, S_IRUSR); 2011 DEBUGFS_ADD_FILE(sensitivity, debug, S_IRUSR);
1917 DEBUGFS_ADD_FILE(chain_noise, debug, S_IRUSR); 2012 DEBUGFS_ADD_FILE(chain_noise, debug, S_IRUSR);
2013 DEBUGFS_ADD_FILE(ucode_tracing, debug, S_IWUSR | S_IRUSR);
1918 } 2014 }
1919 DEBUGFS_ADD_BOOL(disable_sensitivity, rf, &priv->disable_sens_cal); 2015 DEBUGFS_ADD_BOOL(disable_sensitivity, rf, &priv->disable_sens_cal);
1920 DEBUGFS_ADD_BOOL(disable_chain_noise, rf, 2016 DEBUGFS_ADD_BOOL(disable_chain_noise, rf,
@@ -1966,6 +2062,7 @@ void iwl_dbgfs_unregister(struct iwl_priv *priv)
1966 file_clear_ucode_statistics); 2062 file_clear_ucode_statistics);
1967 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files. 2063 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.
1968 file_clear_traffic_statistics); 2064 file_clear_traffic_statistics);
2065 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_csr);
1969 if ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) != CSR_HW_REV_TYPE_3945) { 2066 if ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) != CSR_HW_REV_TYPE_3945) {
1970 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files. 2067 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.
1971 file_ucode_rx_stats); 2068 file_ucode_rx_stats);
@@ -1977,6 +2074,8 @@ void iwl_dbgfs_unregister(struct iwl_priv *priv)
1977 file_sensitivity); 2074 file_sensitivity);
1978 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files. 2075 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.
1979 file_chain_noise); 2076 file_chain_noise);
2077 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.
2078 file_ucode_tracing);
1980 } 2079 }
1981 DEBUGFS_REMOVE(priv->dbgfs->dir_debug); 2080 DEBUGFS_REMOVE(priv->dbgfs->dir_debug);
1982 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_rf_files.file_disable_sensitivity); 2081 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_rf_files.file_disable_sensitivity);
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index 165d1f6e2dd9..42f9b17327c3 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -512,6 +512,7 @@ struct iwl_ht_config {
512 bool is_ht; 512 bool is_ht;
513 bool is_40mhz; 513 bool is_40mhz;
514 bool single_chain_sufficient; 514 bool single_chain_sufficient;
515 enum ieee80211_smps_mode smps; /* current smps mode */
515 /* BSS related data */ 516 /* BSS related data */
516 u8 extension_chan_offset; 517 u8 extension_chan_offset;
517 u8 ht_protection; 518 u8 ht_protection;
@@ -984,6 +985,32 @@ struct iwl_switch_rxon {
984 __le16 channel; 985 __le16 channel;
985}; 986};
986 987
988/*
989 * schedule the timer to wake up every UCODE_TRACE_PERIOD milliseconds
990 * to perform continuous uCode event logging operation if enabled
991 */
992#define UCODE_TRACE_PERIOD (100)
993
994/*
995 * iwl_event_log: current uCode event log position
996 *
997 * @ucode_trace: enable/disable ucode continuous trace timer
998 * @num_wraps: how many times the event buffer wraps
999 * @next_entry: the entry just before the next one that uCode would fill
1000 * @non_wraps_count: counter for no wrap detected when dump ucode events
1001 * @wraps_once_count: counter for wrap once detected when dump ucode events
1002 * @wraps_more_count: counter for wrap more than once detected
1003 * when dump ucode events
1004 */
1005struct iwl_event_log {
1006 bool ucode_trace;
1007 u32 num_wraps;
1008 u32 next_entry;
1009 int non_wraps_count;
1010 int wraps_once_count;
1011 int wraps_more_count;
1012};
1013
987struct iwl_priv { 1014struct iwl_priv {
988 1015
989 /* ieee device used by generic ieee processing code */ 1016 /* ieee device used by generic ieee processing code */
@@ -1261,6 +1288,7 @@ struct iwl_priv {
1261 u32 disable_tx_power_cal; 1288 u32 disable_tx_power_cal;
1262 struct work_struct run_time_calib_work; 1289 struct work_struct run_time_calib_work;
1263 struct timer_list statistics_periodic; 1290 struct timer_list statistics_periodic;
1291 struct timer_list ucode_trace;
1264 bool hw_ready; 1292 bool hw_ready;
1265 /*For 3945*/ 1293 /*For 3945*/
1266#define IWL_DEFAULT_TX_POWER 0x0F 1294#define IWL_DEFAULT_TX_POWER 0x0F
@@ -1268,6 +1296,8 @@ struct iwl_priv {
1268 struct iwl3945_notif_statistics statistics_39; 1296 struct iwl3945_notif_statistics statistics_39;
1269 1297
1270 u32 sta_supp_rates; 1298 u32 sta_supp_rates;
1299
1300 struct iwl_event_log event_log;
1271}; /*iwl_priv */ 1301}; /*iwl_priv */
1272 1302
1273static inline void iwl_txq_ctx_activate(struct iwl_priv *priv, int txq_id) 1303static inline void iwl_txq_ctx_activate(struct iwl_priv *priv, int txq_id)
diff --git a/drivers/net/wireless/iwlwifi/iwl-devtrace.c b/drivers/net/wireless/iwlwifi/iwl-devtrace.c
index e7d88d1da15d..bf46308b17fa 100644
--- a/drivers/net/wireless/iwlwifi/iwl-devtrace.c
+++ b/drivers/net/wireless/iwlwifi/iwl-devtrace.c
@@ -11,4 +11,6 @@ EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_iowrite32);
11EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_rx); 11EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_rx);
12EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_ucode_event); 12EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_ucode_event);
13EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_ucode_error); 13EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_ucode_error);
14EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_ucode_cont_event);
15EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_ucode_wrap_event);
14#endif 16#endif
diff --git a/drivers/net/wireless/iwlwifi/iwl-devtrace.h b/drivers/net/wireless/iwlwifi/iwl-devtrace.h
index 21361968ab7e..0819f990be6c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-devtrace.h
+++ b/drivers/net/wireless/iwlwifi/iwl-devtrace.h
@@ -65,6 +65,50 @@ TRACE_EVENT(iwlwifi_dev_iowrite32,
65); 65);
66 66
67#undef TRACE_SYSTEM 67#undef TRACE_SYSTEM
68#define TRACE_SYSTEM iwlwifi_ucode
69
70TRACE_EVENT(iwlwifi_dev_ucode_cont_event,
71 TP_PROTO(struct iwl_priv *priv, u32 time, u32 data, u32 ev),
72 TP_ARGS(priv, time, data, ev),
73 TP_STRUCT__entry(
74 PRIV_ENTRY
75
76 __field(u32, time)
77 __field(u32, data)
78 __field(u32, ev)
79 ),
80 TP_fast_assign(
81 PRIV_ASSIGN;
82 __entry->time = time;
83 __entry->data = data;
84 __entry->ev = ev;
85 ),
86 TP_printk("[%p] EVT_LOGT:%010u:0x%08x:%04u",
87 __entry->priv, __entry->time, __entry->data, __entry->ev)
88);
89
90TRACE_EVENT(iwlwifi_dev_ucode_wrap_event,
91 TP_PROTO(struct iwl_priv *priv, u32 wraps, u32 n_entry, u32 p_entry),
92 TP_ARGS(priv, wraps, n_entry, p_entry),
93 TP_STRUCT__entry(
94 PRIV_ENTRY
95
96 __field(u32, wraps)
97 __field(u32, n_entry)
98 __field(u32, p_entry)
99 ),
100 TP_fast_assign(
101 PRIV_ASSIGN;
102 __entry->wraps = wraps;
103 __entry->n_entry = n_entry;
104 __entry->p_entry = p_entry;
105 ),
106 TP_printk("[%p] wraps=#%02d n=0x%X p=0x%X",
107 __entry->priv, __entry->wraps, __entry->n_entry,
108 __entry->p_entry)
109);
110
111#undef TRACE_SYSTEM
68#define TRACE_SYSTEM iwlwifi 112#define TRACE_SYSTEM iwlwifi
69 113
70TRACE_EVENT(iwlwifi_dev_hcmd, 114TRACE_EVENT(iwlwifi_dev_hcmd,
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index e5d8fa38432e..6533122ed87a 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -1559,8 +1559,9 @@ void iwl3945_dump_nic_error_log(struct iwl_priv *priv)
1559 * iwl3945_print_event_log - Dump error event log to syslog 1559 * iwl3945_print_event_log - Dump error event log to syslog
1560 * 1560 *
1561 */ 1561 */
1562static void iwl3945_print_event_log(struct iwl_priv *priv, u32 start_idx, 1562static int iwl3945_print_event_log(struct iwl_priv *priv, u32 start_idx,
1563 u32 num_events, u32 mode) 1563 u32 num_events, u32 mode,
1564 int pos, char **buf, size_t bufsz)
1564{ 1565{
1565 u32 i; 1566 u32 i;
1566 u32 base; /* SRAM byte address of event log header */ 1567 u32 base; /* SRAM byte address of event log header */
@@ -1570,7 +1571,7 @@ static void iwl3945_print_event_log(struct iwl_priv *priv, u32 start_idx,
1570 unsigned long reg_flags; 1571 unsigned long reg_flags;
1571 1572
1572 if (num_events == 0) 1573 if (num_events == 0)
1573 return; 1574 return pos;
1574 1575
1575 base = le32_to_cpu(priv->card_alive.log_event_table_ptr); 1576 base = le32_to_cpu(priv->card_alive.log_event_table_ptr);
1576 1577
@@ -1596,26 +1597,43 @@ static void iwl3945_print_event_log(struct iwl_priv *priv, u32 start_idx,
1596 time = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT); 1597 time = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT);
1597 if (mode == 0) { 1598 if (mode == 0) {
1598 /* data, ev */ 1599 /* data, ev */
1599 IWL_ERR(priv, "0x%08x\t%04u\n", time, ev); 1600 if (bufsz) {
1600 trace_iwlwifi_dev_ucode_event(priv, 0, time, ev); 1601 pos += scnprintf(*buf + pos, bufsz - pos,
1602 "0x%08x:%04u\n",
1603 time, ev);
1604 } else {
1605 IWL_ERR(priv, "0x%08x\t%04u\n", time, ev);
1606 trace_iwlwifi_dev_ucode_event(priv, 0,
1607 time, ev);
1608 }
1601 } else { 1609 } else {
1602 data = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT); 1610 data = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT);
1603 IWL_ERR(priv, "%010u\t0x%08x\t%04u\n", time, data, ev); 1611 if (bufsz) {
1604 trace_iwlwifi_dev_ucode_event(priv, time, data, ev); 1612 pos += scnprintf(*buf + pos, bufsz - pos,
1613 "%010u:0x%08x:%04u\n",
1614 time, data, ev);
1615 } else {
1616 IWL_ERR(priv, "%010u\t0x%08x\t%04u\n",
1617 time, data, ev);
1618 trace_iwlwifi_dev_ucode_event(priv, time,
1619 data, ev);
1620 }
1605 } 1621 }
1606 } 1622 }
1607 1623
1608 /* Allow device to power down */ 1624 /* Allow device to power down */
1609 iwl_release_nic_access(priv); 1625 iwl_release_nic_access(priv);
1610 spin_unlock_irqrestore(&priv->reg_lock, reg_flags); 1626 spin_unlock_irqrestore(&priv->reg_lock, reg_flags);
1627 return pos;
1611} 1628}
1612 1629
1613/** 1630/**
1614 * iwl3945_print_last_event_logs - Dump the newest # of event log to syslog 1631 * iwl3945_print_last_event_logs - Dump the newest # of event log to syslog
1615 */ 1632 */
1616static void iwl3945_print_last_event_logs(struct iwl_priv *priv, u32 capacity, 1633static int iwl3945_print_last_event_logs(struct iwl_priv *priv, u32 capacity,
1617 u32 num_wraps, u32 next_entry, 1634 u32 num_wraps, u32 next_entry,
1618 u32 size, u32 mode) 1635 u32 size, u32 mode,
1636 int pos, char **buf, size_t bufsz)
1619{ 1637{
1620 /* 1638 /*
1621 * display the newest DEFAULT_LOG_ENTRIES entries 1639 * display the newest DEFAULT_LOG_ENTRIES entries
@@ -1623,21 +1641,28 @@ static void iwl3945_print_last_event_logs(struct iwl_priv *priv, u32 capacity,
1623 */ 1641 */
1624 if (num_wraps) { 1642 if (num_wraps) {
1625 if (next_entry < size) { 1643 if (next_entry < size) {
1626 iwl3945_print_event_log(priv, 1644 pos = iwl3945_print_event_log(priv,
1627 capacity - (size - next_entry), 1645 capacity - (size - next_entry),
1628 size - next_entry, mode); 1646 size - next_entry, mode,
1629 iwl3945_print_event_log(priv, 0, 1647 pos, buf, bufsz);
1630 next_entry, mode); 1648 pos = iwl3945_print_event_log(priv, 0,
1649 next_entry, mode,
1650 pos, buf, bufsz);
1631 } else 1651 } else
1632 iwl3945_print_event_log(priv, next_entry - size, 1652 pos = iwl3945_print_event_log(priv, next_entry - size,
1633 size, mode); 1653 size, mode,
1654 pos, buf, bufsz);
1634 } else { 1655 } else {
1635 if (next_entry < size) 1656 if (next_entry < size)
1636 iwl3945_print_event_log(priv, 0, next_entry, mode); 1657 pos = iwl3945_print_event_log(priv, 0,
1658 next_entry, mode,
1659 pos, buf, bufsz);
1637 else 1660 else
1638 iwl3945_print_event_log(priv, next_entry - size, 1661 pos = iwl3945_print_event_log(priv, next_entry - size,
1639 size, mode); 1662 size, mode,
1663 pos, buf, bufsz);
1640 } 1664 }
1665 return pos;
1641} 1666}
1642 1667
1643/* For sanity check only. Actual size is determined by uCode, typ. 512 */ 1668/* For sanity check only. Actual size is determined by uCode, typ. 512 */
@@ -1645,7 +1670,8 @@ static void iwl3945_print_last_event_logs(struct iwl_priv *priv, u32 capacity,
1645 1670
1646#define DEFAULT_IWL3945_DUMP_EVENT_LOG_ENTRIES (20) 1671#define DEFAULT_IWL3945_DUMP_EVENT_LOG_ENTRIES (20)
1647 1672
1648void iwl3945_dump_nic_event_log(struct iwl_priv *priv, bool full_log) 1673int iwl3945_dump_nic_event_log(struct iwl_priv *priv, bool full_log,
1674 char **buf, bool display)
1649{ 1675{
1650 u32 base; /* SRAM byte address of event log header */ 1676 u32 base; /* SRAM byte address of event log header */
1651 u32 capacity; /* event log capacity in # entries */ 1677 u32 capacity; /* event log capacity in # entries */
@@ -1653,11 +1679,13 @@ void iwl3945_dump_nic_event_log(struct iwl_priv *priv, bool full_log)
1653 u32 num_wraps; /* # times uCode wrapped to top of log */ 1679 u32 num_wraps; /* # times uCode wrapped to top of log */
1654 u32 next_entry; /* index of next entry to be written by uCode */ 1680 u32 next_entry; /* index of next entry to be written by uCode */
1655 u32 size; /* # entries that we'll print */ 1681 u32 size; /* # entries that we'll print */
1682 int pos = 0;
1683 size_t bufsz = 0;
1656 1684
1657 base = le32_to_cpu(priv->card_alive.log_event_table_ptr); 1685 base = le32_to_cpu(priv->card_alive.log_event_table_ptr);
1658 if (!iwl3945_hw_valid_rtc_data_addr(base)) { 1686 if (!iwl3945_hw_valid_rtc_data_addr(base)) {
1659 IWL_ERR(priv, "Invalid event log pointer 0x%08X\n", base); 1687 IWL_ERR(priv, "Invalid event log pointer 0x%08X\n", base);
1660 return; 1688 return pos;
1661 } 1689 }
1662 1690
1663 /* event log header */ 1691 /* event log header */
@@ -1683,7 +1711,7 @@ void iwl3945_dump_nic_event_log(struct iwl_priv *priv, bool full_log)
1683 /* bail out if nothing in log */ 1711 /* bail out if nothing in log */
1684 if (size == 0) { 1712 if (size == 0) {
1685 IWL_ERR(priv, "Start IWL Event Log Dump: nothing in log\n"); 1713 IWL_ERR(priv, "Start IWL Event Log Dump: nothing in log\n");
1686 return; 1714 return pos;
1687 } 1715 }
1688 1716
1689#ifdef CONFIG_IWLWIFI_DEBUG 1717#ifdef CONFIG_IWLWIFI_DEBUG
@@ -1699,25 +1727,38 @@ void iwl3945_dump_nic_event_log(struct iwl_priv *priv, bool full_log)
1699 size); 1727 size);
1700 1728
1701#ifdef CONFIG_IWLWIFI_DEBUG 1729#ifdef CONFIG_IWLWIFI_DEBUG
1730 if (display) {
1731 if (full_log)
1732 bufsz = capacity * 48;
1733 else
1734 bufsz = size * 48;
1735 *buf = kmalloc(bufsz, GFP_KERNEL);
1736 if (!*buf)
1737 return pos;
1738 }
1702 if ((iwl_get_debug_level(priv) & IWL_DL_FW_ERRORS) || full_log) { 1739 if ((iwl_get_debug_level(priv) & IWL_DL_FW_ERRORS) || full_log) {
1703 /* if uCode has wrapped back to top of log, 1740 /* if uCode has wrapped back to top of log,
1704 * start at the oldest entry, 1741 * start at the oldest entry,
1705 * i.e the next one that uCode would fill. 1742 * i.e the next one that uCode would fill.
1706 */ 1743 */
1707 if (num_wraps) 1744 if (num_wraps)
1708 iwl3945_print_event_log(priv, next_entry, 1745 pos = iwl3945_print_event_log(priv, next_entry,
1709 capacity - next_entry, mode); 1746 capacity - next_entry, mode,
1747 pos, buf, bufsz);
1710 1748
1711 /* (then/else) start at top of log */ 1749 /* (then/else) start at top of log */
1712 iwl3945_print_event_log(priv, 0, next_entry, mode); 1750 pos = iwl3945_print_event_log(priv, 0, next_entry, mode,
1751 pos, buf, bufsz);
1713 } else 1752 } else
1714 iwl3945_print_last_event_logs(priv, capacity, num_wraps, 1753 pos = iwl3945_print_last_event_logs(priv, capacity, num_wraps,
1715 next_entry, size, mode); 1754 next_entry, size, mode,
1755 pos, buf, bufsz);
1716#else 1756#else
1717 iwl3945_print_last_event_logs(priv, capacity, num_wraps, 1757 pos = iwl3945_print_last_event_logs(priv, capacity, num_wraps,
1718 next_entry, size, mode); 1758 next_entry, size, mode,
1759 pos, buf, bufsz);
1719#endif 1760#endif
1720 1761 return pos;
1721} 1762}
1722 1763
1723static void iwl3945_irq_tasklet(struct iwl_priv *priv) 1764static void iwl3945_irq_tasklet(struct iwl_priv *priv)
diff --git a/drivers/net/wireless/iwmc3200wifi/rx.c b/drivers/net/wireless/iwmc3200wifi/rx.c
index 6d6ed7485175..d32adeab68a3 100644
--- a/drivers/net/wireless/iwmc3200wifi/rx.c
+++ b/drivers/net/wireless/iwmc3200wifi/rx.c
@@ -868,36 +868,35 @@ static int iwm_mlme_mgt_frame(struct iwm_priv *iwm, u8 *buf,
868 struct iwm_umac_notif_mgt_frame *mgt_frame = 868 struct iwm_umac_notif_mgt_frame *mgt_frame =
869 (struct iwm_umac_notif_mgt_frame *)buf; 869 (struct iwm_umac_notif_mgt_frame *)buf;
870 struct ieee80211_mgmt *mgt = (struct ieee80211_mgmt *)mgt_frame->frame; 870 struct ieee80211_mgmt *mgt = (struct ieee80211_mgmt *)mgt_frame->frame;
871 u8 *ie;
872 871
873 IWM_HEXDUMP(iwm, DBG, MLME, "MGT: ", mgt_frame->frame, 872 IWM_HEXDUMP(iwm, DBG, MLME, "MGT: ", mgt_frame->frame,
874 le16_to_cpu(mgt_frame->len)); 873 le16_to_cpu(mgt_frame->len));
875 874
876 if (ieee80211_is_assoc_req(mgt->frame_control)) { 875 if (ieee80211_is_assoc_req(mgt->frame_control)) {
877 ie = mgt->u.assoc_req.variable;; 876 iwm->req_ie_len = le16_to_cpu(mgt_frame->len)
878 iwm->req_ie_len = 877 - offsetof(struct ieee80211_mgmt,
879 le16_to_cpu(mgt_frame->len) - (ie - (u8 *)mgt); 878 u.assoc_req.variable);
880 kfree(iwm->req_ie); 879 kfree(iwm->req_ie);
881 iwm->req_ie = kmemdup(mgt->u.assoc_req.variable, 880 iwm->req_ie = kmemdup(mgt->u.assoc_req.variable,
882 iwm->req_ie_len, GFP_KERNEL); 881 iwm->req_ie_len, GFP_KERNEL);
883 } else if (ieee80211_is_reassoc_req(mgt->frame_control)) { 882 } else if (ieee80211_is_reassoc_req(mgt->frame_control)) {
884 ie = mgt->u.reassoc_req.variable;; 883 iwm->req_ie_len = le16_to_cpu(mgt_frame->len)
885 iwm->req_ie_len = 884 - offsetof(struct ieee80211_mgmt,
886 le16_to_cpu(mgt_frame->len) - (ie - (u8 *)mgt); 885 u.reassoc_req.variable);
887 kfree(iwm->req_ie); 886 kfree(iwm->req_ie);
888 iwm->req_ie = kmemdup(mgt->u.reassoc_req.variable, 887 iwm->req_ie = kmemdup(mgt->u.reassoc_req.variable,
889 iwm->req_ie_len, GFP_KERNEL); 888 iwm->req_ie_len, GFP_KERNEL);
890 } else if (ieee80211_is_assoc_resp(mgt->frame_control)) { 889 } else if (ieee80211_is_assoc_resp(mgt->frame_control)) {
891 ie = mgt->u.assoc_resp.variable;; 890 iwm->resp_ie_len = le16_to_cpu(mgt_frame->len)
892 iwm->resp_ie_len = 891 - offsetof(struct ieee80211_mgmt,
893 le16_to_cpu(mgt_frame->len) - (ie - (u8 *)mgt); 892 u.assoc_resp.variable);
894 kfree(iwm->resp_ie); 893 kfree(iwm->resp_ie);
895 iwm->resp_ie = kmemdup(mgt->u.assoc_resp.variable, 894 iwm->resp_ie = kmemdup(mgt->u.assoc_resp.variable,
896 iwm->resp_ie_len, GFP_KERNEL); 895 iwm->resp_ie_len, GFP_KERNEL);
897 } else if (ieee80211_is_reassoc_resp(mgt->frame_control)) { 896 } else if (ieee80211_is_reassoc_resp(mgt->frame_control)) {
898 ie = mgt->u.reassoc_resp.variable;; 897 iwm->resp_ie_len = le16_to_cpu(mgt_frame->len)
899 iwm->resp_ie_len = 898 - offsetof(struct ieee80211_mgmt,
900 le16_to_cpu(mgt_frame->len) - (ie - (u8 *)mgt); 899 u.reassoc_resp.variable);
901 kfree(iwm->resp_ie); 900 kfree(iwm->resp_ie);
902 iwm->resp_ie = kmemdup(mgt->u.reassoc_resp.variable, 901 iwm->resp_ie = kmemdup(mgt->u.reassoc_resp.variable,
903 iwm->resp_ie_len, GFP_KERNEL); 902 iwm->resp_ie_len, GFP_KERNEL);
@@ -1534,6 +1533,33 @@ static void classify8023(struct sk_buff *skb)
1534 } 1533 }
1535} 1534}
1536 1535
1536static void iwm_rx_process_amsdu(struct iwm_priv *iwm, struct sk_buff *skb)
1537{
1538 struct wireless_dev *wdev = iwm_to_wdev(iwm);
1539 struct net_device *ndev = iwm_to_ndev(iwm);
1540 struct sk_buff_head list;
1541 struct sk_buff *frame;
1542
1543 IWM_HEXDUMP(iwm, DBG, RX, "A-MSDU: ", skb->data, skb->len);
1544
1545 __skb_queue_head_init(&list);
1546 ieee80211_amsdu_to_8023s(skb, &list, ndev->dev_addr, wdev->iftype, 0);
1547
1548 while ((frame = __skb_dequeue(&list))) {
1549 ndev->stats.rx_packets++;
1550 ndev->stats.rx_bytes += frame->len;
1551
1552 frame->protocol = eth_type_trans(frame, ndev);
1553 frame->ip_summed = CHECKSUM_NONE;
1554 memset(frame->cb, 0, sizeof(frame->cb));
1555
1556 if (netif_rx_ni(frame) == NET_RX_DROP) {
1557 IWM_ERR(iwm, "Packet dropped\n");
1558 ndev->stats.rx_dropped++;
1559 }
1560 }
1561}
1562
1537static void iwm_rx_process_packet(struct iwm_priv *iwm, 1563static void iwm_rx_process_packet(struct iwm_priv *iwm,
1538 struct iwm_rx_packet *packet, 1564 struct iwm_rx_packet *packet,
1539 struct iwm_rx_ticket_node *ticket_node) 1565 struct iwm_rx_ticket_node *ticket_node)
@@ -1548,25 +1574,34 @@ static void iwm_rx_process_packet(struct iwm_priv *iwm,
1548 switch (le16_to_cpu(ticket_node->ticket->action)) { 1574 switch (le16_to_cpu(ticket_node->ticket->action)) {
1549 case IWM_RX_TICKET_RELEASE: 1575 case IWM_RX_TICKET_RELEASE:
1550 IWM_DBG_RX(iwm, DBG, "RELEASE packet\n"); 1576 IWM_DBG_RX(iwm, DBG, "RELEASE packet\n");
1551 classify8023(skb); 1577
1552 iwm_rx_adjust_packet(iwm, packet, ticket_node); 1578 iwm_rx_adjust_packet(iwm, packet, ticket_node);
1579 skb->dev = iwm_to_ndev(iwm);
1580 classify8023(skb);
1581
1582 if (le16_to_cpu(ticket_node->ticket->flags) &
1583 IWM_RX_TICKET_AMSDU_MSK) {
1584 iwm_rx_process_amsdu(iwm, skb);
1585 break;
1586 }
1587
1553 ret = ieee80211_data_to_8023(skb, ndev->dev_addr, wdev->iftype); 1588 ret = ieee80211_data_to_8023(skb, ndev->dev_addr, wdev->iftype);
1554 if (ret < 0) { 1589 if (ret < 0) {
1555 IWM_DBG_RX(iwm, DBG, "Couldn't convert 802.11 header - " 1590 IWM_DBG_RX(iwm, DBG, "Couldn't convert 802.11 header - "
1556 "%d\n", ret); 1591 "%d\n", ret);
1592 kfree_skb(packet->skb);
1557 break; 1593 break;
1558 } 1594 }
1559 1595
1560 IWM_HEXDUMP(iwm, DBG, RX, "802.3: ", skb->data, skb->len); 1596 IWM_HEXDUMP(iwm, DBG, RX, "802.3: ", skb->data, skb->len);
1561 1597
1562 skb->dev = iwm_to_ndev(iwm); 1598 ndev->stats.rx_packets++;
1599 ndev->stats.rx_bytes += skb->len;
1600
1563 skb->protocol = eth_type_trans(skb, ndev); 1601 skb->protocol = eth_type_trans(skb, ndev);
1564 skb->ip_summed = CHECKSUM_NONE; 1602 skb->ip_summed = CHECKSUM_NONE;
1565 memset(skb->cb, 0, sizeof(skb->cb)); 1603 memset(skb->cb, 0, sizeof(skb->cb));
1566 1604
1567 ndev->stats.rx_packets++;
1568 ndev->stats.rx_bytes += skb->len;
1569
1570 if (netif_rx_ni(skb) == NET_RX_DROP) { 1605 if (netif_rx_ni(skb) == NET_RX_DROP) {
1571 IWM_ERR(iwm, "Packet dropped\n"); 1606 IWM_ERR(iwm, "Packet dropped\n");
1572 ndev->stats.rx_dropped++; 1607 ndev->stats.rx_dropped++;
diff --git a/drivers/net/wireless/libertas/Kconfig b/drivers/net/wireless/libertas/Kconfig
index 30aa9d48d67e..0485c9957575 100644
--- a/drivers/net/wireless/libertas/Kconfig
+++ b/drivers/net/wireless/libertas/Kconfig
@@ -37,3 +37,9 @@ config LIBERTAS_DEBUG
37 depends on LIBERTAS 37 depends on LIBERTAS
38 ---help--- 38 ---help---
39 Debugging support. 39 Debugging support.
40
41config LIBERTAS_MESH
42 bool "Enable mesh support"
43 depends on LIBERTAS
44 help
45 This enables Libertas' MESH support, used by e.g. the OLPC people.
diff --git a/drivers/net/wireless/libertas/Makefile b/drivers/net/wireless/libertas/Makefile
index b188cd97a053..45e870e33117 100644
--- a/drivers/net/wireless/libertas/Makefile
+++ b/drivers/net/wireless/libertas/Makefile
@@ -5,11 +5,11 @@ libertas-y += cmdresp.o
5libertas-y += debugfs.o 5libertas-y += debugfs.o
6libertas-y += ethtool.o 6libertas-y += ethtool.o
7libertas-y += main.o 7libertas-y += main.o
8libertas-y += mesh.o
9libertas-y += rx.o 8libertas-y += rx.o
10libertas-y += scan.o 9libertas-y += scan.o
11libertas-y += tx.o 10libertas-y += tx.o
12libertas-y += wext.o 11libertas-y += wext.o
12libertas-$(CONFIG_LIBERTAS_MESH) += mesh.o
13 13
14usb8xxx-objs += if_usb.o 14usb8xxx-objs += if_usb.o
15libertas_cs-objs += if_cs.o 15libertas_cs-objs += if_cs.o
diff --git a/drivers/net/wireless/libertas/assoc.c b/drivers/net/wireless/libertas/assoc.c
index 751067369ba8..5e650f358415 100644
--- a/drivers/net/wireless/libertas/assoc.c
+++ b/drivers/net/wireless/libertas/assoc.c
@@ -390,10 +390,8 @@ int lbs_cmd_802_11_rate_adapt_rateset(struct lbs_private *priv,
390 cmd.enablehwauto = cpu_to_le16(priv->enablehwauto); 390 cmd.enablehwauto = cpu_to_le16(priv->enablehwauto);
391 cmd.bitmap = lbs_rate_to_fw_bitmap(priv->cur_rate, priv->enablehwauto); 391 cmd.bitmap = lbs_rate_to_fw_bitmap(priv->cur_rate, priv->enablehwauto);
392 ret = lbs_cmd_with_response(priv, CMD_802_11_RATE_ADAPT_RATESET, &cmd); 392 ret = lbs_cmd_with_response(priv, CMD_802_11_RATE_ADAPT_RATESET, &cmd);
393 if (!ret && cmd_action == CMD_ACT_GET) { 393 if (!ret && cmd_action == CMD_ACT_GET)
394 priv->ratebitmap = le16_to_cpu(cmd.bitmap);
395 priv->enablehwauto = le16_to_cpu(cmd.enablehwauto); 394 priv->enablehwauto = le16_to_cpu(cmd.enablehwauto);
396 }
397 395
398 lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret); 396 lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
399 return ret; 397 return ret;
@@ -807,8 +805,7 @@ static int lbs_try_associate(struct lbs_private *priv,
807 } 805 }
808 806
809 /* Use short preamble only when both the BSS and firmware support it */ 807 /* Use short preamble only when both the BSS and firmware support it */
810 if ((priv->capability & WLAN_CAPABILITY_SHORT_PREAMBLE) && 808 if (assoc_req->bss.capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
811 (assoc_req->bss.capability & WLAN_CAPABILITY_SHORT_PREAMBLE))
812 preamble = RADIO_PREAMBLE_SHORT; 809 preamble = RADIO_PREAMBLE_SHORT;
813 810
814 ret = lbs_set_radio(priv, preamble, 1); 811 ret = lbs_set_radio(priv, preamble, 1);
@@ -939,8 +936,7 @@ static int lbs_adhoc_join(struct lbs_private *priv,
939 } 936 }
940 937
941 /* Use short preamble only when both the BSS and firmware support it */ 938 /* Use short preamble only when both the BSS and firmware support it */
942 if ((priv->capability & WLAN_CAPABILITY_SHORT_PREAMBLE) && 939 if (bss->capability & WLAN_CAPABILITY_SHORT_PREAMBLE) {
943 (bss->capability & WLAN_CAPABILITY_SHORT_PREAMBLE)) {
944 lbs_deb_join("AdhocJoin: Short preamble\n"); 940 lbs_deb_join("AdhocJoin: Short preamble\n");
945 preamble = RADIO_PREAMBLE_SHORT; 941 preamble = RADIO_PREAMBLE_SHORT;
946 } 942 }
@@ -1049,7 +1045,7 @@ static int lbs_adhoc_start(struct lbs_private *priv,
1049 struct assoc_request *assoc_req) 1045 struct assoc_request *assoc_req)
1050{ 1046{
1051 struct cmd_ds_802_11_ad_hoc_start cmd; 1047 struct cmd_ds_802_11_ad_hoc_start cmd;
1052 u8 preamble = RADIO_PREAMBLE_LONG; 1048 u8 preamble = RADIO_PREAMBLE_SHORT;
1053 size_t ratesize = 0; 1049 size_t ratesize = 0;
1054 u16 tmpcap = 0; 1050 u16 tmpcap = 0;
1055 int ret = 0; 1051 int ret = 0;
@@ -1057,11 +1053,6 @@ static int lbs_adhoc_start(struct lbs_private *priv,
1057 1053
1058 lbs_deb_enter(LBS_DEB_ASSOC); 1054 lbs_deb_enter(LBS_DEB_ASSOC);
1059 1055
1060 if (priv->capability & WLAN_CAPABILITY_SHORT_PREAMBLE) {
1061 lbs_deb_join("ADHOC_START: Will use short preamble\n");
1062 preamble = RADIO_PREAMBLE_SHORT;
1063 }
1064
1065 ret = lbs_set_radio(priv, preamble, 1); 1056 ret = lbs_set_radio(priv, preamble, 1);
1066 if (ret) 1057 if (ret)
1067 goto out; 1058 goto out;
diff --git a/drivers/net/wireless/libertas/cmd.c b/drivers/net/wireless/libertas/cmd.c
index 42611bea76a3..82371ef39524 100644
--- a/drivers/net/wireless/libertas/cmd.c
+++ b/drivers/net/wireless/libertas/cmd.c
@@ -143,19 +143,6 @@ int lbs_update_hw_spec(struct lbs_private *priv)
143 lbs_deb_cmd("GET_HW_SPEC: hardware interface 0x%x, hardware spec 0x%04x\n", 143 lbs_deb_cmd("GET_HW_SPEC: hardware interface 0x%x, hardware spec 0x%04x\n",
144 cmd.hwifversion, cmd.version); 144 cmd.hwifversion, cmd.version);
145 145
146 /* Determine mesh_fw_ver from fwrelease and fwcapinfo */
147 /* 5.0.16p0 9.0.0.p0 is known to NOT support any mesh */
148 /* 5.110.22 have mesh command with 0xa3 command id */
149 /* 10.0.0.p0 FW brings in mesh config command with different id */
150 /* Check FW version MSB and initialize mesh_fw_ver */
151 if (MRVL_FW_MAJOR_REV(priv->fwrelease) == MRVL_FW_V5)
152 priv->mesh_fw_ver = MESH_FW_OLD;
153 else if ((MRVL_FW_MAJOR_REV(priv->fwrelease) >= MRVL_FW_V10) &&
154 (priv->fwcapinfo & MESH_CAPINFO_ENABLE_MASK))
155 priv->mesh_fw_ver = MESH_FW_NEW;
156 else
157 priv->mesh_fw_ver = MESH_NONE;
158
159 /* Clamp region code to 8-bit since FW spec indicates that it should 146 /* Clamp region code to 8-bit since FW spec indicates that it should
160 * only ever be 8-bit, even though the field size is 16-bit. Some firmware 147 * only ever be 8-bit, even though the field size is 16-bit. Some firmware
161 * returns non-zero high 8 bits here. 148 * returns non-zero high 8 bits here.
@@ -855,9 +842,6 @@ int lbs_set_radio(struct lbs_private *priv, u8 preamble, u8 radio_on)
855 if (priv->fwrelease < 0x09000000) { 842 if (priv->fwrelease < 0x09000000) {
856 switch (preamble) { 843 switch (preamble) {
857 case RADIO_PREAMBLE_SHORT: 844 case RADIO_PREAMBLE_SHORT:
858 if (!(priv->capability & WLAN_CAPABILITY_SHORT_PREAMBLE))
859 goto out;
860 /* Fall through */
861 case RADIO_PREAMBLE_AUTO: 845 case RADIO_PREAMBLE_AUTO:
862 case RADIO_PREAMBLE_LONG: 846 case RADIO_PREAMBLE_LONG:
863 cmd.control = cpu_to_le16(preamble); 847 cmd.control = cpu_to_le16(preamble);
@@ -1011,6 +995,8 @@ int lbs_prepare_and_send_command(struct lbs_private *priv,
1011 ret = 0; 995 ret = 0;
1012 break; 996 break;
1013 997
998#ifdef CONFIG_LIBERTAS_MESH
999
1014 case CMD_BT_ACCESS: 1000 case CMD_BT_ACCESS:
1015 ret = lbs_cmd_bt_access(cmdptr, cmd_action, pdata_buf); 1001 ret = lbs_cmd_bt_access(cmdptr, cmd_action, pdata_buf);
1016 break; 1002 break;
@@ -1019,6 +1005,8 @@ int lbs_prepare_and_send_command(struct lbs_private *priv,
1019 ret = lbs_cmd_fwt_access(cmdptr, cmd_action, pdata_buf); 1005 ret = lbs_cmd_fwt_access(cmdptr, cmd_action, pdata_buf);
1020 break; 1006 break;
1021 1007
1008#endif
1009
1022 case CMD_802_11_BEACON_CTRL: 1010 case CMD_802_11_BEACON_CTRL:
1023 ret = lbs_cmd_bcn_ctrl(priv, cmdptr, cmd_action); 1011 ret = lbs_cmd_bcn_ctrl(priv, cmdptr, cmd_action);
1024 break; 1012 break;
@@ -1317,7 +1305,7 @@ int lbs_execute_next_command(struct lbs_private *priv)
1317 if ((priv->psmode != LBS802_11POWERMODECAM) && 1305 if ((priv->psmode != LBS802_11POWERMODECAM) &&
1318 (priv->psstate == PS_STATE_FULL_POWER) && 1306 (priv->psstate == PS_STATE_FULL_POWER) &&
1319 ((priv->connect_status == LBS_CONNECTED) || 1307 ((priv->connect_status == LBS_CONNECTED) ||
1320 (priv->mesh_connect_status == LBS_CONNECTED))) { 1308 lbs_mesh_connected(priv))) {
1321 if (priv->secinfo.WPAenabled || 1309 if (priv->secinfo.WPAenabled ||
1322 priv->secinfo.WPA2enabled) { 1310 priv->secinfo.WPA2enabled) {
1323 /* check for valid WPA group keys */ 1311 /* check for valid WPA group keys */
diff --git a/drivers/net/wireless/libertas/cmd.h b/drivers/net/wireless/libertas/cmd.h
index 2862748aef70..cb4138a55fdf 100644
--- a/drivers/net/wireless/libertas/cmd.h
+++ b/drivers/net/wireless/libertas/cmd.h
@@ -110,18 +110,6 @@ int lbs_set_snmp_mib(struct lbs_private *priv, u32 oid, u16 val);
110int lbs_get_snmp_mib(struct lbs_private *priv, u32 oid, u16 *out_val); 110int lbs_get_snmp_mib(struct lbs_private *priv, u32 oid, u16 *out_val);
111 111
112 112
113/* Mesh related */
114
115int lbs_mesh_access(struct lbs_private *priv, uint16_t cmd_action,
116 struct cmd_ds_mesh_access *cmd);
117
118int lbs_mesh_config_send(struct lbs_private *priv,
119 struct cmd_ds_mesh_config *cmd,
120 uint16_t action, uint16_t type);
121
122int lbs_mesh_config(struct lbs_private *priv, uint16_t enable, uint16_t chan);
123
124
125/* Commands only used in wext.c, assoc. and scan.c */ 113/* Commands only used in wext.c, assoc. and scan.c */
126 114
127int lbs_set_power_adapt_cfg(struct lbs_private *priv, int enable, int8_t p0, 115int lbs_set_power_adapt_cfg(struct lbs_private *priv, int enable, int8_t p0,
diff --git a/drivers/net/wireless/libertas/cmdresp.c b/drivers/net/wireless/libertas/cmdresp.c
index 21d57690c20a..0334a58820ee 100644
--- a/drivers/net/wireless/libertas/cmdresp.c
+++ b/drivers/net/wireless/libertas/cmdresp.c
@@ -485,20 +485,8 @@ int lbs_process_event(struct lbs_private *priv, u32 event)
485 break; 485 break;
486 486
487 case MACREG_INT_CODE_MESH_AUTO_STARTED: 487 case MACREG_INT_CODE_MESH_AUTO_STARTED:
488 /* Ignore spurious autostart events if autostart is disabled */ 488 /* Ignore spurious autostart events */
489 if (!priv->mesh_autostart_enabled) { 489 lbs_pr_info("EVENT: MESH_AUTO_STARTED (ignoring)\n");
490 lbs_pr_info("EVENT: MESH_AUTO_STARTED (ignoring)\n");
491 break;
492 }
493 lbs_pr_info("EVENT: MESH_AUTO_STARTED\n");
494 priv->mesh_connect_status = LBS_CONNECTED;
495 if (priv->mesh_open) {
496 netif_carrier_on(priv->mesh_dev);
497 if (!priv->tx_pending_len)
498 netif_wake_queue(priv->mesh_dev);
499 }
500 priv->mode = IW_MODE_ADHOC;
501 schedule_work(&priv->sync_channel);
502 break; 490 break;
503 491
504 default: 492 default:
diff --git a/drivers/net/wireless/libertas/defs.h b/drivers/net/wireless/libertas/defs.h
index 6b6ea9f7bf5b..ea3f10ef4e00 100644
--- a/drivers/net/wireless/libertas/defs.h
+++ b/drivers/net/wireless/libertas/defs.h
@@ -397,13 +397,6 @@ enum KEY_INFO_WPA {
397 KEY_INFO_WPA_ENABLED = 0x04 397 KEY_INFO_WPA_ENABLED = 0x04
398}; 398};
399 399
400/** mesh_fw_ver */
401enum _mesh_fw_ver {
402 MESH_NONE = 0, /* MESH is not supported */
403 MESH_FW_OLD, /* MESH is supported in FW V5 */
404 MESH_FW_NEW, /* MESH is supported in FW V10 and newer */
405};
406
407/* Default values for fwt commands. */ 400/* Default values for fwt commands. */
408#define FWT_DEFAULT_METRIC 0 401#define FWT_DEFAULT_METRIC 0
409#define FWT_DEFAULT_DIR 1 402#define FWT_DEFAULT_DIR 1
diff --git a/drivers/net/wireless/libertas/dev.h b/drivers/net/wireless/libertas/dev.h
index 05bb298dfae9..c348aff8f309 100644
--- a/drivers/net/wireless/libertas/dev.h
+++ b/drivers/net/wireless/libertas/dev.h
@@ -39,15 +39,14 @@ struct lbs_private {
39 39
40 /* Mesh */ 40 /* Mesh */
41 struct net_device *mesh_dev; /* Virtual device */ 41 struct net_device *mesh_dev; /* Virtual device */
42#ifdef CONFIG_LIBERTAS_MESH
42 u32 mesh_connect_status; 43 u32 mesh_connect_status;
43 struct lbs_mesh_stats mstats; 44 struct lbs_mesh_stats mstats;
44 int mesh_open; 45 int mesh_open;
45 int mesh_fw_ver;
46 int mesh_autostart_enabled;
47 uint16_t mesh_tlv; 46 uint16_t mesh_tlv;
48 u8 mesh_ssid[IEEE80211_MAX_SSID_LEN + 1]; 47 u8 mesh_ssid[IEEE80211_MAX_SSID_LEN + 1];
49 u8 mesh_ssid_len; 48 u8 mesh_ssid_len;
50 struct work_struct sync_channel; 49#endif
51 50
52 /* Monitor mode */ 51 /* Monitor mode */
53 struct net_device *rtap_net_dev; 52 struct net_device *rtap_net_dev;
@@ -176,9 +175,7 @@ struct lbs_private {
176 struct bss_descriptor *networks; 175 struct bss_descriptor *networks;
177 struct assoc_request * pending_assoc_req; 176 struct assoc_request * pending_assoc_req;
178 struct assoc_request * in_progress_assoc_req; 177 struct assoc_request * in_progress_assoc_req;
179 u16 capability;
180 uint16_t enablehwauto; 178 uint16_t enablehwauto;
181 uint16_t ratebitmap;
182 179
183 /* ADHOC */ 180 /* ADHOC */
184 u16 beacon_period; 181 u16 beacon_period;
diff --git a/drivers/net/wireless/libertas/ethtool.c b/drivers/net/wireless/libertas/ethtool.c
index 63d020374c2b..3804a58d7f4e 100644
--- a/drivers/net/wireless/libertas/ethtool.c
+++ b/drivers/net/wireless/libertas/ethtool.c
@@ -114,9 +114,11 @@ const struct ethtool_ops lbs_ethtool_ops = {
114 .get_drvinfo = lbs_ethtool_get_drvinfo, 114 .get_drvinfo = lbs_ethtool_get_drvinfo,
115 .get_eeprom = lbs_ethtool_get_eeprom, 115 .get_eeprom = lbs_ethtool_get_eeprom,
116 .get_eeprom_len = lbs_ethtool_get_eeprom_len, 116 .get_eeprom_len = lbs_ethtool_get_eeprom_len,
117#ifdef CONFIG_LIBERTAS_MESH
117 .get_sset_count = lbs_mesh_ethtool_get_sset_count, 118 .get_sset_count = lbs_mesh_ethtool_get_sset_count,
118 .get_ethtool_stats = lbs_mesh_ethtool_get_stats, 119 .get_ethtool_stats = lbs_mesh_ethtool_get_stats,
119 .get_strings = lbs_mesh_ethtool_get_strings, 120 .get_strings = lbs_mesh_ethtool_get_strings,
121#endif
120 .get_wol = lbs_ethtool_get_wol, 122 .get_wol = lbs_ethtool_get_wol,
121 .set_wol = lbs_ethtool_set_wol, 123 .set_wol = lbs_ethtool_set_wol,
122}; 124};
diff --git a/drivers/net/wireless/libertas/main.c b/drivers/net/wireless/libertas/main.c
index c2975c8e2f21..60bde1233a30 100644
--- a/drivers/net/wireless/libertas/main.c
+++ b/drivers/net/wireless/libertas/main.c
@@ -123,7 +123,7 @@ static ssize_t lbs_rtap_set(struct device *dev,
123 if (priv->monitormode == monitor_mode) 123 if (priv->monitormode == monitor_mode)
124 return strlen(buf); 124 return strlen(buf);
125 if (!priv->monitormode) { 125 if (!priv->monitormode) {
126 if (priv->infra_open || priv->mesh_open) 126 if (priv->infra_open || lbs_mesh_open(priv))
127 return -EBUSY; 127 return -EBUSY;
128 if (priv->mode == IW_MODE_INFRA) 128 if (priv->mode == IW_MODE_INFRA)
129 lbs_cmd_80211_deauthenticate(priv, 129 lbs_cmd_80211_deauthenticate(priv,
@@ -622,7 +622,7 @@ static int lbs_thread(void *data)
622 if (priv->connect_status == LBS_CONNECTED) 622 if (priv->connect_status == LBS_CONNECTED)
623 netif_wake_queue(priv->dev); 623 netif_wake_queue(priv->dev);
624 if (priv->mesh_dev && 624 if (priv->mesh_dev &&
625 priv->mesh_connect_status == LBS_CONNECTED) 625 lbs_mesh_connected(priv))
626 netif_wake_queue(priv->mesh_dev); 626 netif_wake_queue(priv->mesh_dev);
627 } 627 }
628 } 628 }
@@ -809,18 +809,6 @@ int lbs_exit_auto_deep_sleep(struct lbs_private *priv)
809 return 0; 809 return 0;
810} 810}
811 811
812static void lbs_sync_channel_worker(struct work_struct *work)
813{
814 struct lbs_private *priv = container_of(work, struct lbs_private,
815 sync_channel);
816
817 lbs_deb_enter(LBS_DEB_MAIN);
818 if (lbs_update_channel(priv))
819 lbs_pr_info("Channel synchronization failed.");
820 lbs_deb_leave(LBS_DEB_MAIN);
821}
822
823
824static int lbs_init_adapter(struct lbs_private *priv) 812static int lbs_init_adapter(struct lbs_private *priv)
825{ 813{
826 size_t bufsize; 814 size_t bufsize;
@@ -848,14 +836,12 @@ static int lbs_init_adapter(struct lbs_private *priv)
848 memset(priv->current_addr, 0xff, ETH_ALEN); 836 memset(priv->current_addr, 0xff, ETH_ALEN);
849 837
850 priv->connect_status = LBS_DISCONNECTED; 838 priv->connect_status = LBS_DISCONNECTED;
851 priv->mesh_connect_status = LBS_DISCONNECTED;
852 priv->secinfo.auth_mode = IW_AUTH_ALG_OPEN_SYSTEM; 839 priv->secinfo.auth_mode = IW_AUTH_ALG_OPEN_SYSTEM;
853 priv->mode = IW_MODE_INFRA; 840 priv->mode = IW_MODE_INFRA;
854 priv->channel = DEFAULT_AD_HOC_CHANNEL; 841 priv->channel = DEFAULT_AD_HOC_CHANNEL;
855 priv->mac_control = CMD_ACT_MAC_RX_ON | CMD_ACT_MAC_TX_ON; 842 priv->mac_control = CMD_ACT_MAC_RX_ON | CMD_ACT_MAC_TX_ON;
856 priv->radio_on = 1; 843 priv->radio_on = 1;
857 priv->enablehwauto = 1; 844 priv->enablehwauto = 1;
858 priv->capability = WLAN_CAPABILITY_SHORT_PREAMBLE;
859 priv->psmode = LBS802_11POWERMODECAM; 845 priv->psmode = LBS802_11POWERMODECAM;
860 priv->psstate = PS_STATE_FULL_POWER; 846 priv->psstate = PS_STATE_FULL_POWER;
861 priv->is_deep_sleep = 0; 847 priv->is_deep_sleep = 0;
@@ -998,11 +984,6 @@ struct lbs_private *lbs_add_card(void *card, struct device *dmdev)
998 INIT_DELAYED_WORK(&priv->assoc_work, lbs_association_worker); 984 INIT_DELAYED_WORK(&priv->assoc_work, lbs_association_worker);
999 INIT_DELAYED_WORK(&priv->scan_work, lbs_scan_worker); 985 INIT_DELAYED_WORK(&priv->scan_work, lbs_scan_worker);
1000 INIT_WORK(&priv->mcast_work, lbs_set_mcast_worker); 986 INIT_WORK(&priv->mcast_work, lbs_set_mcast_worker);
1001 INIT_WORK(&priv->sync_channel, lbs_sync_channel_worker);
1002
1003 priv->mesh_open = 0;
1004 sprintf(priv->mesh_ssid, "mesh");
1005 priv->mesh_ssid_len = 4;
1006 987
1007 priv->wol_criteria = 0xffffffff; 988 priv->wol_criteria = 0xffffffff;
1008 priv->wol_gpio = 0xff; 989 priv->wol_gpio = 0xff;
@@ -1076,6 +1057,17 @@ void lbs_remove_card(struct lbs_private *priv)
1076EXPORT_SYMBOL_GPL(lbs_remove_card); 1057EXPORT_SYMBOL_GPL(lbs_remove_card);
1077 1058
1078 1059
1060static int lbs_rtap_supported(struct lbs_private *priv)
1061{
1062 if (MRVL_FW_MAJOR_REV(priv->fwrelease) == MRVL_FW_V5)
1063 return 1;
1064
1065 /* newer firmware use a capability mask */
1066 return ((MRVL_FW_MAJOR_REV(priv->fwrelease) >= MRVL_FW_V10) &&
1067 (priv->fwcapinfo & MESH_CAPINFO_ENABLE_MASK));
1068}
1069
1070
1079int lbs_start_card(struct lbs_private *priv) 1071int lbs_start_card(struct lbs_private *priv)
1080{ 1072{
1081 struct net_device *dev = priv->dev; 1073 struct net_device *dev = priv->dev;
@@ -1095,12 +1087,14 @@ int lbs_start_card(struct lbs_private *priv)
1095 1087
1096 lbs_update_channel(priv); 1088 lbs_update_channel(priv);
1097 1089
1090 lbs_init_mesh(priv);
1091
1098 /* 1092 /*
1099 * While rtap isn't related to mesh, only mesh-enabled 1093 * While rtap isn't related to mesh, only mesh-enabled
1100 * firmware implements the rtap functionality via 1094 * firmware implements the rtap functionality via
1101 * CMD_802_11_MONITOR_MODE. 1095 * CMD_802_11_MONITOR_MODE.
1102 */ 1096 */
1103 if (lbs_init_mesh(priv)) { 1097 if (lbs_rtap_supported(priv)) {
1104 if (device_create_file(&dev->dev, &dev_attr_lbs_rtap)) 1098 if (device_create_file(&dev->dev, &dev_attr_lbs_rtap))
1105 lbs_pr_err("cannot register lbs_rtap attribute\n"); 1099 lbs_pr_err("cannot register lbs_rtap attribute\n");
1106 } 1100 }
@@ -1134,7 +1128,9 @@ void lbs_stop_card(struct lbs_private *priv)
1134 netif_carrier_off(dev); 1128 netif_carrier_off(dev);
1135 1129
1136 lbs_debugfs_remove_one(priv); 1130 lbs_debugfs_remove_one(priv);
1137 if (lbs_deinit_mesh(priv)) 1131 lbs_deinit_mesh(priv);
1132
1133 if (lbs_rtap_supported(priv))
1138 device_remove_file(&dev->dev, &dev_attr_lbs_rtap); 1134 device_remove_file(&dev->dev, &dev_attr_lbs_rtap);
1139 1135
1140 /* Delete the timeout of the currently processing command */ 1136 /* Delete the timeout of the currently processing command */
diff --git a/drivers/net/wireless/libertas/mesh.c b/drivers/net/wireless/libertas/mesh.c
index 2f91c9b808af..954cd00f7452 100644
--- a/drivers/net/wireless/libertas/mesh.c
+++ b/drivers/net/wireless/libertas/mesh.c
@@ -1,4 +1,3 @@
1#include <linux/moduleparam.h>
2#include <linux/delay.h> 1#include <linux/delay.h>
3#include <linux/etherdevice.h> 2#include <linux/etherdevice.h>
4#include <linux/netdevice.h> 3#include <linux/netdevice.h>
@@ -196,7 +195,14 @@ int lbs_init_mesh(struct lbs_private *priv)
196 195
197 lbs_deb_enter(LBS_DEB_MESH); 196 lbs_deb_enter(LBS_DEB_MESH);
198 197
199 if (priv->mesh_fw_ver == MESH_FW_OLD) { 198 priv->mesh_connect_status = LBS_DISCONNECTED;
199
200 /* Determine mesh_fw_ver from fwrelease and fwcapinfo */
201 /* 5.0.16p0 9.0.0.p0 is known to NOT support any mesh */
202 /* 5.110.22 have mesh command with 0xa3 command id */
203 /* 10.0.0.p0 FW brings in mesh config command with different id */
204 /* Check FW version MSB and initialize mesh_fw_ver */
205 if (MRVL_FW_MAJOR_REV(priv->fwrelease) == MRVL_FW_V5) {
200 /* Enable mesh, if supported, and work out which TLV it uses. 206 /* Enable mesh, if supported, and work out which TLV it uses.
201 0x100 + 291 is an unofficial value used in 5.110.20.pXX 207 0x100 + 291 is an unofficial value used in 5.110.20.pXX
202 0x100 + 37 is the official value used in 5.110.21.pXX 208 0x100 + 37 is the official value used in 5.110.21.pXX
@@ -218,7 +224,9 @@ int lbs_init_mesh(struct lbs_private *priv)
218 priv->channel)) 224 priv->channel))
219 priv->mesh_tlv = 0; 225 priv->mesh_tlv = 0;
220 } 226 }
221 } else if (priv->mesh_fw_ver == MESH_FW_NEW) { 227 } else
228 if ((MRVL_FW_MAJOR_REV(priv->fwrelease) >= MRVL_FW_V10) &&
229 (priv->fwcapinfo & MESH_CAPINFO_ENABLE_MASK)) {
222 /* 10.0.0.pXX new firmwares should succeed with TLV 230 /* 10.0.0.pXX new firmwares should succeed with TLV
223 * 0x100+37; Do not invoke command with old TLV. 231 * 0x100+37; Do not invoke command with old TLV.
224 */ 232 */
@@ -227,7 +235,12 @@ int lbs_init_mesh(struct lbs_private *priv)
227 priv->channel)) 235 priv->channel))
228 priv->mesh_tlv = 0; 236 priv->mesh_tlv = 0;
229 } 237 }
238
239
230 if (priv->mesh_tlv) { 240 if (priv->mesh_tlv) {
241 sprintf(priv->mesh_ssid, "mesh");
242 priv->mesh_ssid_len = 4;
243
231 lbs_add_mesh(priv); 244 lbs_add_mesh(priv);
232 245
233 if (device_create_file(&dev->dev, &dev_attr_lbs_mesh)) 246 if (device_create_file(&dev->dev, &dev_attr_lbs_mesh))
@@ -416,10 +429,10 @@ struct net_device *lbs_mesh_set_dev(struct lbs_private *priv,
416 struct net_device *dev, struct rxpd *rxpd) 429 struct net_device *dev, struct rxpd *rxpd)
417{ 430{
418 if (priv->mesh_dev) { 431 if (priv->mesh_dev) {
419 if (priv->mesh_fw_ver == MESH_FW_OLD) { 432 if (priv->mesh_tlv == TLV_TYPE_OLD_MESH_ID) {
420 if (rxpd->rx_control & RxPD_MESH_FRAME) 433 if (rxpd->rx_control & RxPD_MESH_FRAME)
421 dev = priv->mesh_dev; 434 dev = priv->mesh_dev;
422 } else if (priv->mesh_fw_ver == MESH_FW_NEW) { 435 } else if (priv->mesh_tlv == TLV_TYPE_MESH_ID) {
423 if (rxpd->u.bss.bss_num == MESH_IFACE_ID) 436 if (rxpd->u.bss.bss_num == MESH_IFACE_ID)
424 dev = priv->mesh_dev; 437 dev = priv->mesh_dev;
425 } 438 }
@@ -432,9 +445,9 @@ void lbs_mesh_set_txpd(struct lbs_private *priv,
432 struct net_device *dev, struct txpd *txpd) 445 struct net_device *dev, struct txpd *txpd)
433{ 446{
434 if (dev == priv->mesh_dev) { 447 if (dev == priv->mesh_dev) {
435 if (priv->mesh_fw_ver == MESH_FW_OLD) 448 if (priv->mesh_tlv == TLV_TYPE_OLD_MESH_ID)
436 txpd->tx_control |= cpu_to_le32(TxPD_MESH_FRAME); 449 txpd->tx_control |= cpu_to_le32(TxPD_MESH_FRAME);
437 else if (priv->mesh_fw_ver == MESH_FW_NEW) 450 else if (priv->mesh_tlv == TLV_TYPE_MESH_ID)
438 txpd->u.bss.bss_num = MESH_IFACE_ID; 451 txpd->u.bss.bss_num = MESH_IFACE_ID;
439 } 452 }
440} 453}
@@ -538,7 +551,7 @@ static int __lbs_mesh_config_send(struct lbs_private *priv,
538 * Command id is 0xac for v10 FW along with mesh interface 551 * Command id is 0xac for v10 FW along with mesh interface
539 * id in bits 14-13-12. 552 * id in bits 14-13-12.
540 */ 553 */
541 if (priv->mesh_fw_ver == MESH_FW_NEW) 554 if (priv->mesh_tlv == TLV_TYPE_MESH_ID)
542 command = CMD_MESH_CONFIG | 555 command = CMD_MESH_CONFIG |
543 (MESH_IFACE_ID << MESH_IFACE_BIT_OFFSET); 556 (MESH_IFACE_ID << MESH_IFACE_BIT_OFFSET);
544 557
diff --git a/drivers/net/wireless/libertas/mesh.h b/drivers/net/wireless/libertas/mesh.h
index fea9b5d005fc..e2573303a328 100644
--- a/drivers/net/wireless/libertas/mesh.h
+++ b/drivers/net/wireless/libertas/mesh.h
@@ -9,6 +9,8 @@
9#include <net/lib80211.h> 9#include <net/lib80211.h>
10 10
11 11
12#ifdef CONFIG_LIBERTAS_MESH
13
12/* Mesh statistics */ 14/* Mesh statistics */
13struct lbs_mesh_stats { 15struct lbs_mesh_stats {
14 u32 fwd_bcast_cnt; /* Fwd: Broadcast counter */ 16 u32 fwd_bcast_cnt; /* Fwd: Broadcast counter */
@@ -46,11 +48,20 @@ void lbs_mesh_set_txpd(struct lbs_private *priv,
46/* Command handling */ 48/* Command handling */
47 49
48struct cmd_ds_command; 50struct cmd_ds_command;
51struct cmd_ds_mesh_access;
52struct cmd_ds_mesh_config;
49 53
50int lbs_cmd_bt_access(struct cmd_ds_command *cmd, 54int lbs_cmd_bt_access(struct cmd_ds_command *cmd,
51 u16 cmd_action, void *pdata_buf); 55 u16 cmd_action, void *pdata_buf);
52int lbs_cmd_fwt_access(struct cmd_ds_command *cmd, 56int lbs_cmd_fwt_access(struct cmd_ds_command *cmd,
53 u16 cmd_action, void *pdata_buf); 57 u16 cmd_action, void *pdata_buf);
58int lbs_mesh_access(struct lbs_private *priv, uint16_t cmd_action,
59 struct cmd_ds_mesh_access *cmd);
60int lbs_mesh_config_send(struct lbs_private *priv,
61 struct cmd_ds_mesh_config *cmd,
62 uint16_t action, uint16_t type);
63int lbs_mesh_config(struct lbs_private *priv, uint16_t enable, uint16_t chan);
64
54 65
55 66
56/* Persistent configuration */ 67/* Persistent configuration */
@@ -75,4 +86,25 @@ void lbs_mesh_ethtool_get_strings(struct net_device *dev,
75 uint32_t stringset, uint8_t *s); 86 uint32_t stringset, uint8_t *s);
76 87
77 88
89/* Accessors */
90
91#define lbs_mesh_open(priv) (priv->mesh_open)
92#define lbs_mesh_connected(priv) (priv->mesh_connect_status == LBS_CONNECTED)
93
94#else
95
96#define lbs_init_mesh(priv)
97#define lbs_deinit_mesh(priv)
98#define lbs_add_mesh(priv)
99#define lbs_remove_mesh(priv)
100#define lbs_mesh_set_dev(priv, dev, rxpd) (dev)
101#define lbs_mesh_set_txpd(priv, dev, txpd)
102#define lbs_mesh_config(priv, enable, chan)
103#define lbs_mesh_open(priv) (0)
104#define lbs_mesh_connected(priv) (0)
105
106#endif
107
108
109
78#endif 110#endif
diff --git a/drivers/net/wireless/libertas/scan.c b/drivers/net/wireless/libertas/scan.c
index c6a6c042b82f..4a0c3e3cd3b1 100644
--- a/drivers/net/wireless/libertas/scan.c
+++ b/drivers/net/wireless/libertas/scan.c
@@ -640,7 +640,7 @@ out:
640 if (!priv->tx_pending_len) 640 if (!priv->tx_pending_len)
641 netif_wake_queue(priv->dev); 641 netif_wake_queue(priv->dev);
642 } 642 }
643 if (priv->mesh_dev && (priv->mesh_connect_status == LBS_CONNECTED)) { 643 if (priv->mesh_dev && lbs_mesh_connected(priv)) {
644 netif_carrier_on(priv->mesh_dev); 644 netif_carrier_on(priv->mesh_dev);
645 if (!priv->tx_pending_len) 645 if (!priv->tx_pending_len)
646 netif_wake_queue(priv->mesh_dev); 646 netif_wake_queue(priv->mesh_dev);
diff --git a/drivers/net/wireless/libertas/tx.c b/drivers/net/wireless/libertas/tx.c
index 315d1ce286ca..52d244ea3d97 100644
--- a/drivers/net/wireless/libertas/tx.c
+++ b/drivers/net/wireless/libertas/tx.c
@@ -198,7 +198,7 @@ void lbs_send_tx_feedback(struct lbs_private *priv, u32 try_count)
198 if (priv->connect_status == LBS_CONNECTED) 198 if (priv->connect_status == LBS_CONNECTED)
199 netif_wake_queue(priv->dev); 199 netif_wake_queue(priv->dev);
200 200
201 if (priv->mesh_dev && (priv->mesh_connect_status == LBS_CONNECTED)) 201 if (priv->mesh_dev && lbs_mesh_connected(priv))
202 netif_wake_queue(priv->mesh_dev); 202 netif_wake_queue(priv->mesh_dev);
203} 203}
204EXPORT_SYMBOL_GPL(lbs_send_tx_feedback); 204EXPORT_SYMBOL_GPL(lbs_send_tx_feedback);
diff --git a/drivers/net/wireless/libertas/wext.c b/drivers/net/wireless/libertas/wext.c
index 4b1aab593a84..71f88a08e090 100644
--- a/drivers/net/wireless/libertas/wext.c
+++ b/drivers/net/wireless/libertas/wext.c
@@ -192,7 +192,7 @@ static void copy_active_data_rates(struct lbs_private *priv, u8 *rates)
192 lbs_deb_enter(LBS_DEB_WEXT); 192 lbs_deb_enter(LBS_DEB_WEXT);
193 193
194 if ((priv->connect_status != LBS_CONNECTED) && 194 if ((priv->connect_status != LBS_CONNECTED) &&
195 (priv->mesh_connect_status != LBS_CONNECTED)) 195 !lbs_mesh_connected(priv))
196 memcpy(rates, lbs_bg_rates, MAX_RATES); 196 memcpy(rates, lbs_bg_rates, MAX_RATES);
197 else 197 else
198 memcpy(rates, priv->curbssparams.rates, MAX_RATES); 198 memcpy(rates, priv->curbssparams.rates, MAX_RATES);
@@ -298,6 +298,7 @@ static int lbs_get_nick(struct net_device *dev, struct iw_request_info *info,
298 return 0; 298 return 0;
299} 299}
300 300
301#ifdef CONFIG_LIBERTAS_MESH
301static int mesh_get_nick(struct net_device *dev, struct iw_request_info *info, 302static int mesh_get_nick(struct net_device *dev, struct iw_request_info *info,
302 struct iw_point *dwrq, char *extra) 303 struct iw_point *dwrq, char *extra)
303{ 304{
@@ -307,7 +308,7 @@ static int mesh_get_nick(struct net_device *dev, struct iw_request_info *info,
307 308
308 /* Use nickname to indicate that mesh is on */ 309 /* Use nickname to indicate that mesh is on */
309 310
310 if (priv->mesh_connect_status == LBS_CONNECTED) { 311 if (lbs_mesh_connected(priv)) {
311 strncpy(extra, "Mesh", 12); 312 strncpy(extra, "Mesh", 12);
312 extra[12] = '\0'; 313 extra[12] = '\0';
313 dwrq->length = strlen(extra); 314 dwrq->length = strlen(extra);
@@ -321,6 +322,7 @@ static int mesh_get_nick(struct net_device *dev, struct iw_request_info *info,
321 lbs_deb_leave(LBS_DEB_WEXT); 322 lbs_deb_leave(LBS_DEB_WEXT);
322 return 0; 323 return 0;
323} 324}
325#endif
324 326
325static int lbs_set_rts(struct net_device *dev, struct iw_request_info *info, 327static int lbs_set_rts(struct net_device *dev, struct iw_request_info *info,
326 struct iw_param *vwrq, char *extra) 328 struct iw_param *vwrq, char *extra)
@@ -422,6 +424,7 @@ static int lbs_get_mode(struct net_device *dev,
422 return 0; 424 return 0;
423} 425}
424 426
427#ifdef CONFIG_LIBERTAS_MESH
425static int mesh_wlan_get_mode(struct net_device *dev, 428static int mesh_wlan_get_mode(struct net_device *dev,
426 struct iw_request_info *info, u32 * uwrq, 429 struct iw_request_info *info, u32 * uwrq,
427 char *extra) 430 char *extra)
@@ -433,6 +436,7 @@ static int mesh_wlan_get_mode(struct net_device *dev,
433 lbs_deb_leave(LBS_DEB_WEXT); 436 lbs_deb_leave(LBS_DEB_WEXT);
434 return 0; 437 return 0;
435} 438}
439#endif
436 440
437static int lbs_get_txpow(struct net_device *dev, 441static int lbs_get_txpow(struct net_device *dev,
438 struct iw_request_info *info, 442 struct iw_request_info *info,
@@ -863,7 +867,7 @@ static struct iw_statistics *lbs_get_wireless_stats(struct net_device *dev)
863 867
864 /* If we're not associated, all quality values are meaningless */ 868 /* If we're not associated, all quality values are meaningless */
865 if ((priv->connect_status != LBS_CONNECTED) && 869 if ((priv->connect_status != LBS_CONNECTED) &&
866 (priv->mesh_connect_status != LBS_CONNECTED)) 870 !lbs_mesh_connected(priv))
867 goto out; 871 goto out;
868 872
869 /* Quality by RSSI */ 873 /* Quality by RSSI */
@@ -1010,6 +1014,7 @@ out:
1010 return ret; 1014 return ret;
1011} 1015}
1012 1016
1017#ifdef CONFIG_LIBERTAS_MESH
1013static int lbs_mesh_set_freq(struct net_device *dev, 1018static int lbs_mesh_set_freq(struct net_device *dev,
1014 struct iw_request_info *info, 1019 struct iw_request_info *info,
1015 struct iw_freq *fwrq, char *extra) 1020 struct iw_freq *fwrq, char *extra)
@@ -1061,6 +1066,7 @@ out:
1061 lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret); 1066 lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);
1062 return ret; 1067 return ret;
1063} 1068}
1069#endif
1064 1070
1065static int lbs_set_rate(struct net_device *dev, struct iw_request_info *info, 1071static int lbs_set_rate(struct net_device *dev, struct iw_request_info *info,
1066 struct iw_param *vwrq, char *extra) 1072 struct iw_param *vwrq, char *extra)
@@ -2108,6 +2114,7 @@ out:
2108 return ret; 2114 return ret;
2109} 2115}
2110 2116
2117#ifdef CONFIG_LIBERTAS_MESH
2111static int lbs_mesh_get_essid(struct net_device *dev, 2118static int lbs_mesh_get_essid(struct net_device *dev,
2112 struct iw_request_info *info, 2119 struct iw_request_info *info,
2113 struct iw_point *dwrq, char *extra) 2120 struct iw_point *dwrq, char *extra)
@@ -2161,6 +2168,7 @@ static int lbs_mesh_set_essid(struct net_device *dev,
2161 lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret); 2168 lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);
2162 return ret; 2169 return ret;
2163} 2170}
2171#endif
2164 2172
2165/** 2173/**
2166 * @brief Connect to the AP or Ad-hoc Network with specific bssid 2174 * @brief Connect to the AP or Ad-hoc Network with specific bssid
@@ -2267,7 +2275,13 @@ static const iw_handler lbs_handler[] = {
2267 (iw_handler) lbs_get_encodeext,/* SIOCGIWENCODEEXT */ 2275 (iw_handler) lbs_get_encodeext,/* SIOCGIWENCODEEXT */
2268 (iw_handler) NULL, /* SIOCSIWPMKSA */ 2276 (iw_handler) NULL, /* SIOCSIWPMKSA */
2269}; 2277};
2278struct iw_handler_def lbs_handler_def = {
2279 .num_standard = ARRAY_SIZE(lbs_handler),
2280 .standard = (iw_handler *) lbs_handler,
2281 .get_wireless_stats = lbs_get_wireless_stats,
2282};
2270 2283
2284#ifdef CONFIG_LIBERTAS_MESH
2271static const iw_handler mesh_wlan_handler[] = { 2285static const iw_handler mesh_wlan_handler[] = {
2272 (iw_handler) NULL, /* SIOCSIWCOMMIT */ 2286 (iw_handler) NULL, /* SIOCSIWCOMMIT */
2273 (iw_handler) lbs_get_name, /* SIOCGIWNAME */ 2287 (iw_handler) lbs_get_name, /* SIOCGIWNAME */
@@ -2325,14 +2339,10 @@ static const iw_handler mesh_wlan_handler[] = {
2325 (iw_handler) lbs_get_encodeext,/* SIOCGIWENCODEEXT */ 2339 (iw_handler) lbs_get_encodeext,/* SIOCGIWENCODEEXT */
2326 (iw_handler) NULL, /* SIOCSIWPMKSA */ 2340 (iw_handler) NULL, /* SIOCSIWPMKSA */
2327}; 2341};
2328struct iw_handler_def lbs_handler_def = {
2329 .num_standard = ARRAY_SIZE(lbs_handler),
2330 .standard = (iw_handler *) lbs_handler,
2331 .get_wireless_stats = lbs_get_wireless_stats,
2332};
2333 2342
2334struct iw_handler_def mesh_handler_def = { 2343struct iw_handler_def mesh_handler_def = {
2335 .num_standard = ARRAY_SIZE(mesh_wlan_handler), 2344 .num_standard = ARRAY_SIZE(mesh_wlan_handler),
2336 .standard = (iw_handler *) mesh_wlan_handler, 2345 .standard = (iw_handler *) mesh_wlan_handler,
2337 .get_wireless_stats = lbs_get_wireless_stats, 2346 .get_wireless_stats = lbs_get_wireless_stats,
2338}; 2347};
2348#endif
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
index 88e41176e7fd..718a5f198c30 100644
--- a/drivers/net/wireless/mac80211_hwsim.c
+++ b/drivers/net/wireless/mac80211_hwsim.c
@@ -436,6 +436,38 @@ static bool hwsim_ps_rx_ok(struct mac80211_hwsim_data *data,
436} 436}
437 437
438 438
439struct mac80211_hwsim_addr_match_data {
440 bool ret;
441 const u8 *addr;
442};
443
444static void mac80211_hwsim_addr_iter(void *data, u8 *mac,
445 struct ieee80211_vif *vif)
446{
447 struct mac80211_hwsim_addr_match_data *md = data;
448 if (memcmp(mac, md->addr, ETH_ALEN) == 0)
449 md->ret = true;
450}
451
452
453static bool mac80211_hwsim_addr_match(struct mac80211_hwsim_data *data,
454 const u8 *addr)
455{
456 struct mac80211_hwsim_addr_match_data md;
457
458 if (memcmp(addr, data->hw->wiphy->perm_addr, ETH_ALEN) == 0)
459 return true;
460
461 md.ret = false;
462 md.addr = addr;
463 ieee80211_iterate_active_interfaces_atomic(data->hw,
464 mac80211_hwsim_addr_iter,
465 &md);
466
467 return md.ret;
468}
469
470
439static bool mac80211_hwsim_tx_frame(struct ieee80211_hw *hw, 471static bool mac80211_hwsim_tx_frame(struct ieee80211_hw *hw,
440 struct sk_buff *skb) 472 struct sk_buff *skb)
441{ 473{
@@ -488,8 +520,7 @@ static bool mac80211_hwsim_tx_frame(struct ieee80211_hw *hw,
488 if (nskb == NULL) 520 if (nskb == NULL)
489 continue; 521 continue;
490 522
491 if (memcmp(hdr->addr1, data2->hw->wiphy->perm_addr, 523 if (mac80211_hwsim_addr_match(data2, hdr->addr1))
492 ETH_ALEN) == 0)
493 ack = true; 524 ack = true;
494 memcpy(IEEE80211_SKB_RXCB(nskb), &rx_status, sizeof(rx_status)); 525 memcpy(IEEE80211_SKB_RXCB(nskb), &rx_status, sizeof(rx_status));
495 ieee80211_rx_irqsafe(data2->hw, nskb); 526 ieee80211_rx_irqsafe(data2->hw, nskb);
@@ -618,12 +649,26 @@ static int mac80211_hwsim_config(struct ieee80211_hw *hw, u32 changed)
618{ 649{
619 struct mac80211_hwsim_data *data = hw->priv; 650 struct mac80211_hwsim_data *data = hw->priv;
620 struct ieee80211_conf *conf = &hw->conf; 651 struct ieee80211_conf *conf = &hw->conf;
621 652 static const char *chantypes[4] = {
622 printk(KERN_DEBUG "%s:%s (freq=%d idle=%d ps=%d)\n", 653 [NL80211_CHAN_NO_HT] = "noht",
654 [NL80211_CHAN_HT20] = "ht20",
655 [NL80211_CHAN_HT40MINUS] = "ht40-",
656 [NL80211_CHAN_HT40PLUS] = "ht40+",
657 };
658 static const char *smps_modes[IEEE80211_SMPS_NUM_MODES] = {
659 [IEEE80211_SMPS_AUTOMATIC] = "auto",
660 [IEEE80211_SMPS_OFF] = "off",
661 [IEEE80211_SMPS_STATIC] = "static",
662 [IEEE80211_SMPS_DYNAMIC] = "dynamic",
663 };
664
665 printk(KERN_DEBUG "%s:%s (freq=%d/%s idle=%d ps=%d smps=%s)\n",
623 wiphy_name(hw->wiphy), __func__, 666 wiphy_name(hw->wiphy), __func__,
624 conf->channel->center_freq, 667 conf->channel->center_freq,
668 chantypes[conf->channel_type],
625 !!(conf->flags & IEEE80211_CONF_IDLE), 669 !!(conf->flags & IEEE80211_CONF_IDLE),
626 !!(conf->flags & IEEE80211_CONF_PS)); 670 !!(conf->flags & IEEE80211_CONF_PS),
671 smps_modes[conf->smps_mode]);
627 672
628 data->idle = !!(conf->flags & IEEE80211_CONF_IDLE); 673 data->idle = !!(conf->flags & IEEE80211_CONF_IDLE);
629 674
@@ -827,6 +872,31 @@ static int mac80211_hwsim_testmode_cmd(struct ieee80211_hw *hw,
827} 872}
828#endif 873#endif
829 874
875static int mac80211_hwsim_ampdu_action(struct ieee80211_hw *hw,
876 struct ieee80211_vif *vif,
877 enum ieee80211_ampdu_mlme_action action,
878 struct ieee80211_sta *sta, u16 tid, u16 *ssn)
879{
880 switch (action) {
881 case IEEE80211_AMPDU_TX_START:
882 ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid);
883 break;
884 case IEEE80211_AMPDU_TX_STOP:
885 ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);
886 break;
887 case IEEE80211_AMPDU_TX_OPERATIONAL:
888 break;
889 case IEEE80211_AMPDU_RX_START:
890 case IEEE80211_AMPDU_RX_STOP:
891 break;
892 default:
893 return -EOPNOTSUPP;
894 }
895
896 return 0;
897}
898
899
830static const struct ieee80211_ops mac80211_hwsim_ops = 900static const struct ieee80211_ops mac80211_hwsim_ops =
831{ 901{
832 .tx = mac80211_hwsim_tx, 902 .tx = mac80211_hwsim_tx,
@@ -841,6 +911,7 @@ static const struct ieee80211_ops mac80211_hwsim_ops =
841 .set_tim = mac80211_hwsim_set_tim, 911 .set_tim = mac80211_hwsim_set_tim,
842 .conf_tx = mac80211_hwsim_conf_tx, 912 .conf_tx = mac80211_hwsim_conf_tx,
843 CFG80211_TESTMODE_CMD(mac80211_hwsim_testmode_cmd) 913 CFG80211_TESTMODE_CMD(mac80211_hwsim_testmode_cmd)
914 .ampdu_action = mac80211_hwsim_ampdu_action,
844}; 915};
845 916
846 917
@@ -1082,7 +1153,9 @@ static int __init init_mac80211_hwsim(void)
1082 BIT(NL80211_IFTYPE_MESH_POINT); 1153 BIT(NL80211_IFTYPE_MESH_POINT);
1083 1154
1084 hw->flags = IEEE80211_HW_MFP_CAPABLE | 1155 hw->flags = IEEE80211_HW_MFP_CAPABLE |
1085 IEEE80211_HW_SIGNAL_DBM; 1156 IEEE80211_HW_SIGNAL_DBM |
1157 IEEE80211_HW_SUPPORTS_STATIC_SMPS |
1158 IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS;
1086 1159
1087 /* ask mac80211 to reserve space for magic */ 1160 /* ask mac80211 to reserve space for magic */
1088 hw->vif_data_size = sizeof(struct hwsim_vif_priv); 1161 hw->vif_data_size = sizeof(struct hwsim_vif_priv);
diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c
index 2ecbedb26e15..305c106fdc1c 100644
--- a/drivers/net/wireless/rndis_wlan.c
+++ b/drivers/net/wireless/rndis_wlan.c
@@ -2594,23 +2594,9 @@ end:
2594/* 2594/*
2595 * driver/device initialization 2595 * driver/device initialization
2596 */ 2596 */
2597static int bcm4320a_early_init(struct usbnet *usbdev) 2597static void rndis_copy_module_params(struct usbnet *usbdev)
2598{
2599 /* bcm4320a doesn't handle configuration parameters well. Try
2600 * set any and you get partially zeroed mac and broken device.
2601 */
2602
2603 return 0;
2604}
2605
2606static int bcm4320b_early_init(struct usbnet *usbdev)
2607{ 2598{
2608 struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); 2599 struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
2609 char buf[8];
2610
2611 /* Early initialization settings, setting these won't have effect
2612 * if called after generic_rndis_bind().
2613 */
2614 2600
2615 priv->param_country[0] = modparam_country[0]; 2601 priv->param_country[0] = modparam_country[0];
2616 priv->param_country[1] = modparam_country[1]; 2602 priv->param_country[1] = modparam_country[1];
@@ -2652,6 +2638,32 @@ static int bcm4320b_early_init(struct usbnet *usbdev)
2652 priv->param_workaround_interval = 500; 2638 priv->param_workaround_interval = 500;
2653 else 2639 else
2654 priv->param_workaround_interval = modparam_workaround_interval; 2640 priv->param_workaround_interval = modparam_workaround_interval;
2641}
2642
2643static int bcm4320a_early_init(struct usbnet *usbdev)
2644{
2645 /* copy module parameters for bcm4320a so that iwconfig reports txpower
2646 * and workaround parameter is copied to private structure correctly.
2647 */
2648 rndis_copy_module_params(usbdev);
2649
2650 /* bcm4320a doesn't handle configuration parameters well. Try
2651 * set any and you get partially zeroed mac and broken device.
2652 */
2653
2654 return 0;
2655}
2656
2657static int bcm4320b_early_init(struct usbnet *usbdev)
2658{
2659 struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
2660 char buf[8];
2661
2662 rndis_copy_module_params(usbdev);
2663
2664 /* Early initialization settings, setting these won't have effect
2665 * if called after generic_rndis_bind().
2666 */
2655 2667
2656 rndis_set_config_parameter_str(usbdev, "Country", priv->param_country); 2668 rndis_set_config_parameter_str(usbdev, "Country", priv->param_country);
2657 rndis_set_config_parameter_str(usbdev, "FrameBursting", 2669 rndis_set_config_parameter_str(usbdev, "FrameBursting",
diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c
index dfc886fcb44d..458378c4e500 100644
--- a/drivers/net/wireless/rt2x00/rt2800pci.c
+++ b/drivers/net/wireless/rt2x00/rt2800pci.c
@@ -835,7 +835,6 @@ static void rt2800pci_fill_rxdone(struct queue_entry *entry,
835 struct rxdone_entry_desc *rxdesc) 835 struct rxdone_entry_desc *rxdesc)
836{ 836{
837 struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; 837 struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
838 struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
839 struct queue_entry_priv_pci *entry_priv = entry->priv_data; 838 struct queue_entry_priv_pci *entry_priv = entry->priv_data;
840 __le32 *rxd = entry_priv->desc; 839 __le32 *rxd = entry_priv->desc;
841 __le32 *rxwi = (__le32 *)entry->skb->data; 840 __le32 *rxwi = (__le32 *)entry->skb->data;
@@ -883,10 +882,8 @@ static void rt2800pci_fill_rxdone(struct queue_entry *entry,
883 if (rt2x00_get_field32(rxd3, RXD_W3_MY_BSS)) 882 if (rt2x00_get_field32(rxd3, RXD_W3_MY_BSS))
884 rxdesc->dev_flags |= RXDONE_MY_BSS; 883 rxdesc->dev_flags |= RXDONE_MY_BSS;
885 884
886 if (rt2x00_get_field32(rxd3, RXD_W3_L2PAD)) { 885 if (rt2x00_get_field32(rxd3, RXD_W3_L2PAD))
887 rxdesc->dev_flags |= RXDONE_L2PAD; 886 rxdesc->dev_flags |= RXDONE_L2PAD;
888 skbdesc->flags |= SKBDESC_L2_PADDED;
889 }
890 887
891 if (rt2x00_get_field32(rxwi1, RXWI_W1_SHORT_GI)) 888 if (rt2x00_get_field32(rxwi1, RXWI_W1_SHORT_GI))
892 rxdesc->flags |= RX_FLAG_SHORT_GI; 889 rxdesc->flags |= RX_FLAG_SHORT_GI;
@@ -927,7 +924,6 @@ static void rt2800pci_fill_rxdone(struct queue_entry *entry,
927 * Remove TXWI descriptor from start of buffer. 924 * Remove TXWI descriptor from start of buffer.
928 */ 925 */
929 skb_pull(entry->skb, RXWI_DESC_SIZE); 926 skb_pull(entry->skb, RXWI_DESC_SIZE);
930 skb_trim(entry->skb, rxdesc->size);
931} 927}
932 928
933/* 929/*
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c
index af85d18cdbe7..40295b454ff6 100644
--- a/drivers/net/wireless/rt2x00/rt2800usb.c
+++ b/drivers/net/wireless/rt2x00/rt2800usb.c
@@ -295,9 +295,7 @@ static int rt2800usb_enable_radio(struct rt2x00_dev *rt2x00dev)
295 295
296 rt2800_register_read(rt2x00dev, USB_DMA_CFG, &reg); 296 rt2800_register_read(rt2x00dev, USB_DMA_CFG, &reg);
297 rt2x00_set_field32(&reg, USB_DMA_CFG_PHY_CLEAR, 0); 297 rt2x00_set_field32(&reg, USB_DMA_CFG_PHY_CLEAR, 0);
298 /* Don't use bulk in aggregation when working with USB 1.1 */ 298 rt2x00_set_field32(&reg, USB_DMA_CFG_RX_BULK_AGG_EN, 0);
299 rt2x00_set_field32(&reg, USB_DMA_CFG_RX_BULK_AGG_EN,
300 (rt2x00dev->rx->usb_maxpacket == 512));
301 rt2x00_set_field32(&reg, USB_DMA_CFG_RX_BULK_AGG_TIMEOUT, 128); 299 rt2x00_set_field32(&reg, USB_DMA_CFG_RX_BULK_AGG_TIMEOUT, 128);
302 /* 300 /*
303 * Total room for RX frames in kilobytes, PBF might still exceed 301 * Total room for RX frames in kilobytes, PBF might still exceed
@@ -573,41 +571,57 @@ static void rt2800usb_fill_rxdone(struct queue_entry *entry,
573{ 571{
574 struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; 572 struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
575 struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); 573 struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
576 __le32 *rxd = (__le32 *)entry->skb->data; 574 __le32 *rxi = (__le32 *)entry->skb->data;
577 __le32 *rxwi; 575 __le32 *rxwi;
578 u32 rxd0; 576 __le32 *rxd;
577 u32 rxi0;
579 u32 rxwi0; 578 u32 rxwi0;
580 u32 rxwi1; 579 u32 rxwi1;
581 u32 rxwi2; 580 u32 rxwi2;
582 u32 rxwi3; 581 u32 rxwi3;
582 u32 rxd0;
583 int rx_pkt_len;
584
585 /*
586 * RX frame format is :
587 * | RXINFO | RXWI | header | L2 pad | payload | pad | RXD | USB pad |
588 * |<------------ rx_pkt_len -------------->|
589 */
590 rt2x00_desc_read(rxi, 0, &rxi0);
591 rx_pkt_len = rt2x00_get_field32(rxi0, RXINFO_W0_USB_DMA_RX_PKT_LEN);
592
593 rxwi = (__le32 *)(entry->skb->data + RXINFO_DESC_SIZE);
594
595 /*
596 * FIXME : we need to check for rx_pkt_len validity
597 */
598 rxd = (__le32 *)(entry->skb->data + RXINFO_DESC_SIZE + rx_pkt_len);
583 599
584 /* 600 /*
585 * Copy descriptor to the skbdesc->desc buffer, making it safe from 601 * Copy descriptor to the skbdesc->desc buffer, making it safe from
586 * moving of frame data in rt2x00usb. 602 * moving of frame data in rt2x00usb.
587 */ 603 */
588 memcpy(skbdesc->desc, rxd, skbdesc->desc_len); 604 memcpy(skbdesc->desc, rxi, skbdesc->desc_len);
589 rxd = (__le32 *)skbdesc->desc;
590 rxwi = &rxd[RXINFO_DESC_SIZE / sizeof(__le32)];
591 605
592 /* 606 /*
593 * It is now safe to read the descriptor on all architectures. 607 * It is now safe to read the descriptor on all architectures.
594 */ 608 */
595 rt2x00_desc_read(rxd, 0, &rxd0);
596 rt2x00_desc_read(rxwi, 0, &rxwi0); 609 rt2x00_desc_read(rxwi, 0, &rxwi0);
597 rt2x00_desc_read(rxwi, 1, &rxwi1); 610 rt2x00_desc_read(rxwi, 1, &rxwi1);
598 rt2x00_desc_read(rxwi, 2, &rxwi2); 611 rt2x00_desc_read(rxwi, 2, &rxwi2);
599 rt2x00_desc_read(rxwi, 3, &rxwi3); 612 rt2x00_desc_read(rxwi, 3, &rxwi3);
613 rt2x00_desc_read(rxd, 0, &rxd0);
600 614
601 if (rt2x00_get_field32(rxd0, RXINFO_W0_CRC_ERROR)) 615 if (rt2x00_get_field32(rxd0, RXD_W0_CRC_ERROR))
602 rxdesc->flags |= RX_FLAG_FAILED_FCS_CRC; 616 rxdesc->flags |= RX_FLAG_FAILED_FCS_CRC;
603 617
604 if (test_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags)) { 618 if (test_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags)) {
605 rxdesc->cipher = rt2x00_get_field32(rxwi0, RXWI_W0_UDF); 619 rxdesc->cipher = rt2x00_get_field32(rxwi0, RXWI_W0_UDF);
606 rxdesc->cipher_status = 620 rxdesc->cipher_status =
607 rt2x00_get_field32(rxd0, RXINFO_W0_CIPHER_ERROR); 621 rt2x00_get_field32(rxd0, RXD_W0_CIPHER_ERROR);
608 } 622 }
609 623
610 if (rt2x00_get_field32(rxd0, RXINFO_W0_DECRYPTED)) { 624 if (rt2x00_get_field32(rxd0, RXD_W0_DECRYPTED)) {
611 /* 625 /*
612 * Hardware has stripped IV/EIV data from 802.11 frame during 626 * Hardware has stripped IV/EIV data from 802.11 frame during
613 * decryption. Unfortunately the descriptor doesn't contain 627 * decryption. Unfortunately the descriptor doesn't contain
@@ -622,13 +636,11 @@ static void rt2800usb_fill_rxdone(struct queue_entry *entry,
622 rxdesc->flags |= RX_FLAG_MMIC_ERROR; 636 rxdesc->flags |= RX_FLAG_MMIC_ERROR;
623 } 637 }
624 638
625 if (rt2x00_get_field32(rxd0, RXINFO_W0_MY_BSS)) 639 if (rt2x00_get_field32(rxd0, RXD_W0_MY_BSS))
626 rxdesc->dev_flags |= RXDONE_MY_BSS; 640 rxdesc->dev_flags |= RXDONE_MY_BSS;
627 641
628 if (rt2x00_get_field32(rxd0, RXINFO_W0_L2PAD)) { 642 if (rt2x00_get_field32(rxd0, RXD_W0_L2PAD))
629 rxdesc->dev_flags |= RXDONE_L2PAD; 643 rxdesc->dev_flags |= RXDONE_L2PAD;
630 skbdesc->flags |= SKBDESC_L2_PADDED;
631 }
632 644
633 if (rt2x00_get_field32(rxwi1, RXWI_W1_SHORT_GI)) 645 if (rt2x00_get_field32(rxwi1, RXWI_W1_SHORT_GI))
634 rxdesc->flags |= RX_FLAG_SHORT_GI; 646 rxdesc->flags |= RX_FLAG_SHORT_GI;
@@ -663,7 +675,6 @@ static void rt2800usb_fill_rxdone(struct queue_entry *entry,
663 * Remove RXWI descriptor from start of buffer. 675 * Remove RXWI descriptor from start of buffer.
664 */ 676 */
665 skb_pull(entry->skb, skbdesc->desc_len); 677 skb_pull(entry->skb, skbdesc->desc_len);
666 skb_trim(entry->skb, rxdesc->size);
667} 678}
668 679
669/* 680/*
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.h b/drivers/net/wireless/rt2x00/rt2800usb.h
index 1e4340a182ef..d1d8ae94b4d4 100644
--- a/drivers/net/wireless/rt2x00/rt2800usb.h
+++ b/drivers/net/wireless/rt2x00/rt2800usb.h
@@ -79,6 +79,8 @@
79 */ 79 */
80#define TXINFO_DESC_SIZE ( 1 * sizeof(__le32) ) 80#define TXINFO_DESC_SIZE ( 1 * sizeof(__le32) )
81#define RXINFO_DESC_SIZE ( 1 * sizeof(__le32) ) 81#define RXINFO_DESC_SIZE ( 1 * sizeof(__le32) )
82#define RXWI_DESC_SIZE ( 4 * sizeof(__le32) )
83#define RXD_DESC_SIZE ( 1 * sizeof(__le32) )
82 84
83/* 85/*
84 * TX Info structure 86 * TX Info structure
@@ -101,6 +103,54 @@
101#define TXINFO_W0_USB_DMA_TX_BURST FIELD32(0x80000000) 103#define TXINFO_W0_USB_DMA_TX_BURST FIELD32(0x80000000)
102 104
103/* 105/*
106 * RX Info structure
107 */
108
109/*
110 * Word 0
111 */
112
113#define RXINFO_W0_USB_DMA_RX_PKT_LEN FIELD32(0x0000ffff)
114
115/*
116 * RX WI structure
117 */
118
119/*
120 * Word0
121 */
122#define RXWI_W0_WIRELESS_CLI_ID FIELD32(0x000000ff)
123#define RXWI_W0_KEY_INDEX FIELD32(0x00000300)
124#define RXWI_W0_BSSID FIELD32(0x00001c00)
125#define RXWI_W0_UDF FIELD32(0x0000e000)
126#define RXWI_W0_MPDU_TOTAL_BYTE_COUNT FIELD32(0x0fff0000)
127#define RXWI_W0_TID FIELD32(0xf0000000)
128
129/*
130 * Word1
131 */
132#define RXWI_W1_FRAG FIELD32(0x0000000f)
133#define RXWI_W1_SEQUENCE FIELD32(0x0000fff0)
134#define RXWI_W1_MCS FIELD32(0x007f0000)
135#define RXWI_W1_BW FIELD32(0x00800000)
136#define RXWI_W1_SHORT_GI FIELD32(0x01000000)
137#define RXWI_W1_STBC FIELD32(0x06000000)
138#define RXWI_W1_PHYMODE FIELD32(0xc0000000)
139
140/*
141 * Word2
142 */
143#define RXWI_W2_RSSI0 FIELD32(0x000000ff)
144#define RXWI_W2_RSSI1 FIELD32(0x0000ff00)
145#define RXWI_W2_RSSI2 FIELD32(0x00ff0000)
146
147/*
148 * Word3
149 */
150#define RXWI_W3_SNR0 FIELD32(0x000000ff)
151#define RXWI_W3_SNR1 FIELD32(0x0000ff00)
152
153/*
104 * RX descriptor format for RX Ring. 154 * RX descriptor format for RX Ring.
105 */ 155 */
106 156
@@ -115,25 +165,25 @@
115 * AMSDU: rx with 802.3 header, not 802.11 header. 165 * AMSDU: rx with 802.3 header, not 802.11 header.
116 */ 166 */
117 167
118#define RXINFO_W0_BA FIELD32(0x00000001) 168#define RXD_W0_BA FIELD32(0x00000001)
119#define RXINFO_W0_DATA FIELD32(0x00000002) 169#define RXD_W0_DATA FIELD32(0x00000002)
120#define RXINFO_W0_NULLDATA FIELD32(0x00000004) 170#define RXD_W0_NULLDATA FIELD32(0x00000004)
121#define RXINFO_W0_FRAG FIELD32(0x00000008) 171#define RXD_W0_FRAG FIELD32(0x00000008)
122#define RXINFO_W0_UNICAST_TO_ME FIELD32(0x00000010) 172#define RXD_W0_UNICAST_TO_ME FIELD32(0x00000010)
123#define RXINFO_W0_MULTICAST FIELD32(0x00000020) 173#define RXD_W0_MULTICAST FIELD32(0x00000020)
124#define RXINFO_W0_BROADCAST FIELD32(0x00000040) 174#define RXD_W0_BROADCAST FIELD32(0x00000040)
125#define RXINFO_W0_MY_BSS FIELD32(0x00000080) 175#define RXD_W0_MY_BSS FIELD32(0x00000080)
126#define RXINFO_W0_CRC_ERROR FIELD32(0x00000100) 176#define RXD_W0_CRC_ERROR FIELD32(0x00000100)
127#define RXINFO_W0_CIPHER_ERROR FIELD32(0x00000600) 177#define RXD_W0_CIPHER_ERROR FIELD32(0x00000600)
128#define RXINFO_W0_AMSDU FIELD32(0x00000800) 178#define RXD_W0_AMSDU FIELD32(0x00000800)
129#define RXINFO_W0_HTC FIELD32(0x00001000) 179#define RXD_W0_HTC FIELD32(0x00001000)
130#define RXINFO_W0_RSSI FIELD32(0x00002000) 180#define RXD_W0_RSSI FIELD32(0x00002000)
131#define RXINFO_W0_L2PAD FIELD32(0x00004000) 181#define RXD_W0_L2PAD FIELD32(0x00004000)
132#define RXINFO_W0_AMPDU FIELD32(0x00008000) 182#define RXD_W0_AMPDU FIELD32(0x00008000)
133#define RXINFO_W0_DECRYPTED FIELD32(0x00010000) 183#define RXD_W0_DECRYPTED FIELD32(0x00010000)
134#define RXINFO_W0_PLCP_RSSI FIELD32(0x00020000) 184#define RXD_W0_PLCP_RSSI FIELD32(0x00020000)
135#define RXINFO_W0_CIPHER_ALG FIELD32(0x00040000) 185#define RXD_W0_CIPHER_ALG FIELD32(0x00040000)
136#define RXINFO_W0_LAST_AMSDU FIELD32(0x00080000) 186#define RXD_W0_LAST_AMSDU FIELD32(0x00080000)
137#define RXINFO_W0_PLCP_SIGNAL FIELD32(0xfff00000) 187#define RXD_W0_PLCP_SIGNAL FIELD32(0xfff00000)
138 188
139#endif /* RT2800USB_H */ 189#endif /* RT2800USB_H */
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h
index 4d841c07c970..194dae01d0c3 100644
--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
@@ -104,6 +104,12 @@
104#define GET_DURATION_RES(__size, __rate)(((__size) * 8 * 10) % (__rate)) 104#define GET_DURATION_RES(__size, __rate)(((__size) * 8 * 10) % (__rate))
105 105
106/* 106/*
107 * Determine the number of L2 padding bytes required between the header and
108 * the payload.
109 */
110#define L2PAD_SIZE(__hdrlen) (-(__hdrlen) & 3)
111
112/*
107 * Determine the alignment requirement, 113 * Determine the alignment requirement,
108 * to make sure the 802.11 payload is padded to a 4-byte boundrary 114 * to make sure the 802.11 payload is padded to a 4-byte boundrary
109 * we must determine the address of the payload and calculate the 115 * we must determine the address of the payload and calculate the
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c
index 06c43ca39bf8..d7711e4d4751 100644
--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
@@ -385,9 +385,6 @@ void rt2x00lib_rxdone(struct rt2x00_dev *rt2x00dev,
385 memset(&rxdesc, 0, sizeof(rxdesc)); 385 memset(&rxdesc, 0, sizeof(rxdesc));
386 rt2x00dev->ops->lib->fill_rxdone(entry, &rxdesc); 386 rt2x00dev->ops->lib->fill_rxdone(entry, &rxdesc);
387 387
388 /* Trim buffer to correct size */
389 skb_trim(entry->skb, rxdesc.size);
390
391 /* 388 /*
392 * The data behind the ieee80211 header must be 389 * The data behind the ieee80211 header must be
393 * aligned on a 4 byte boundary. 390 * aligned on a 4 byte boundary.
@@ -404,11 +401,16 @@ void rt2x00lib_rxdone(struct rt2x00_dev *rt2x00dev,
404 (rxdesc.flags & RX_FLAG_IV_STRIPPED)) 401 (rxdesc.flags & RX_FLAG_IV_STRIPPED))
405 rt2x00crypto_rx_insert_iv(entry->skb, header_length, 402 rt2x00crypto_rx_insert_iv(entry->skb, header_length,
406 &rxdesc); 403 &rxdesc);
407 else if (rxdesc.dev_flags & RXDONE_L2PAD) 404 else if (header_length &&
405 (rxdesc.size > header_length) &&
406 (rxdesc.dev_flags & RXDONE_L2PAD))
408 rt2x00queue_remove_l2pad(entry->skb, header_length); 407 rt2x00queue_remove_l2pad(entry->skb, header_length);
409 else 408 else
410 rt2x00queue_align_payload(entry->skb, header_length); 409 rt2x00queue_align_payload(entry->skb, header_length);
411 410
411 /* Trim buffer to correct size */
412 skb_trim(entry->skb, rxdesc.size);
413
412 /* 414 /*
413 * Check if the frame was received using HT. In that case, 415 * Check if the frame was received using HT. In that case,
414 * the rate is the MCS index and should be passed to mac80211 416 * the rate is the MCS index and should be passed to mac80211
diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.c b/drivers/net/wireless/rt2x00/rt2x00pci.c
index 0feb4d0e4668..801be436cf1d 100644
--- a/drivers/net/wireless/rt2x00/rt2x00pci.c
+++ b/drivers/net/wireless/rt2x00/rt2x00pci.c
@@ -41,6 +41,9 @@ int rt2x00pci_regbusy_read(struct rt2x00_dev *rt2x00dev,
41{ 41{
42 unsigned int i; 42 unsigned int i;
43 43
44 if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags))
45 return 0;
46
44 for (i = 0; i < REGISTER_BUSY_COUNT; i++) { 47 for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
45 rt2x00pci_register_read(rt2x00dev, offset, reg); 48 rt2x00pci_register_read(rt2x00dev, offset, reg);
46 if (!rt2x00_get_field32(*reg, field)) 49 if (!rt2x00_get_field32(*reg, field))
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c
index 239afc7a9c0b..3d8fb684b4eb 100644
--- a/drivers/net/wireless/rt2x00/rt2x00queue.c
+++ b/drivers/net/wireless/rt2x00/rt2x00queue.c
@@ -177,55 +177,45 @@ void rt2x00queue_align_payload(struct sk_buff *skb, unsigned int header_length)
177 177
178void rt2x00queue_insert_l2pad(struct sk_buff *skb, unsigned int header_length) 178void rt2x00queue_insert_l2pad(struct sk_buff *skb, unsigned int header_length)
179{ 179{
180 struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); 180 unsigned int payload_length = skb->len - header_length;
181 unsigned int frame_length = skb->len;
182 unsigned int header_align = ALIGN_SIZE(skb, 0); 181 unsigned int header_align = ALIGN_SIZE(skb, 0);
183 unsigned int payload_align = ALIGN_SIZE(skb, header_length); 182 unsigned int payload_align = ALIGN_SIZE(skb, header_length);
184 unsigned int l2pad = 4 - (payload_align - header_align); 183 unsigned int l2pad = payload_length ? L2PAD_SIZE(header_length) : 0;
185 184
186 if (header_align == payload_align) { 185 /*
187 /* 186 * Adjust the header alignment if the payload needs to be moved more
188 * Both header and payload must be moved the same 187 * than the header.
189 * amount of bytes to align them properly. This means 188 */
190 * we don't use the L2 padding but just move the entire 189 if (payload_align > header_align)
191 * frame. 190 header_align += 4;
192 */ 191
193 rt2x00queue_align_frame(skb); 192 /* There is nothing to do if no alignment is needed */
194 } else if (!payload_align) { 193 if (!header_align)
195 /* 194 return;
196 * Simple L2 padding, only the header needs to be moved, 195
197 * the payload is already properly aligned. 196 /* Reserve the amount of space needed in front of the frame */
198 */ 197 skb_push(skb, header_align);
199 skb_push(skb, header_align); 198
200 memmove(skb->data, skb->data + header_align, frame_length); 199 /*
201 skbdesc->flags |= SKBDESC_L2_PADDED; 200 * Move the header.
202 } else { 201 */
203 /* 202 memmove(skb->data, skb->data + header_align, header_length);
204 *
205 * Complicated L2 padding, both header and payload need
206 * to be moved. By default we only move to the start
207 * of the buffer, so our header alignment needs to be
208 * increased if there is not enough room for the header
209 * to be moved.
210 */
211 if (payload_align > header_align)
212 header_align += 4;
213 203
214 skb_push(skb, header_align); 204 /* Move the payload, if present and if required */
215 memmove(skb->data, skb->data + header_align, header_length); 205 if (payload_length && payload_align)
216 memmove(skb->data + header_length + l2pad, 206 memmove(skb->data + header_length + l2pad,
217 skb->data + header_length + l2pad + payload_align, 207 skb->data + header_length + l2pad + payload_align,
218 frame_length - header_length); 208 payload_length);
219 skbdesc->flags |= SKBDESC_L2_PADDED; 209
220 } 210 /* Trim the skb to the correct size */
211 skb_trim(skb, header_length + l2pad + payload_length);
221} 212}
222 213
223void rt2x00queue_remove_l2pad(struct sk_buff *skb, unsigned int header_length) 214void rt2x00queue_remove_l2pad(struct sk_buff *skb, unsigned int header_length)
224{ 215{
225 struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); 216 unsigned int l2pad = L2PAD_SIZE(header_length);
226 unsigned int l2pad = 4 - (header_length & 3);
227 217
228 if (!l2pad || (skbdesc->flags & SKBDESC_L2_PADDED)) 218 if (!l2pad)
229 return; 219 return;
230 220
231 memmove(skb->data + l2pad, skb->data, header_length); 221 memmove(skb->data + l2pad, skb->data, header_length);
@@ -346,7 +336,9 @@ static void rt2x00queue_create_tx_descriptor(struct queue_entry *entry,
346 * Header and alignment information. 336 * Header and alignment information.
347 */ 337 */
348 txdesc->header_length = ieee80211_get_hdrlen_from_skb(entry->skb); 338 txdesc->header_length = ieee80211_get_hdrlen_from_skb(entry->skb);
349 txdesc->l2pad = ALIGN_SIZE(entry->skb, txdesc->header_length); 339 if (test_bit(DRIVER_REQUIRE_L2PAD, &rt2x00dev->flags) &&
340 (entry->skb->len > txdesc->header_length))
341 txdesc->l2pad = L2PAD_SIZE(txdesc->header_length);
350 342
351 /* 343 /*
352 * Check whether this frame is to be acked. 344 * Check whether this frame is to be acked.
@@ -387,10 +379,13 @@ static void rt2x00queue_create_tx_descriptor(struct queue_entry *entry,
387 379
388 /* 380 /*
389 * Beacons and probe responses require the tsf timestamp 381 * Beacons and probe responses require the tsf timestamp
390 * to be inserted into the frame. 382 * to be inserted into the frame, except for a frame that has been injected
383 * through a monitor interface. This latter is needed for testing a
384 * monitor interface.
391 */ 385 */
392 if (ieee80211_is_beacon(hdr->frame_control) || 386 if ((ieee80211_is_beacon(hdr->frame_control) ||
393 ieee80211_is_probe_resp(hdr->frame_control)) 387 ieee80211_is_probe_resp(hdr->frame_control)) &&
388 (!(tx_info->flags & IEEE80211_TX_CTL_INJECTED)))
394 __set_bit(ENTRY_TXD_REQ_TIMESTAMP, &txdesc->flags); 389 __set_bit(ENTRY_TXD_REQ_TIMESTAMP, &txdesc->flags);
395 390
396 /* 391 /*
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.h b/drivers/net/wireless/rt2x00/rt2x00queue.h
index 70775e5ba1ac..c1e482bb37b3 100644
--- a/drivers/net/wireless/rt2x00/rt2x00queue.h
+++ b/drivers/net/wireless/rt2x00/rt2x00queue.h
@@ -92,8 +92,6 @@ enum data_queue_qid {
92 * @SKBDESC_DMA_MAPPED_TX: &skb_dma field has been mapped for TX 92 * @SKBDESC_DMA_MAPPED_TX: &skb_dma field has been mapped for TX
93 * @SKBDESC_IV_STRIPPED: Frame contained a IV/EIV provided by 93 * @SKBDESC_IV_STRIPPED: Frame contained a IV/EIV provided by
94 * mac80211 but was stripped for processing by the driver. 94 * mac80211 but was stripped for processing by the driver.
95 * @SKBDESC_L2_PADDED: Payload has been padded for 4-byte alignment,
96 * the padded bytes are located between header and payload.
97 * @SKBDESC_NOT_MAC80211: Frame didn't originate from mac80211, 95 * @SKBDESC_NOT_MAC80211: Frame didn't originate from mac80211,
98 * don't try to pass it back. 96 * don't try to pass it back.
99 */ 97 */
@@ -101,8 +99,7 @@ enum skb_frame_desc_flags {
101 SKBDESC_DMA_MAPPED_RX = 1 << 0, 99 SKBDESC_DMA_MAPPED_RX = 1 << 0,
102 SKBDESC_DMA_MAPPED_TX = 1 << 1, 100 SKBDESC_DMA_MAPPED_TX = 1 << 1,
103 SKBDESC_IV_STRIPPED = 1 << 2, 101 SKBDESC_IV_STRIPPED = 1 << 2,
104 SKBDESC_L2_PADDED = 1 << 3, 102 SKBDESC_NOT_MAC80211 = 1 << 3,
105 SKBDESC_NOT_MAC80211 = 1 << 4,
106}; 103};
107 104
108/** 105/**
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c
index ced3b6ab5e16..6ce88d3c3b65 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.c
+++ b/drivers/net/wireless/rt2x00/rt73usb.c
@@ -2354,6 +2354,7 @@ static struct usb_device_id rt73usb_device_table[] = {
2354 { USB_DEVICE(0x08dd, 0x0120), USB_DEVICE_DATA(&rt73usb_ops) }, 2354 { USB_DEVICE(0x08dd, 0x0120), USB_DEVICE_DATA(&rt73usb_ops) },
2355 /* Buffalo */ 2355 /* Buffalo */
2356 { USB_DEVICE(0x0411, 0x00d8), USB_DEVICE_DATA(&rt73usb_ops) }, 2356 { USB_DEVICE(0x0411, 0x00d8), USB_DEVICE_DATA(&rt73usb_ops) },
2357 { USB_DEVICE(0x0411, 0x00d9), USB_DEVICE_DATA(&rt73usb_ops) },
2357 { USB_DEVICE(0x0411, 0x00f4), USB_DEVICE_DATA(&rt73usb_ops) }, 2358 { USB_DEVICE(0x0411, 0x00f4), USB_DEVICE_DATA(&rt73usb_ops) },
2358 { USB_DEVICE(0x0411, 0x0116), USB_DEVICE_DATA(&rt73usb_ops) }, 2359 { USB_DEVICE(0x0411, 0x0116), USB_DEVICE_DATA(&rt73usb_ops) },
2359 { USB_DEVICE(0x0411, 0x0119), USB_DEVICE_DATA(&rt73usb_ops) }, 2360 { USB_DEVICE(0x0411, 0x0119), USB_DEVICE_DATA(&rt73usb_ops) },
diff --git a/drivers/net/wireless/rtl818x/rtl8180_dev.c b/drivers/net/wireless/rtl818x/rtl8180_dev.c
index a1a3dd15c664..8a40a1439984 100644
--- a/drivers/net/wireless/rtl818x/rtl8180_dev.c
+++ b/drivers/net/wireless/rtl818x/rtl8180_dev.c
@@ -132,7 +132,6 @@ static void rtl8180_handle_rx(struct ieee80211_hw *dev)
132 132
133 rx_status.antenna = (flags2 >> 15) & 1; 133 rx_status.antenna = (flags2 >> 15) & 1;
134 /* TODO: improve signal/rssi reporting */ 134 /* TODO: improve signal/rssi reporting */
135 rx_status.qual = flags2 & 0xFF;
136 rx_status.signal = (flags2 >> 8) & 0x7F; 135 rx_status.signal = (flags2 >> 8) & 0x7F;
137 /* XXX: is this correct? */ 136 /* XXX: is this correct? */
138 rx_status.rate_idx = (flags >> 20) & 0xF; 137 rx_status.rate_idx = (flags >> 20) & 0xF;
diff --git a/drivers/net/wireless/wl12xx/wl1251.h b/drivers/net/wireless/wl12xx/wl1251.h
index 054533f7a124..6301578d1565 100644
--- a/drivers/net/wireless/wl12xx/wl1251.h
+++ b/drivers/net/wireless/wl12xx/wl1251.h
@@ -247,6 +247,7 @@ struct wl1251_debugfs {
247 struct dentry *rxpipe_tx_xfr_host_int_trig_rx_data; 247 struct dentry *rxpipe_tx_xfr_host_int_trig_rx_data;
248 248
249 struct dentry *tx_queue_len; 249 struct dentry *tx_queue_len;
250 struct dentry *tx_queue_status;
250 251
251 struct dentry *retry_count; 252 struct dentry *retry_count;
252 struct dentry *excessive_retries; 253 struct dentry *excessive_retries;
diff --git a/drivers/net/wireless/wl12xx/wl1251_acx.c b/drivers/net/wireless/wl12xx/wl1251_acx.c
index acfa086dbfc5..beff084040b5 100644
--- a/drivers/net/wireless/wl12xx/wl1251_acx.c
+++ b/drivers/net/wireless/wl12xx/wl1251_acx.c
@@ -976,3 +976,72 @@ out:
976 kfree(acx); 976 kfree(acx);
977 return ret; 977 return ret;
978} 978}
979
980int wl1251_acx_ac_cfg(struct wl1251 *wl, u8 ac, u8 cw_min, u16 cw_max,
981 u8 aifs, u16 txop)
982{
983 struct wl1251_acx_ac_cfg *acx;
984 int ret = 0;
985
986 wl1251_debug(DEBUG_ACX, "acx ac cfg %d cw_ming %d cw_max %d "
987 "aifs %d txop %d", ac, cw_min, cw_max, aifs, txop);
988
989 acx = kzalloc(sizeof(*acx), GFP_KERNEL);
990
991 if (!acx) {
992 ret = -ENOMEM;
993 goto out;
994 }
995
996 acx->ac = ac;
997 acx->cw_min = cw_min;
998 acx->cw_max = cw_max;
999 acx->aifsn = aifs;
1000 acx->txop_limit = txop;
1001
1002 ret = wl1251_cmd_configure(wl, ACX_AC_CFG, acx, sizeof(*acx));
1003 if (ret < 0) {
1004 wl1251_warning("acx ac cfg failed: %d", ret);
1005 goto out;
1006 }
1007
1008out:
1009 kfree(acx);
1010 return ret;
1011}
1012
1013int wl1251_acx_tid_cfg(struct wl1251 *wl, u8 queue,
1014 enum wl1251_acx_channel_type type,
1015 u8 tsid, enum wl1251_acx_ps_scheme ps_scheme,
1016 enum wl1251_acx_ack_policy ack_policy)
1017{
1018 struct wl1251_acx_tid_cfg *acx;
1019 int ret = 0;
1020
1021 wl1251_debug(DEBUG_ACX, "acx tid cfg %d type %d tsid %d "
1022 "ps_scheme %d ack_policy %d", queue, type, tsid,
1023 ps_scheme, ack_policy);
1024
1025 acx = kzalloc(sizeof(*acx), GFP_KERNEL);
1026
1027 if (!acx) {
1028 ret = -ENOMEM;
1029 goto out;
1030 }
1031
1032 acx->queue = queue;
1033 acx->type = type;
1034 acx->tsid = tsid;
1035 acx->ps_scheme = ps_scheme;
1036 acx->ack_policy = ack_policy;
1037
1038 ret = wl1251_cmd_configure(wl, ACX_TID_CFG, acx, sizeof(*acx));
1039 if (ret < 0) {
1040 wl1251_warning("acx tid cfg failed: %d", ret);
1041 goto out;
1042 }
1043
1044out:
1045 kfree(acx);
1046 return ret;
1047}
diff --git a/drivers/net/wireless/wl12xx/wl1251_acx.h b/drivers/net/wireless/wl12xx/wl1251_acx.h
index 652371432cd8..26160c45784c 100644
--- a/drivers/net/wireless/wl12xx/wl1251_acx.h
+++ b/drivers/net/wireless/wl12xx/wl1251_acx.h
@@ -1166,6 +1166,87 @@ struct wl1251_acx_wr_tbtt_and_dtim {
1166 u8 padding; 1166 u8 padding;
1167} __attribute__ ((packed)); 1167} __attribute__ ((packed));
1168 1168
1169struct wl1251_acx_ac_cfg {
1170 struct acx_header header;
1171
1172 /*
1173 * Access Category - The TX queue's access category
1174 * (refer to AccessCategory_enum)
1175 */
1176 u8 ac;
1177
1178 /*
1179 * The contention window minimum size (in slots) for
1180 * the access class.
1181 */
1182 u8 cw_min;
1183
1184 /*
1185 * The contention window maximum size (in slots) for
1186 * the access class.
1187 */
1188 u16 cw_max;
1189
1190 /* The AIF value (in slots) for the access class. */
1191 u8 aifsn;
1192
1193 u8 reserved;
1194
1195 /* The TX Op Limit (in microseconds) for the access class. */
1196 u16 txop_limit;
1197} __attribute__ ((packed));
1198
1199
1200enum wl1251_acx_channel_type {
1201 CHANNEL_TYPE_DCF = 0,
1202 CHANNEL_TYPE_EDCF = 1,
1203 CHANNEL_TYPE_HCCA = 2,
1204};
1205
1206enum wl1251_acx_ps_scheme {
1207 /* regular ps: simple sending of packets */
1208 WL1251_ACX_PS_SCHEME_LEGACY = 0,
1209
1210 /* sending a packet triggers a unscheduled apsd downstream */
1211 WL1251_ACX_PS_SCHEME_UPSD_TRIGGER = 1,
1212
1213 /* a pspoll packet will be sent before every data packet */
1214 WL1251_ACX_PS_SCHEME_LEGACY_PSPOLL = 2,
1215
1216 /* scheduled apsd mode */
1217 WL1251_ACX_PS_SCHEME_SAPSD = 3,
1218};
1219
1220enum wl1251_acx_ack_policy {
1221 WL1251_ACX_ACK_POLICY_LEGACY = 0,
1222 WL1251_ACX_ACK_POLICY_NO_ACK = 1,
1223 WL1251_ACX_ACK_POLICY_BLOCK = 2,
1224};
1225
1226struct wl1251_acx_tid_cfg {
1227 struct acx_header header;
1228
1229 /* tx queue id number (0-7) */
1230 u8 queue;
1231
1232 /* channel access type for the queue, enum wl1251_acx_channel_type */
1233 u8 type;
1234
1235 /* EDCA: ac index (0-3), HCCA: traffic stream id (8-15) */
1236 u8 tsid;
1237
1238 /* ps scheme of the specified queue, enum wl1251_acx_ps_scheme */
1239 u8 ps_scheme;
1240
1241 /* the tx queue ack policy, enum wl1251_acx_ack_policy */
1242 u8 ack_policy;
1243
1244 u8 padding[3];
1245
1246 /* not supported */
1247 u32 apsdconf[2];
1248} __attribute__ ((packed));
1249
1169/************************************************************************* 1250/*************************************************************************
1170 1251
1171 Host Interrupt Register (WiLink -> Host) 1252 Host Interrupt Register (WiLink -> Host)
@@ -1322,5 +1403,11 @@ int wl1251_acx_tsf_info(struct wl1251 *wl, u64 *mactime);
1322int wl1251_acx_rate_policies(struct wl1251 *wl); 1403int wl1251_acx_rate_policies(struct wl1251 *wl);
1323int wl1251_acx_mem_cfg(struct wl1251 *wl); 1404int wl1251_acx_mem_cfg(struct wl1251 *wl);
1324int wl1251_acx_wr_tbtt_and_dtim(struct wl1251 *wl, u16 tbtt, u8 dtim); 1405int wl1251_acx_wr_tbtt_and_dtim(struct wl1251 *wl, u16 tbtt, u8 dtim);
1406int wl1251_acx_ac_cfg(struct wl1251 *wl, u8 ac, u8 cw_min, u16 cw_max,
1407 u8 aifs, u16 txop);
1408int wl1251_acx_tid_cfg(struct wl1251 *wl, u8 queue,
1409 enum wl1251_acx_channel_type type,
1410 u8 tsid, enum wl1251_acx_ps_scheme ps_scheme,
1411 enum wl1251_acx_ack_policy ack_policy);
1325 1412
1326#endif /* __WL1251_ACX_H__ */ 1413#endif /* __WL1251_ACX_H__ */
diff --git a/drivers/net/wireless/wl12xx/wl1251_debugfs.c b/drivers/net/wireless/wl12xx/wl1251_debugfs.c
index a00723059f83..0ccba57fb9fb 100644
--- a/drivers/net/wireless/wl12xx/wl1251_debugfs.c
+++ b/drivers/net/wireless/wl12xx/wl1251_debugfs.c
@@ -237,6 +237,27 @@ static const struct file_operations tx_queue_len_ops = {
237 .open = wl1251_open_file_generic, 237 .open = wl1251_open_file_generic,
238}; 238};
239 239
240static ssize_t tx_queue_status_read(struct file *file, char __user *userbuf,
241 size_t count, loff_t *ppos)
242{
243 struct wl1251 *wl = file->private_data;
244 char buf[3], status;
245 int len;
246
247 if (wl->tx_queue_stopped)
248 status = 's';
249 else
250 status = 'r';
251
252 len = scnprintf(buf, sizeof(buf), "%c\n", status);
253 return simple_read_from_buffer(userbuf, count, ppos, buf, len);
254}
255
256static const struct file_operations tx_queue_status_ops = {
257 .read = tx_queue_status_read,
258 .open = wl1251_open_file_generic,
259};
260
240static void wl1251_debugfs_delete_files(struct wl1251 *wl) 261static void wl1251_debugfs_delete_files(struct wl1251 *wl)
241{ 262{
242 DEBUGFS_FWSTATS_DEL(tx, internal_desc_overflow); 263 DEBUGFS_FWSTATS_DEL(tx, internal_desc_overflow);
@@ -331,6 +352,7 @@ static void wl1251_debugfs_delete_files(struct wl1251 *wl)
331 DEBUGFS_FWSTATS_DEL(rxpipe, tx_xfr_host_int_trig_rx_data); 352 DEBUGFS_FWSTATS_DEL(rxpipe, tx_xfr_host_int_trig_rx_data);
332 353
333 DEBUGFS_DEL(tx_queue_len); 354 DEBUGFS_DEL(tx_queue_len);
355 DEBUGFS_DEL(tx_queue_status);
334 DEBUGFS_DEL(retry_count); 356 DEBUGFS_DEL(retry_count);
335 DEBUGFS_DEL(excessive_retries); 357 DEBUGFS_DEL(excessive_retries);
336} 358}
@@ -431,6 +453,7 @@ static int wl1251_debugfs_add_files(struct wl1251 *wl)
431 DEBUGFS_FWSTATS_ADD(rxpipe, tx_xfr_host_int_trig_rx_data); 453 DEBUGFS_FWSTATS_ADD(rxpipe, tx_xfr_host_int_trig_rx_data);
432 454
433 DEBUGFS_ADD(tx_queue_len, wl->debugfs.rootdir); 455 DEBUGFS_ADD(tx_queue_len, wl->debugfs.rootdir);
456 DEBUGFS_ADD(tx_queue_status, wl->debugfs.rootdir);
434 DEBUGFS_ADD(retry_count, wl->debugfs.rootdir); 457 DEBUGFS_ADD(retry_count, wl->debugfs.rootdir);
435 DEBUGFS_ADD(excessive_retries, wl->debugfs.rootdir); 458 DEBUGFS_ADD(excessive_retries, wl->debugfs.rootdir);
436 459
diff --git a/drivers/net/wireless/wl12xx/wl1251_init.c b/drivers/net/wireless/wl12xx/wl1251_init.c
index 5cb573383eeb..5aad56ea7153 100644
--- a/drivers/net/wireless/wl12xx/wl1251_init.c
+++ b/drivers/net/wireless/wl12xx/wl1251_init.c
@@ -294,6 +294,11 @@ static int wl1251_hw_init_tx_queue_config(struct wl1251 *wl)
294 goto out; 294 goto out;
295 } 295 }
296 296
297 wl1251_acx_ac_cfg(wl, AC_BE, CWMIN_BE, CWMAX_BE, AIFS_DIFS, TXOP_BE);
298 wl1251_acx_ac_cfg(wl, AC_BK, CWMIN_BK, CWMAX_BK, AIFS_DIFS, TXOP_BK);
299 wl1251_acx_ac_cfg(wl, AC_VI, CWMIN_VI, CWMAX_VI, AIFS_DIFS, TXOP_VI);
300 wl1251_acx_ac_cfg(wl, AC_VO, CWMIN_VO, CWMAX_VO, AIFS_DIFS, TXOP_VO);
301
297out: 302out:
298 kfree(config); 303 kfree(config);
299 return ret; 304 return ret;
diff --git a/drivers/net/wireless/wl12xx/wl1251_init.h b/drivers/net/wireless/wl12xx/wl1251_init.h
index b3b25ec885ea..269cefb3e7d4 100644
--- a/drivers/net/wireless/wl12xx/wl1251_init.h
+++ b/drivers/net/wireless/wl12xx/wl1251_init.h
@@ -26,6 +26,53 @@
26 26
27#include "wl1251.h" 27#include "wl1251.h"
28 28
29enum {
30 /* best effort/legacy */
31 AC_BE = 0,
32
33 /* background */
34 AC_BK = 1,
35
36 /* video */
37 AC_VI = 2,
38
39 /* voice */
40 AC_VO = 3,
41
42 /* broadcast dummy access category */
43 AC_BCAST = 4,
44
45 NUM_ACCESS_CATEGORIES = 4
46};
47
48/* following are defult values for the IE fields*/
49#define CWMIN_BK 15
50#define CWMIN_BE 15
51#define CWMIN_VI 7
52#define CWMIN_VO 3
53#define CWMAX_BK 1023
54#define CWMAX_BE 63
55#define CWMAX_VI 15
56#define CWMAX_VO 7
57
58/* slot number setting to start transmission at PIFS interval */
59#define AIFS_PIFS 1
60
61/*
62 * slot number setting to start transmission at DIFS interval - normal DCF
63 * access
64 */
65#define AIFS_DIFS 2
66
67#define AIFSN_BK 7
68#define AIFSN_BE 3
69#define AIFSN_VI AIFS_PIFS
70#define AIFSN_VO AIFS_PIFS
71#define TXOP_BK 0
72#define TXOP_BE 0
73#define TXOP_VI 3008
74#define TXOP_VO 1504
75
29int wl1251_hw_init_hwenc_config(struct wl1251 *wl); 76int wl1251_hw_init_hwenc_config(struct wl1251 *wl);
30int wl1251_hw_init_templates_config(struct wl1251 *wl); 77int wl1251_hw_init_templates_config(struct wl1251 *wl);
31int wl1251_hw_init_rx_config(struct wl1251 *wl, u32 config, u32 filter); 78int wl1251_hw_init_rx_config(struct wl1251 *wl, u32 config, u32 filter);
diff --git a/drivers/net/wireless/wl12xx/wl1251_main.c b/drivers/net/wireless/wl12xx/wl1251_main.c
index 2f50a256efa5..6aeffbe9e401 100644
--- a/drivers/net/wireless/wl12xx/wl1251_main.c
+++ b/drivers/net/wireless/wl12xx/wl1251_main.c
@@ -395,6 +395,7 @@ static int wl1251_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
395 * the queue here, otherwise the queue will get too long. 395 * the queue here, otherwise the queue will get too long.
396 */ 396 */
397 if (skb_queue_len(&wl->tx_queue) >= WL1251_TX_QUEUE_MAX_LENGTH) { 397 if (skb_queue_len(&wl->tx_queue) >= WL1251_TX_QUEUE_MAX_LENGTH) {
398 wl1251_debug(DEBUG_TX, "op_tx: tx_queue full, stop queues");
398 ieee80211_stop_queues(wl->hw); 399 ieee80211_stop_queues(wl->hw);
399 400
400 /* 401 /*
@@ -640,20 +641,25 @@ static int wl1251_op_config(struct ieee80211_hw *hw, u32 changed)
640 * through the bss_info_changed() hook. 641 * through the bss_info_changed() hook.
641 */ 642 */
642 ret = wl1251_ps_set_mode(wl, STATION_POWER_SAVE_MODE); 643 ret = wl1251_ps_set_mode(wl, STATION_POWER_SAVE_MODE);
644 if (ret < 0)
645 goto out_sleep;
643 } else if (!(conf->flags & IEEE80211_CONF_PS) && 646 } else if (!(conf->flags & IEEE80211_CONF_PS) &&
644 wl->psm_requested) { 647 wl->psm_requested) {
645 wl1251_debug(DEBUG_PSM, "psm disabled"); 648 wl1251_debug(DEBUG_PSM, "psm disabled");
646 649
647 wl->psm_requested = false; 650 wl->psm_requested = false;
648 651
649 if (wl->psm) 652 if (wl->psm) {
650 ret = wl1251_ps_set_mode(wl, STATION_ACTIVE_MODE); 653 ret = wl1251_ps_set_mode(wl, STATION_ACTIVE_MODE);
654 if (ret < 0)
655 goto out_sleep;
656 }
651 } 657 }
652 658
653 if (conf->power_level != wl->power_level) { 659 if (conf->power_level != wl->power_level) {
654 ret = wl1251_acx_tx_power(wl, conf->power_level); 660 ret = wl1251_acx_tx_power(wl, conf->power_level);
655 if (ret < 0) 661 if (ret < 0)
656 goto out; 662 goto out_sleep;
657 663
658 wl->power_level = conf->power_level; 664 wl->power_level = conf->power_level;
659 } 665 }
@@ -1273,6 +1279,43 @@ static struct ieee80211_channel wl1251_channels[] = {
1273 { .hw_value = 13, .center_freq = 2472}, 1279 { .hw_value = 13, .center_freq = 2472},
1274}; 1280};
1275 1281
1282static int wl1251_op_conf_tx(struct ieee80211_hw *hw, u16 queue,
1283 const struct ieee80211_tx_queue_params *params)
1284{
1285 struct wl1251 *wl = hw->priv;
1286 int ret;
1287
1288 mutex_lock(&wl->mutex);
1289
1290 wl1251_debug(DEBUG_MAC80211, "mac80211 conf tx %d", queue);
1291
1292 ret = wl1251_ps_elp_wakeup(wl);
1293 if (ret < 0)
1294 goto out;
1295
1296 ret = wl1251_acx_ac_cfg(wl, wl1251_tx_get_queue(queue),
1297 params->cw_min, params->cw_max,
1298 params->aifs, params->txop);
1299 if (ret < 0)
1300 goto out_sleep;
1301
1302 ret = wl1251_acx_tid_cfg(wl, wl1251_tx_get_queue(queue),
1303 CHANNEL_TYPE_EDCF,
1304 wl1251_tx_get_queue(queue),
1305 WL1251_ACX_PS_SCHEME_LEGACY,
1306 WL1251_ACX_ACK_POLICY_LEGACY);
1307 if (ret < 0)
1308 goto out_sleep;
1309
1310out_sleep:
1311 wl1251_ps_elp_sleep(wl);
1312
1313out:
1314 mutex_unlock(&wl->mutex);
1315
1316 return ret;
1317}
1318
1276/* can't be const, mac80211 writes to this */ 1319/* can't be const, mac80211 writes to this */
1277static struct ieee80211_supported_band wl1251_band_2ghz = { 1320static struct ieee80211_supported_band wl1251_band_2ghz = {
1278 .channels = wl1251_channels, 1321 .channels = wl1251_channels,
@@ -1293,6 +1336,7 @@ static const struct ieee80211_ops wl1251_ops = {
1293 .hw_scan = wl1251_op_hw_scan, 1336 .hw_scan = wl1251_op_hw_scan,
1294 .bss_info_changed = wl1251_op_bss_info_changed, 1337 .bss_info_changed = wl1251_op_bss_info_changed,
1295 .set_rts_threshold = wl1251_op_set_rts_threshold, 1338 .set_rts_threshold = wl1251_op_set_rts_threshold,
1339 .conf_tx = wl1251_op_conf_tx,
1296}; 1340};
1297 1341
1298static int wl1251_register_hw(struct wl1251 *wl) 1342static int wl1251_register_hw(struct wl1251 *wl)
@@ -1338,6 +1382,8 @@ int wl1251_init_ieee80211(struct wl1251 *wl)
1338 wl->hw->wiphy->max_scan_ssids = 1; 1382 wl->hw->wiphy->max_scan_ssids = 1;
1339 wl->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &wl1251_band_2ghz; 1383 wl->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &wl1251_band_2ghz;
1340 1384
1385 wl->hw->queues = 4;
1386
1341 ret = wl1251_register_hw(wl); 1387 ret = wl1251_register_hw(wl);
1342 if (ret) 1388 if (ret)
1343 goto out; 1389 goto out;
diff --git a/drivers/net/wireless/wl12xx/wl1251_ps.c b/drivers/net/wireless/wl12xx/wl1251_ps.c
index 9931b197ff77..851dfb65e474 100644
--- a/drivers/net/wireless/wl12xx/wl1251_ps.c
+++ b/drivers/net/wireless/wl12xx/wl1251_ps.c
@@ -26,7 +26,8 @@
26#include "wl1251_cmd.h" 26#include "wl1251_cmd.h"
27#include "wl1251_io.h" 27#include "wl1251_io.h"
28 28
29#define WL1251_WAKEUP_TIMEOUT 2000 29/* in ms */
30#define WL1251_WAKEUP_TIMEOUT 100
30 31
31void wl1251_elp_work(struct work_struct *work) 32void wl1251_elp_work(struct work_struct *work)
32{ 33{
@@ -67,7 +68,7 @@ void wl1251_ps_elp_sleep(struct wl1251 *wl)
67 68
68int wl1251_ps_elp_wakeup(struct wl1251 *wl) 69int wl1251_ps_elp_wakeup(struct wl1251 *wl)
69{ 70{
70 unsigned long timeout; 71 unsigned long timeout, start;
71 u32 elp_reg; 72 u32 elp_reg;
72 73
73 if (!wl->elp) 74 if (!wl->elp)
@@ -75,6 +76,7 @@ int wl1251_ps_elp_wakeup(struct wl1251 *wl)
75 76
76 wl1251_debug(DEBUG_PSM, "waking up chip from elp"); 77 wl1251_debug(DEBUG_PSM, "waking up chip from elp");
77 78
79 start = jiffies;
78 timeout = jiffies + msecs_to_jiffies(WL1251_WAKEUP_TIMEOUT); 80 timeout = jiffies + msecs_to_jiffies(WL1251_WAKEUP_TIMEOUT);
79 81
80 wl1251_write32(wl, HW_ACCESS_ELP_CTRL_REG_ADDR, ELPCTRL_WAKE_UP); 82 wl1251_write32(wl, HW_ACCESS_ELP_CTRL_REG_ADDR, ELPCTRL_WAKE_UP);
@@ -95,8 +97,7 @@ int wl1251_ps_elp_wakeup(struct wl1251 *wl)
95 } 97 }
96 98
97 wl1251_debug(DEBUG_PSM, "wakeup time: %u ms", 99 wl1251_debug(DEBUG_PSM, "wakeup time: %u ms",
98 jiffies_to_msecs(jiffies) - 100 jiffies_to_msecs(jiffies - start));
99 (jiffies_to_msecs(timeout) - WL1251_WAKEUP_TIMEOUT));
100 101
101 wl->elp = false; 102 wl->elp = false;
102 103
diff --git a/drivers/net/wireless/wl12xx/wl1251_rx.c b/drivers/net/wireless/wl12xx/wl1251_rx.c
index f84cc89cbffc..b56732226cc0 100644
--- a/drivers/net/wireless/wl12xx/wl1251_rx.c
+++ b/drivers/net/wireless/wl12xx/wl1251_rx.c
@@ -126,7 +126,7 @@ static void wl1251_rx_body(struct wl1251 *wl,
126 if (wl->rx_current_buffer) 126 if (wl->rx_current_buffer)
127 rx_packet_ring_addr += wl->data_path->rx_packet_ring_chunk_size; 127 rx_packet_ring_addr += wl->data_path->rx_packet_ring_chunk_size;
128 128
129 skb = dev_alloc_skb(length); 129 skb = __dev_alloc_skb(length, GFP_KERNEL);
130 if (!skb) { 130 if (!skb) {
131 wl1251_error("Couldn't allocate RX frame"); 131 wl1251_error("Couldn't allocate RX frame");
132 return; 132 return;
diff --git a/drivers/net/wireless/wl12xx/wl1251_tx.c b/drivers/net/wireless/wl12xx/wl1251_tx.c
index f85970615849..c8223185efd2 100644
--- a/drivers/net/wireless/wl12xx/wl1251_tx.c
+++ b/drivers/net/wireless/wl12xx/wl1251_tx.c
@@ -167,8 +167,7 @@ static int wl1251_tx_fill_hdr(struct wl1251 *wl, struct sk_buff *skb,
167 tx_hdr->expiry_time = cpu_to_le32(1 << 16); 167 tx_hdr->expiry_time = cpu_to_le32(1 << 16);
168 tx_hdr->id = id; 168 tx_hdr->id = id;
169 169
170 /* FIXME: how to get the correct queue id? */ 170 tx_hdr->xmit_queue = wl1251_tx_get_queue(skb_get_queue_mapping(skb));
171 tx_hdr->xmit_queue = 0;
172 171
173 wl1251_tx_control(tx_hdr, control, fc); 172 wl1251_tx_control(tx_hdr, control, fc);
174 wl1251_tx_frag_block_num(tx_hdr); 173 wl1251_tx_frag_block_num(tx_hdr);
@@ -220,6 +219,7 @@ static int wl1251_tx_send_packet(struct wl1251 *wl, struct sk_buff *skb,
220 /* align the buffer on a 4-byte boundary */ 219 /* align the buffer on a 4-byte boundary */
221 skb_reserve(skb, offset); 220 skb_reserve(skb, offset);
222 memmove(skb->data, src, skb->len); 221 memmove(skb->data, src, skb->len);
222 tx_hdr = (struct tx_double_buffer_desc *) skb->data;
223 } else { 223 } else {
224 wl1251_info("No handler, fixme!"); 224 wl1251_info("No handler, fixme!");
225 return -EINVAL; 225 return -EINVAL;
@@ -237,8 +237,9 @@ static int wl1251_tx_send_packet(struct wl1251 *wl, struct sk_buff *skb,
237 237
238 wl1251_mem_write(wl, addr, skb->data, len); 238 wl1251_mem_write(wl, addr, skb->data, len);
239 239
240 wl1251_debug(DEBUG_TX, "tx id %u skb 0x%p payload %u rate 0x%x", 240 wl1251_debug(DEBUG_TX, "tx id %u skb 0x%p payload %u rate 0x%x "
241 tx_hdr->id, skb, tx_hdr->length, tx_hdr->rate); 241 "queue %d", tx_hdr->id, skb, tx_hdr->length,
242 tx_hdr->rate, tx_hdr->xmit_queue);
242 243
243 return 0; 244 return 0;
244} 245}
diff --git a/drivers/net/wireless/wl12xx/wl1251_tx.h b/drivers/net/wireless/wl12xx/wl1251_tx.h
index 7c1c1665c810..55856c6bb97a 100644
--- a/drivers/net/wireless/wl12xx/wl1251_tx.h
+++ b/drivers/net/wireless/wl12xx/wl1251_tx.h
@@ -26,6 +26,7 @@
26#define __WL1251_TX_H__ 26#define __WL1251_TX_H__
27 27
28#include <linux/bitops.h> 28#include <linux/bitops.h>
29#include "wl1251_acx.h"
29 30
30/* 31/*
31 * 32 *
@@ -209,6 +210,22 @@ struct tx_result {
209 u8 done_2; 210 u8 done_2;
210} __attribute__ ((packed)); 211} __attribute__ ((packed));
211 212
213static inline int wl1251_tx_get_queue(int queue)
214{
215 switch (queue) {
216 case 0:
217 return QOS_AC_VO;
218 case 1:
219 return QOS_AC_VI;
220 case 2:
221 return QOS_AC_BE;
222 case 3:
223 return QOS_AC_BK;
224 default:
225 return QOS_AC_BE;
226 }
227}
228
212void wl1251_tx_work(struct work_struct *work); 229void wl1251_tx_work(struct work_struct *work);
213void wl1251_tx_complete(struct wl1251 *wl); 230void wl1251_tx_complete(struct wl1251 *wl);
214void wl1251_tx_flush(struct wl1251 *wl); 231void wl1251_tx_flush(struct wl1251 *wl);
diff --git a/drivers/net/wireless/zd1211rw/zd_usb.c b/drivers/net/wireless/zd1211rw/zd_usb.c
index ac19ecd19cfe..4daf1c94ec04 100644
--- a/drivers/net/wireless/zd1211rw/zd_usb.c
+++ b/drivers/net/wireless/zd1211rw/zd_usb.c
@@ -1078,11 +1078,15 @@ static int eject_installer(struct usb_interface *intf)
1078 int r; 1078 int r;
1079 1079
1080 /* Find bulk out endpoint */ 1080 /* Find bulk out endpoint */
1081 endpoint = &iface_desc->endpoint[1].desc; 1081 for (r = 1; r >= 0; r--) {
1082 if (usb_endpoint_dir_out(endpoint) && 1082 endpoint = &iface_desc->endpoint[r].desc;
1083 usb_endpoint_xfer_bulk(endpoint)) { 1083 if (usb_endpoint_dir_out(endpoint) &&
1084 bulk_out_ep = endpoint->bEndpointAddress; 1084 usb_endpoint_xfer_bulk(endpoint)) {
1085 } else { 1085 bulk_out_ep = endpoint->bEndpointAddress;
1086 break;
1087 }
1088 }
1089 if (r == -1) {
1086 dev_err(&udev->dev, 1090 dev_err(&udev->dev,
1087 "zd1211rw: Could not find bulk out endpoint\n"); 1091 "zd1211rw: Could not find bulk out endpoint\n");
1088 return -ENODEV; 1092 return -ENODEV;
diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h
index 163c840437d6..d62edc7df3ae 100644
--- a/include/linux/ieee80211.h
+++ b/include/linux/ieee80211.h
@@ -707,6 +707,10 @@ struct ieee80211_mgmt {
707 u8 action; 707 u8 action;
708 u8 trans_id[WLAN_SA_QUERY_TR_ID_LEN]; 708 u8 trans_id[WLAN_SA_QUERY_TR_ID_LEN];
709 } __attribute__ ((packed)) sa_query; 709 } __attribute__ ((packed)) sa_query;
710 struct {
711 u8 action;
712 u8 smps_control;
713 } __attribute__ ((packed)) ht_smps;
710 } u; 714 } u;
711 } __attribute__ ((packed)) action; 715 } __attribute__ ((packed)) action;
712 } u; 716 } u;
@@ -771,7 +775,10 @@ struct ieee80211_bar {
771/** 775/**
772 * struct ieee80211_mcs_info - MCS information 776 * struct ieee80211_mcs_info - MCS information
773 * @rx_mask: RX mask 777 * @rx_mask: RX mask
774 * @rx_highest: highest supported RX rate 778 * @rx_highest: highest supported RX rate. If set represents
779 * the highest supported RX data rate in units of 1 Mbps.
780 * If this field is 0 this value should not be used to
781 * consider the highest RX data rate supported.
775 * @tx_params: TX parameters 782 * @tx_params: TX parameters
776 */ 783 */
777struct ieee80211_mcs_info { 784struct ieee80211_mcs_info {
@@ -824,6 +831,7 @@ struct ieee80211_ht_cap {
824#define IEEE80211_HT_CAP_LDPC_CODING 0x0001 831#define IEEE80211_HT_CAP_LDPC_CODING 0x0001
825#define IEEE80211_HT_CAP_SUP_WIDTH_20_40 0x0002 832#define IEEE80211_HT_CAP_SUP_WIDTH_20_40 0x0002
826#define IEEE80211_HT_CAP_SM_PS 0x000C 833#define IEEE80211_HT_CAP_SM_PS 0x000C
834#define IEEE80211_HT_CAP_SM_PS_SHIFT 2
827#define IEEE80211_HT_CAP_GRN_FLD 0x0010 835#define IEEE80211_HT_CAP_GRN_FLD 0x0010
828#define IEEE80211_HT_CAP_SGI_20 0x0020 836#define IEEE80211_HT_CAP_SGI_20 0x0020
829#define IEEE80211_HT_CAP_SGI_40 0x0040 837#define IEEE80211_HT_CAP_SGI_40 0x0040
@@ -839,6 +847,7 @@ struct ieee80211_ht_cap {
839/* 802.11n HT capability AMPDU settings (for ampdu_params_info) */ 847/* 802.11n HT capability AMPDU settings (for ampdu_params_info) */
840#define IEEE80211_HT_AMPDU_PARM_FACTOR 0x03 848#define IEEE80211_HT_AMPDU_PARM_FACTOR 0x03
841#define IEEE80211_HT_AMPDU_PARM_DENSITY 0x1C 849#define IEEE80211_HT_AMPDU_PARM_DENSITY 0x1C
850#define IEEE80211_HT_AMPDU_PARM_DENSITY_SHIFT 2
842 851
843/* 852/*
844 * Maximum length of AMPDU that the STA can receive. 853 * Maximum length of AMPDU that the STA can receive.
@@ -922,12 +931,17 @@ struct ieee80211_ht_info {
922#define IEEE80211_MAX_AMPDU_BUF 0x40 931#define IEEE80211_MAX_AMPDU_BUF 0x40
923 932
924 933
925/* Spatial Multiplexing Power Save Modes */ 934/* Spatial Multiplexing Power Save Modes (for capability) */
926#define WLAN_HT_CAP_SM_PS_STATIC 0 935#define WLAN_HT_CAP_SM_PS_STATIC 0
927#define WLAN_HT_CAP_SM_PS_DYNAMIC 1 936#define WLAN_HT_CAP_SM_PS_DYNAMIC 1
928#define WLAN_HT_CAP_SM_PS_INVALID 2 937#define WLAN_HT_CAP_SM_PS_INVALID 2
929#define WLAN_HT_CAP_SM_PS_DISABLED 3 938#define WLAN_HT_CAP_SM_PS_DISABLED 3
930 939
940/* for SM power control field lower two bits */
941#define WLAN_HT_SMPS_CONTROL_DISABLED 0
942#define WLAN_HT_SMPS_CONTROL_STATIC 1
943#define WLAN_HT_SMPS_CONTROL_DYNAMIC 3
944
931/* Authentication algorithms */ 945/* Authentication algorithms */
932#define WLAN_AUTH_OPEN 0 946#define WLAN_AUTH_OPEN 0
933#define WLAN_AUTH_SHARED_KEY 1 947#define WLAN_AUTH_SHARED_KEY 1
@@ -1150,6 +1164,18 @@ enum ieee80211_spectrum_mgmt_actioncode {
1150 WLAN_ACTION_SPCT_CHL_SWITCH = 4, 1164 WLAN_ACTION_SPCT_CHL_SWITCH = 4,
1151}; 1165};
1152 1166
1167/* HT action codes */
1168enum ieee80211_ht_actioncode {
1169 WLAN_HT_ACTION_NOTIFY_CHANWIDTH = 0,
1170 WLAN_HT_ACTION_SMPS = 1,
1171 WLAN_HT_ACTION_PSMP = 2,
1172 WLAN_HT_ACTION_PCO_PHASE = 3,
1173 WLAN_HT_ACTION_CSI = 4,
1174 WLAN_HT_ACTION_NONCOMPRESSED_BF = 5,
1175 WLAN_HT_ACTION_COMPRESSED_BF = 6,
1176 WLAN_HT_ACTION_ASEL_IDX_FEEDBACK = 7,
1177};
1178
1153/* Security key length */ 1179/* Security key length */
1154enum ieee80211_key_len { 1180enum ieee80211_key_len {
1155 WLAN_KEY_LEN_WEP40 = 5, 1181 WLAN_KEY_LEN_WEP40 = 5,
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 0884b9a0f778..542a477a94da 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -1578,7 +1578,7 @@ unsigned int ieee80211_hdrlen(__le16 fc);
1578 * @addr: the device MAC address 1578 * @addr: the device MAC address
1579 * @iftype: the virtual interface type 1579 * @iftype: the virtual interface type
1580 */ 1580 */
1581int ieee80211_data_to_8023(struct sk_buff *skb, u8 *addr, 1581int ieee80211_data_to_8023(struct sk_buff *skb, const u8 *addr,
1582 enum nl80211_iftype iftype); 1582 enum nl80211_iftype iftype);
1583 1583
1584/** 1584/**
@@ -1589,10 +1589,28 @@ int ieee80211_data_to_8023(struct sk_buff *skb, u8 *addr,
1589 * @bssid: the network bssid (used only for iftype STATION and ADHOC) 1589 * @bssid: the network bssid (used only for iftype STATION and ADHOC)
1590 * @qos: build 802.11 QoS data frame 1590 * @qos: build 802.11 QoS data frame
1591 */ 1591 */
1592int ieee80211_data_from_8023(struct sk_buff *skb, u8 *addr, 1592int ieee80211_data_from_8023(struct sk_buff *skb, const u8 *addr,
1593 enum nl80211_iftype iftype, u8 *bssid, bool qos); 1593 enum nl80211_iftype iftype, u8 *bssid, bool qos);
1594 1594
1595/** 1595/**
1596 * ieee80211_amsdu_to_8023s - decode an IEEE 802.11n A-MSDU frame
1597 *
1598 * Decode an IEEE 802.11n A-MSDU frame and convert it to a list of
1599 * 802.3 frames. The @list will be empty if the decode fails. The
1600 * @skb is consumed after the function returns.
1601 *
1602 * @skb: The input IEEE 802.11n A-MSDU frame.
1603 * @list: The output list of 802.3 frames. It must be allocated and
1604 * initialized by by the caller.
1605 * @addr: The device MAC address.
1606 * @iftype: The device interface type.
1607 * @extra_headroom: The hardware extra headroom for SKBs in the @list.
1608 */
1609void ieee80211_amsdu_to_8023s(struct sk_buff *skb, struct sk_buff_head *list,
1610 const u8 *addr, enum nl80211_iftype iftype,
1611 const unsigned int extra_headroom);
1612
1613/**
1596 * cfg80211_classify8021d - determine the 802.1p/1d tag for a data frame 1614 * cfg80211_classify8021d - determine the 802.1p/1d tag for a data frame
1597 * @skb: the data frame 1615 * @skb: the data frame
1598 */ 1616 */
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 538d6b761887..494ac69ff477 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -597,8 +597,10 @@ enum ieee80211_conf_flags {
597 * @IEEE80211_CONF_CHANGE_CHANNEL: the channel/channel_type changed 597 * @IEEE80211_CONF_CHANGE_CHANNEL: the channel/channel_type changed
598 * @IEEE80211_CONF_CHANGE_RETRY_LIMITS: retry limits changed 598 * @IEEE80211_CONF_CHANGE_RETRY_LIMITS: retry limits changed
599 * @IEEE80211_CONF_CHANGE_IDLE: Idle flag changed 599 * @IEEE80211_CONF_CHANGE_IDLE: Idle flag changed
600 * @IEEE80211_CONF_CHANGE_SMPS: Spatial multiplexing powersave mode changed
600 */ 601 */
601enum ieee80211_conf_changed { 602enum ieee80211_conf_changed {
603 IEEE80211_CONF_CHANGE_SMPS = BIT(1),
602 IEEE80211_CONF_CHANGE_LISTEN_INTERVAL = BIT(2), 604 IEEE80211_CONF_CHANGE_LISTEN_INTERVAL = BIT(2),
603 IEEE80211_CONF_CHANGE_MONITOR = BIT(3), 605 IEEE80211_CONF_CHANGE_MONITOR = BIT(3),
604 IEEE80211_CONF_CHANGE_PS = BIT(4), 606 IEEE80211_CONF_CHANGE_PS = BIT(4),
@@ -609,6 +611,21 @@ enum ieee80211_conf_changed {
609}; 611};
610 612
611/** 613/**
614 * enum ieee80211_smps_mode - spatial multiplexing power save mode
615 *
616 * @
617 */
618enum ieee80211_smps_mode {
619 IEEE80211_SMPS_AUTOMATIC,
620 IEEE80211_SMPS_OFF,
621 IEEE80211_SMPS_STATIC,
622 IEEE80211_SMPS_DYNAMIC,
623
624 /* keep last */
625 IEEE80211_SMPS_NUM_MODES,
626};
627
628/**
612 * struct ieee80211_conf - configuration of the device 629 * struct ieee80211_conf - configuration of the device
613 * 630 *
614 * This struct indicates how the driver shall configure the hardware. 631 * This struct indicates how the driver shall configure the hardware.
@@ -636,6 +653,10 @@ enum ieee80211_conf_changed {
636 * @short_frame_max_tx_count: Maximum number of transmissions for a "short" 653 * @short_frame_max_tx_count: Maximum number of transmissions for a "short"
637 * frame, called "dot11ShortRetryLimit" in 802.11, but actually means the 654 * frame, called "dot11ShortRetryLimit" in 802.11, but actually means the
638 * number of transmissions not the number of retries 655 * number of transmissions not the number of retries
656 *
657 * @smps_mode: spatial multiplexing powersave mode; note that
658 * %IEEE80211_SMPS_STATIC is used when the device is not
659 * configured for an HT channel
639 */ 660 */
640struct ieee80211_conf { 661struct ieee80211_conf {
641 u32 flags; 662 u32 flags;
@@ -648,6 +669,7 @@ struct ieee80211_conf {
648 669
649 struct ieee80211_channel *channel; 670 struct ieee80211_channel *channel;
650 enum nl80211_channel_type channel_type; 671 enum nl80211_channel_type channel_type;
672 enum ieee80211_smps_mode smps_mode;
651}; 673};
652 674
653/** 675/**
@@ -659,12 +681,14 @@ struct ieee80211_conf {
659 * @type: type of this virtual interface 681 * @type: type of this virtual interface
660 * @bss_conf: BSS configuration for this interface, either our own 682 * @bss_conf: BSS configuration for this interface, either our own
661 * or the BSS we're associated to 683 * or the BSS we're associated to
684 * @addr: address of this interface
662 * @drv_priv: data area for driver use, will always be aligned to 685 * @drv_priv: data area for driver use, will always be aligned to
663 * sizeof(void *). 686 * sizeof(void *).
664 */ 687 */
665struct ieee80211_vif { 688struct ieee80211_vif {
666 enum nl80211_iftype type; 689 enum nl80211_iftype type;
667 struct ieee80211_bss_conf bss_conf; 690 struct ieee80211_bss_conf bss_conf;
691 u8 addr[ETH_ALEN];
668 /* must be last */ 692 /* must be last */
669 u8 drv_priv[0] __attribute__((__aligned__(sizeof(void *)))); 693 u8 drv_priv[0] __attribute__((__aligned__(sizeof(void *))));
670}; 694};
@@ -928,6 +952,16 @@ enum ieee80211_tkip_key_type {
928 * @IEEE80211_HW_BEACON_FILTER: 952 * @IEEE80211_HW_BEACON_FILTER:
929 * Hardware supports dropping of irrelevant beacon frames to 953 * Hardware supports dropping of irrelevant beacon frames to
930 * avoid waking up cpu. 954 * avoid waking up cpu.
955 *
956 * @IEEE80211_HW_SUPPORTS_STATIC_SMPS:
957 * Hardware supports static spatial multiplexing powersave,
958 * ie. can turn off all but one chain even on HT connections
959 * that should be using more chains.
960 *
961 * @IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS:
962 * Hardware supports dynamic spatial multiplexing powersave,
963 * ie. can turn off all but one chain and then wake the rest
964 * up as required after, for example, rts/cts handshake.
931 */ 965 */
932enum ieee80211_hw_flags { 966enum ieee80211_hw_flags {
933 IEEE80211_HW_HAS_RATE_CONTROL = 1<<0, 967 IEEE80211_HW_HAS_RATE_CONTROL = 1<<0,
@@ -945,6 +979,8 @@ enum ieee80211_hw_flags {
945 IEEE80211_HW_SUPPORTS_DYNAMIC_PS = 1<<12, 979 IEEE80211_HW_SUPPORTS_DYNAMIC_PS = 1<<12,
946 IEEE80211_HW_MFP_CAPABLE = 1<<13, 980 IEEE80211_HW_MFP_CAPABLE = 1<<13,
947 IEEE80211_HW_BEACON_FILTER = 1<<14, 981 IEEE80211_HW_BEACON_FILTER = 1<<14,
982 IEEE80211_HW_SUPPORTS_STATIC_SMPS = 1<<15,
983 IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS = 1<<16,
948}; 984};
949 985
950/** 986/**
@@ -1213,6 +1249,31 @@ ieee80211_get_alt_retry_rate(const struct ieee80211_hw *hw,
1213 */ 1249 */
1214 1250
1215/** 1251/**
1252 * DOC: Spatial multiplexing power save
1253 *
1254 * SMPS (Spatial multiplexing power save) is a mechanism to conserve
1255 * power in an 802.11n implementation. For details on the mechanism
1256 * and rationale, please refer to 802.11 (as amended by 802.11n-2009)
1257 * "11.2.3 SM power save".
1258 *
1259 * The mac80211 implementation is capable of sending action frames
1260 * to update the AP about the station's SMPS mode, and will instruct
1261 * the driver to enter the specific mode. It will also announce the
1262 * requested SMPS mode during the association handshake. Hardware
1263 * support for this feature is required, and can be indicated by
1264 * hardware flags.
1265 *
1266 * The default mode will be "automatic", which nl80211/cfg80211
1267 * defines to be dynamic SMPS in (regular) powersave, and SMPS
1268 * turned off otherwise.
1269 *
1270 * To support this feature, the driver must set the appropriate
1271 * hardware support flags, and handle the SMPS flag to the config()
1272 * operation. It will then with this mechanism be instructed to
1273 * enter the requested SMPS mode while associated to an HT AP.
1274 */
1275
1276/**
1216 * DOC: Frame filtering 1277 * DOC: Frame filtering
1217 * 1278 *
1218 * mac80211 requires to see many management frames for proper 1279 * mac80211 requires to see many management frames for proper
diff --git a/net/mac80211/Kconfig b/net/mac80211/Kconfig
index a10d508b07e1..a952b7f8c648 100644
--- a/net/mac80211/Kconfig
+++ b/net/mac80211/Kconfig
@@ -96,18 +96,6 @@ menuconfig MAC80211_DEBUG_MENU
96 ---help--- 96 ---help---
97 This option collects various mac80211 debug settings. 97 This option collects various mac80211 debug settings.
98 98
99config MAC80211_DEBUG_PACKET_ALIGNMENT
100 bool "Enable packet alignment debugging"
101 depends on MAC80211_DEBUG_MENU
102 ---help---
103 This option is recommended for driver authors and strongly
104 discouraged for everybody else, it will trigger a warning
105 when a driver hands mac80211 a buffer that is aligned in
106 a way that will cause problems with the IP stack on some
107 architectures.
108
109 Say N unless you're writing a mac80211 based driver.
110
111config MAC80211_NOINLINE 99config MAC80211_NOINLINE
112 bool "Do not inline TX/RX handlers" 100 bool "Do not inline TX/RX handlers"
113 depends on MAC80211_DEBUG_MENU 101 depends on MAC80211_DEBUG_MENU
diff --git a/net/mac80211/agg-rx.c b/net/mac80211/agg-rx.c
index 51c7dc3c4c3b..a978e666ed6f 100644
--- a/net/mac80211/agg-rx.c
+++ b/net/mac80211/agg-rx.c
@@ -41,8 +41,7 @@ void __ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid,
41 sta->sta.addr, tid); 41 sta->sta.addr, tid);
42#endif /* CONFIG_MAC80211_HT_DEBUG */ 42#endif /* CONFIG_MAC80211_HT_DEBUG */
43 43
44 if (drv_ampdu_action(local, &sta->sdata->vif, 44 if (drv_ampdu_action(local, sta->sdata, IEEE80211_AMPDU_RX_STOP,
45 IEEE80211_AMPDU_RX_STOP,
46 &sta->sta, tid, NULL)) 45 &sta->sta, tid, NULL))
47 printk(KERN_DEBUG "HW problem - can not stop rx " 46 printk(KERN_DEBUG "HW problem - can not stop rx "
48 "aggregation for tid %d\n", tid); 47 "aggregation for tid %d\n", tid);
@@ -83,12 +82,11 @@ void __ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid,
83void ieee80211_sta_stop_rx_ba_session(struct ieee80211_sub_if_data *sdata, u8 *ra, u16 tid, 82void ieee80211_sta_stop_rx_ba_session(struct ieee80211_sub_if_data *sdata, u8 *ra, u16 tid,
84 u16 initiator, u16 reason) 83 u16 initiator, u16 reason)
85{ 84{
86 struct ieee80211_local *local = sdata->local;
87 struct sta_info *sta; 85 struct sta_info *sta;
88 86
89 rcu_read_lock(); 87 rcu_read_lock();
90 88
91 sta = sta_info_get(local, ra); 89 sta = sta_info_get(sdata, ra);
92 if (!sta) { 90 if (!sta) {
93 rcu_read_unlock(); 91 rcu_read_unlock();
94 return; 92 return;
@@ -136,7 +134,7 @@ static void ieee80211_send_addba_resp(struct ieee80211_sub_if_data *sdata, u8 *d
136 134
137 if (!skb) { 135 if (!skb) {
138 printk(KERN_DEBUG "%s: failed to allocate buffer " 136 printk(KERN_DEBUG "%s: failed to allocate buffer "
139 "for addba resp frame\n", sdata->dev->name); 137 "for addba resp frame\n", sdata->name);
140 return; 138 return;
141 } 139 }
142 140
@@ -144,10 +142,10 @@ static void ieee80211_send_addba_resp(struct ieee80211_sub_if_data *sdata, u8 *d
144 mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24); 142 mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24);
145 memset(mgmt, 0, 24); 143 memset(mgmt, 0, 24);
146 memcpy(mgmt->da, da, ETH_ALEN); 144 memcpy(mgmt->da, da, ETH_ALEN);
147 memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN); 145 memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN);
148 if (sdata->vif.type == NL80211_IFTYPE_AP || 146 if (sdata->vif.type == NL80211_IFTYPE_AP ||
149 sdata->vif.type == NL80211_IFTYPE_AP_VLAN) 147 sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
150 memcpy(mgmt->bssid, sdata->dev->dev_addr, ETH_ALEN); 148 memcpy(mgmt->bssid, sdata->vif.addr, ETH_ALEN);
151 else if (sdata->vif.type == NL80211_IFTYPE_STATION) 149 else if (sdata->vif.type == NL80211_IFTYPE_STATION)
152 memcpy(mgmt->bssid, sdata->u.mgd.bssid, ETH_ALEN); 150 memcpy(mgmt->bssid, sdata->u.mgd.bssid, ETH_ALEN);
153 151
@@ -281,8 +279,7 @@ void ieee80211_process_addba_request(struct ieee80211_local *local,
281 goto end; 279 goto end;
282 } 280 }
283 281
284 ret = drv_ampdu_action(local, &sta->sdata->vif, 282 ret = drv_ampdu_action(local, sta->sdata, IEEE80211_AMPDU_RX_START,
285 IEEE80211_AMPDU_RX_START,
286 &sta->sta, tid, &start_seq_num); 283 &sta->sta, tid, &start_seq_num);
287#ifdef CONFIG_MAC80211_HT_DEBUG 284#ifdef CONFIG_MAC80211_HT_DEBUG
288 printk(KERN_DEBUG "Rx A-MPDU request on tid %d result %d\n", tid, ret); 285 printk(KERN_DEBUG "Rx A-MPDU request on tid %d result %d\n", tid, ret);
diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c
index 5e3a7eccef5a..ceda36618d3c 100644
--- a/net/mac80211/agg-tx.c
+++ b/net/mac80211/agg-tx.c
@@ -58,17 +58,17 @@ static void ieee80211_send_addba_request(struct ieee80211_sub_if_data *sdata,
58 58
59 if (!skb) { 59 if (!skb) {
60 printk(KERN_ERR "%s: failed to allocate buffer " 60 printk(KERN_ERR "%s: failed to allocate buffer "
61 "for addba request frame\n", sdata->dev->name); 61 "for addba request frame\n", sdata->name);
62 return; 62 return;
63 } 63 }
64 skb_reserve(skb, local->hw.extra_tx_headroom); 64 skb_reserve(skb, local->hw.extra_tx_headroom);
65 mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24); 65 mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24);
66 memset(mgmt, 0, 24); 66 memset(mgmt, 0, 24);
67 memcpy(mgmt->da, da, ETH_ALEN); 67 memcpy(mgmt->da, da, ETH_ALEN);
68 memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN); 68 memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN);
69 if (sdata->vif.type == NL80211_IFTYPE_AP || 69 if (sdata->vif.type == NL80211_IFTYPE_AP ||
70 sdata->vif.type == NL80211_IFTYPE_AP_VLAN) 70 sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
71 memcpy(mgmt->bssid, sdata->dev->dev_addr, ETH_ALEN); 71 memcpy(mgmt->bssid, sdata->vif.addr, ETH_ALEN);
72 else if (sdata->vif.type == NL80211_IFTYPE_STATION) 72 else if (sdata->vif.type == NL80211_IFTYPE_STATION)
73 memcpy(mgmt->bssid, sdata->u.mgd.bssid, ETH_ALEN); 73 memcpy(mgmt->bssid, sdata->u.mgd.bssid, ETH_ALEN);
74 74
@@ -104,7 +104,7 @@ void ieee80211_send_bar(struct ieee80211_sub_if_data *sdata, u8 *ra, u16 tid, u1
104 skb = dev_alloc_skb(sizeof(*bar) + local->hw.extra_tx_headroom); 104 skb = dev_alloc_skb(sizeof(*bar) + local->hw.extra_tx_headroom);
105 if (!skb) { 105 if (!skb) {
106 printk(KERN_ERR "%s: failed to allocate buffer for " 106 printk(KERN_ERR "%s: failed to allocate buffer for "
107 "bar frame\n", sdata->dev->name); 107 "bar frame\n", sdata->name);
108 return; 108 return;
109 } 109 }
110 skb_reserve(skb, local->hw.extra_tx_headroom); 110 skb_reserve(skb, local->hw.extra_tx_headroom);
@@ -113,7 +113,7 @@ void ieee80211_send_bar(struct ieee80211_sub_if_data *sdata, u8 *ra, u16 tid, u1
113 bar->frame_control = cpu_to_le16(IEEE80211_FTYPE_CTL | 113 bar->frame_control = cpu_to_le16(IEEE80211_FTYPE_CTL |
114 IEEE80211_STYPE_BACK_REQ); 114 IEEE80211_STYPE_BACK_REQ);
115 memcpy(bar->ra, ra, ETH_ALEN); 115 memcpy(bar->ra, ra, ETH_ALEN);
116 memcpy(bar->ta, sdata->dev->dev_addr, ETH_ALEN); 116 memcpy(bar->ta, sdata->vif.addr, ETH_ALEN);
117 bar_control |= (u16)IEEE80211_BAR_CTRL_ACK_POLICY_NORMAL; 117 bar_control |= (u16)IEEE80211_BAR_CTRL_ACK_POLICY_NORMAL;
118 bar_control |= (u16)IEEE80211_BAR_CTRL_CBMTID_COMPRESSED_BA; 118 bar_control |= (u16)IEEE80211_BAR_CTRL_CBMTID_COMPRESSED_BA;
119 bar_control |= (u16)(tid << 12); 119 bar_control |= (u16)(tid << 12);
@@ -144,7 +144,7 @@ int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid,
144 *state = HT_AGG_STATE_REQ_STOP_BA_MSK | 144 *state = HT_AGG_STATE_REQ_STOP_BA_MSK |
145 (initiator << HT_AGG_STATE_INITIATOR_SHIFT); 145 (initiator << HT_AGG_STATE_INITIATOR_SHIFT);
146 146
147 ret = drv_ampdu_action(local, &sta->sdata->vif, 147 ret = drv_ampdu_action(local, sta->sdata,
148 IEEE80211_AMPDU_TX_STOP, 148 IEEE80211_AMPDU_TX_STOP,
149 &sta->sta, tid, NULL); 149 &sta->sta, tid, NULL);
150 150
@@ -303,8 +303,7 @@ int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid)
303 303
304 start_seq_num = sta->tid_seq[tid]; 304 start_seq_num = sta->tid_seq[tid];
305 305
306 ret = drv_ampdu_action(local, &sdata->vif, 306 ret = drv_ampdu_action(local, sdata, IEEE80211_AMPDU_TX_START,
307 IEEE80211_AMPDU_TX_START,
308 pubsta, tid, &start_seq_num); 307 pubsta, tid, &start_seq_num);
309 308
310 if (ret) { 309 if (ret) {
@@ -420,7 +419,7 @@ static void ieee80211_agg_tx_operational(struct ieee80211_local *local,
420 ieee80211_agg_splice_finish(local, sta, tid); 419 ieee80211_agg_splice_finish(local, sta, tid);
421 spin_unlock(&local->ampdu_lock); 420 spin_unlock(&local->ampdu_lock);
422 421
423 drv_ampdu_action(local, &sta->sdata->vif, 422 drv_ampdu_action(local, sta->sdata,
424 IEEE80211_AMPDU_TX_OPERATIONAL, 423 IEEE80211_AMPDU_TX_OPERATIONAL,
425 &sta->sta, tid, NULL); 424 &sta->sta, tid, NULL);
426} 425}
@@ -441,7 +440,7 @@ void ieee80211_start_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u16 tid)
441 } 440 }
442 441
443 rcu_read_lock(); 442 rcu_read_lock();
444 sta = sta_info_get(local, ra); 443 sta = sta_info_get(sdata, ra);
445 if (!sta) { 444 if (!sta) {
446 rcu_read_unlock(); 445 rcu_read_unlock();
447#ifdef CONFIG_MAC80211_HT_DEBUG 446#ifdef CONFIG_MAC80211_HT_DEBUG
@@ -489,7 +488,7 @@ void ieee80211_start_tx_ba_cb_irqsafe(struct ieee80211_vif *vif,
489#ifdef CONFIG_MAC80211_HT_DEBUG 488#ifdef CONFIG_MAC80211_HT_DEBUG
490 if (net_ratelimit()) 489 if (net_ratelimit())
491 printk(KERN_WARNING "%s: Not enough memory, " 490 printk(KERN_WARNING "%s: Not enough memory, "
492 "dropping start BA session", skb->dev->name); 491 "dropping start BA session", sdata->name);
493#endif 492#endif
494 return; 493 return;
495 } 494 }
@@ -564,7 +563,7 @@ void ieee80211_stop_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u8 tid)
564#endif /* CONFIG_MAC80211_HT_DEBUG */ 563#endif /* CONFIG_MAC80211_HT_DEBUG */
565 564
566 rcu_read_lock(); 565 rcu_read_lock();
567 sta = sta_info_get(local, ra); 566 sta = sta_info_get(sdata, ra);
568 if (!sta) { 567 if (!sta) {
569#ifdef CONFIG_MAC80211_HT_DEBUG 568#ifdef CONFIG_MAC80211_HT_DEBUG
570 printk(KERN_DEBUG "Could not find station: %pM\n", ra); 569 printk(KERN_DEBUG "Could not find station: %pM\n", ra);
@@ -621,7 +620,7 @@ void ieee80211_stop_tx_ba_cb_irqsafe(struct ieee80211_vif *vif,
621#ifdef CONFIG_MAC80211_HT_DEBUG 620#ifdef CONFIG_MAC80211_HT_DEBUG
622 if (net_ratelimit()) 621 if (net_ratelimit())
623 printk(KERN_WARNING "%s: Not enough memory, " 622 printk(KERN_WARNING "%s: Not enough memory, "
624 "dropping stop BA session", skb->dev->name); 623 "dropping stop BA session", sdata->name);
625#endif 624#endif
626 return; 625 return;
627 } 626 }
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 6dc3579c0ac5..63843e3e576a 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -150,7 +150,7 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev,
150 rcu_read_lock(); 150 rcu_read_lock();
151 151
152 if (mac_addr) { 152 if (mac_addr) {
153 sta = sta_info_get(sdata->local, mac_addr); 153 sta = sta_info_get(sdata, mac_addr);
154 if (!sta) { 154 if (!sta) {
155 ieee80211_key_free(key); 155 ieee80211_key_free(key);
156 err = -ENOENT; 156 err = -ENOENT;
@@ -181,7 +181,7 @@ static int ieee80211_del_key(struct wiphy *wiphy, struct net_device *dev,
181 if (mac_addr) { 181 if (mac_addr) {
182 ret = -ENOENT; 182 ret = -ENOENT;
183 183
184 sta = sta_info_get(sdata->local, mac_addr); 184 sta = sta_info_get(sdata, mac_addr);
185 if (!sta) 185 if (!sta)
186 goto out_unlock; 186 goto out_unlock;
187 187
@@ -228,7 +228,7 @@ static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev,
228 rcu_read_lock(); 228 rcu_read_lock();
229 229
230 if (mac_addr) { 230 if (mac_addr) {
231 sta = sta_info_get(sdata->local, mac_addr); 231 sta = sta_info_get(sdata, mac_addr);
232 if (!sta) 232 if (!sta)
233 goto out; 233 goto out;
234 234
@@ -415,15 +415,13 @@ static int ieee80211_dump_station(struct wiphy *wiphy, struct net_device *dev,
415static int ieee80211_get_station(struct wiphy *wiphy, struct net_device *dev, 415static int ieee80211_get_station(struct wiphy *wiphy, struct net_device *dev,
416 u8 *mac, struct station_info *sinfo) 416 u8 *mac, struct station_info *sinfo)
417{ 417{
418 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 418 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
419 struct sta_info *sta; 419 struct sta_info *sta;
420 int ret = -ENOENT; 420 int ret = -ENOENT;
421 421
422 rcu_read_lock(); 422 rcu_read_lock();
423 423
424 /* XXX: verify sta->dev == dev */ 424 sta = sta_info_get(sdata, mac);
425
426 sta = sta_info_get(local, mac);
427 if (sta) { 425 if (sta) {
428 ret = 0; 426 ret = 0;
429 sta_set_sinfo(sta, sinfo); 427 sta_set_sinfo(sta, sinfo);
@@ -732,7 +730,7 @@ static int ieee80211_add_station(struct wiphy *wiphy, struct net_device *dev,
732 } else 730 } else
733 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 731 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
734 732
735 if (compare_ether_addr(mac, dev->dev_addr) == 0) 733 if (compare_ether_addr(mac, sdata->vif.addr) == 0)
736 return -EINVAL; 734 return -EINVAL;
737 735
738 if (is_multicast_ether_addr(mac)) 736 if (is_multicast_ether_addr(mac))
@@ -779,8 +777,7 @@ static int ieee80211_del_station(struct wiphy *wiphy, struct net_device *dev,
779 if (mac) { 777 if (mac) {
780 rcu_read_lock(); 778 rcu_read_lock();
781 779
782 /* XXX: get sta belonging to dev */ 780 sta = sta_info_get(sdata, mac);
783 sta = sta_info_get(local, mac);
784 if (!sta) { 781 if (!sta) {
785 rcu_read_unlock(); 782 rcu_read_unlock();
786 return -ENOENT; 783 return -ENOENT;
@@ -801,14 +798,14 @@ static int ieee80211_change_station(struct wiphy *wiphy,
801 u8 *mac, 798 u8 *mac,
802 struct station_parameters *params) 799 struct station_parameters *params)
803{ 800{
801 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
804 struct ieee80211_local *local = wiphy_priv(wiphy); 802 struct ieee80211_local *local = wiphy_priv(wiphy);
805 struct sta_info *sta; 803 struct sta_info *sta;
806 struct ieee80211_sub_if_data *vlansdata; 804 struct ieee80211_sub_if_data *vlansdata;
807 805
808 rcu_read_lock(); 806 rcu_read_lock();
809 807
810 /* XXX: get sta belonging to dev */ 808 sta = sta_info_get(sdata, mac);
811 sta = sta_info_get(local, mac);
812 if (!sta) { 809 if (!sta) {
813 rcu_read_unlock(); 810 rcu_read_unlock();
814 return -ENOENT; 811 return -ENOENT;
@@ -847,7 +844,6 @@ static int ieee80211_change_station(struct wiphy *wiphy,
847static int ieee80211_add_mpath(struct wiphy *wiphy, struct net_device *dev, 844static int ieee80211_add_mpath(struct wiphy *wiphy, struct net_device *dev,
848 u8 *dst, u8 *next_hop) 845 u8 *dst, u8 *next_hop)
849{ 846{
850 struct ieee80211_local *local = wiphy_priv(wiphy);
851 struct ieee80211_sub_if_data *sdata; 847 struct ieee80211_sub_if_data *sdata;
852 struct mesh_path *mpath; 848 struct mesh_path *mpath;
853 struct sta_info *sta; 849 struct sta_info *sta;
@@ -856,7 +852,7 @@ static int ieee80211_add_mpath(struct wiphy *wiphy, struct net_device *dev,
856 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 852 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
857 853
858 rcu_read_lock(); 854 rcu_read_lock();
859 sta = sta_info_get(local, next_hop); 855 sta = sta_info_get(sdata, next_hop);
860 if (!sta) { 856 if (!sta) {
861 rcu_read_unlock(); 857 rcu_read_unlock();
862 return -ENOENT; 858 return -ENOENT;
@@ -895,7 +891,6 @@ static int ieee80211_change_mpath(struct wiphy *wiphy,
895 struct net_device *dev, 891 struct net_device *dev,
896 u8 *dst, u8 *next_hop) 892 u8 *dst, u8 *next_hop)
897{ 893{
898 struct ieee80211_local *local = wiphy_priv(wiphy);
899 struct ieee80211_sub_if_data *sdata; 894 struct ieee80211_sub_if_data *sdata;
900 struct mesh_path *mpath; 895 struct mesh_path *mpath;
901 struct sta_info *sta; 896 struct sta_info *sta;
@@ -904,7 +899,7 @@ static int ieee80211_change_mpath(struct wiphy *wiphy,
904 899
905 rcu_read_lock(); 900 rcu_read_lock();
906 901
907 sta = sta_info_get(local, next_hop); 902 sta = sta_info_get(sdata, next_hop);
908 if (!sta) { 903 if (!sta) {
909 rcu_read_unlock(); 904 rcu_read_unlock();
910 return -ENOENT; 905 return -ENOENT;
@@ -1324,6 +1319,50 @@ static int ieee80211_testmode_cmd(struct wiphy *wiphy, void *data, int len)
1324} 1319}
1325#endif 1320#endif
1326 1321
1322int __ieee80211_request_smps(struct ieee80211_sub_if_data *sdata,
1323 enum ieee80211_smps_mode smps_mode)
1324{
1325 const u8 *ap;
1326 enum ieee80211_smps_mode old_req;
1327 int err;
1328
1329 old_req = sdata->u.mgd.req_smps;
1330 sdata->u.mgd.req_smps = smps_mode;
1331
1332 if (old_req == smps_mode &&
1333 smps_mode != IEEE80211_SMPS_AUTOMATIC)
1334 return 0;
1335
1336 /*
1337 * If not associated, or current association is not an HT
1338 * association, there's no need to send an action frame.
1339 */
1340 if (!sdata->u.mgd.associated ||
1341 sdata->local->oper_channel_type == NL80211_CHAN_NO_HT) {
1342 mutex_lock(&sdata->local->iflist_mtx);
1343 ieee80211_recalc_smps(sdata->local, sdata);
1344 mutex_unlock(&sdata->local->iflist_mtx);
1345 return 0;
1346 }
1347
1348 ap = sdata->u.mgd.associated->cbss.bssid;
1349
1350 if (smps_mode == IEEE80211_SMPS_AUTOMATIC) {
1351 if (sdata->u.mgd.powersave)
1352 smps_mode = IEEE80211_SMPS_DYNAMIC;
1353 else
1354 smps_mode = IEEE80211_SMPS_OFF;
1355 }
1356
1357 /* send SM PS frame to AP */
1358 err = ieee80211_send_smps_action(sdata, smps_mode,
1359 ap, ap);
1360 if (err)
1361 sdata->u.mgd.req_smps = old_req;
1362
1363 return err;
1364}
1365
1327static int ieee80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev, 1366static int ieee80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
1328 bool enabled, int timeout) 1367 bool enabled, int timeout)
1329{ 1368{
@@ -1341,6 +1380,11 @@ static int ieee80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
1341 sdata->u.mgd.powersave = enabled; 1380 sdata->u.mgd.powersave = enabled;
1342 conf->dynamic_ps_timeout = timeout; 1381 conf->dynamic_ps_timeout = timeout;
1343 1382
1383 /* no change, but if automatic follow powersave */
1384 mutex_lock(&sdata->u.mgd.mtx);
1385 __ieee80211_request_smps(sdata, sdata->u.mgd.req_smps);
1386 mutex_unlock(&sdata->u.mgd.mtx);
1387
1344 if (local->hw.flags & IEEE80211_HW_SUPPORTS_DYNAMIC_PS) 1388 if (local->hw.flags & IEEE80211_HW_SUPPORTS_DYNAMIC_PS)
1345 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS); 1389 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS);
1346 1390
@@ -1356,15 +1400,25 @@ static int ieee80211_set_bitrate_mask(struct wiphy *wiphy,
1356{ 1400{
1357 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 1401 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1358 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 1402 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
1359 int i, err = -EINVAL; 1403 int i;
1360 u32 target_rate; 1404 u32 target_rate;
1361 struct ieee80211_supported_band *sband; 1405 struct ieee80211_supported_band *sband;
1362 1406
1407 /*
1408 * This _could_ be supported by providing a hook for
1409 * drivers for this function, but at this point it
1410 * doesn't seem worth bothering.
1411 */
1412 if (local->hw.flags & IEEE80211_HW_HAS_RATE_CONTROL)
1413 return -EOPNOTSUPP;
1414
1363 sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; 1415 sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
1364 1416
1365 /* target_rate = -1, rate->fixed = 0 means auto only, so use all rates 1417 /*
1418 * target_rate = -1, rate->fixed = 0 means auto only, so use all rates
1366 * target_rate = X, rate->fixed = 1 means only rate X 1419 * target_rate = X, rate->fixed = 1 means only rate X
1367 * target_rate = X, rate->fixed = 0 means all rates <= X */ 1420 * target_rate = X, rate->fixed = 0 means all rates <= X
1421 */
1368 sdata->max_ratectrl_rateidx = -1; 1422 sdata->max_ratectrl_rateidx = -1;
1369 sdata->force_unicast_rateidx = -1; 1423 sdata->force_unicast_rateidx = -1;
1370 1424
@@ -1375,20 +1429,18 @@ static int ieee80211_set_bitrate_mask(struct wiphy *wiphy,
1375 else 1429 else
1376 return 0; 1430 return 0;
1377 1431
1378 for (i=0; i< sband->n_bitrates; i++) { 1432 for (i = 0; i< sband->n_bitrates; i++) {
1379 struct ieee80211_rate *brate = &sband->bitrates[i]; 1433 if (target_rate != sband->bitrates[i].bitrate)
1380 int this_rate = brate->bitrate; 1434 continue;
1381 1435
1382 if (target_rate == this_rate) { 1436 /* requested bitrate found */
1383 sdata->max_ratectrl_rateidx = i; 1437 sdata->max_ratectrl_rateidx = i;
1384 if (mask->fixed) 1438 if (mask->fixed)
1385 sdata->force_unicast_rateidx = i; 1439 sdata->force_unicast_rateidx = i;
1386 err = 0; 1440 return 0;
1387 break;
1388 }
1389 } 1441 }
1390 1442
1391 return err; 1443 return -EINVAL;
1392} 1444}
1393 1445
1394struct cfg80211_ops mac80211_config_ops = { 1446struct cfg80211_ops mac80211_config_ops = {
diff --git a/net/mac80211/debugfs_key.c b/net/mac80211/debugfs_key.c
index e0f5224630da..d12e743cb4e1 100644
--- a/net/mac80211/debugfs_key.c
+++ b/net/mac80211/debugfs_key.c
@@ -56,7 +56,7 @@ KEY_CONF_FILE(keyidx, D);
56KEY_CONF_FILE(hw_key_idx, D); 56KEY_CONF_FILE(hw_key_idx, D);
57KEY_FILE(flags, X); 57KEY_FILE(flags, X);
58KEY_FILE(tx_rx_count, D); 58KEY_FILE(tx_rx_count, D);
59KEY_READ(ifindex, sdata->dev->ifindex, 20, "%d\n"); 59KEY_READ(ifindex, sdata->name, IFNAMSIZ + 2, "%s\n");
60KEY_OPS(ifindex); 60KEY_OPS(ifindex);
61 61
62static ssize_t key_algorithm_read(struct file *file, 62static ssize_t key_algorithm_read(struct file *file,
diff --git a/net/mac80211/debugfs_netdev.c b/net/mac80211/debugfs_netdev.c
index 472b2039906c..355983503885 100644
--- a/net/mac80211/debugfs_netdev.c
+++ b/net/mac80211/debugfs_netdev.c
@@ -41,6 +41,30 @@ static ssize_t ieee80211_if_read(
41 return ret; 41 return ret;
42} 42}
43 43
44static ssize_t ieee80211_if_write(
45 struct ieee80211_sub_if_data *sdata,
46 const char __user *userbuf,
47 size_t count, loff_t *ppos,
48 ssize_t (*write)(struct ieee80211_sub_if_data *, const char *, int))
49{
50 u8 *buf;
51 ssize_t ret = -ENODEV;
52
53 buf = kzalloc(count, GFP_KERNEL);
54 if (!buf)
55 return -ENOMEM;
56
57 if (copy_from_user(buf, userbuf, count))
58 return -EFAULT;
59
60 rtnl_lock();
61 if (sdata->dev->reg_state == NETREG_REGISTERED)
62 ret = (*write)(sdata, buf, count);
63 rtnl_unlock();
64
65 return ret;
66}
67
44#define IEEE80211_IF_FMT(name, field, format_string) \ 68#define IEEE80211_IF_FMT(name, field, format_string) \
45static ssize_t ieee80211_if_fmt_##name( \ 69static ssize_t ieee80211_if_fmt_##name( \
46 const struct ieee80211_sub_if_data *sdata, char *buf, \ 70 const struct ieee80211_sub_if_data *sdata, char *buf, \
@@ -71,7 +95,7 @@ static ssize_t ieee80211_if_fmt_##name( \
71 return scnprintf(buf, buflen, "%pM\n", sdata->field); \ 95 return scnprintf(buf, buflen, "%pM\n", sdata->field); \
72} 96}
73 97
74#define __IEEE80211_IF_FILE(name) \ 98#define __IEEE80211_IF_FILE(name, _write) \
75static ssize_t ieee80211_if_read_##name(struct file *file, \ 99static ssize_t ieee80211_if_read_##name(struct file *file, \
76 char __user *userbuf, \ 100 char __user *userbuf, \
77 size_t count, loff_t *ppos) \ 101 size_t count, loff_t *ppos) \
@@ -82,12 +106,24 @@ static ssize_t ieee80211_if_read_##name(struct file *file, \
82} \ 106} \
83static const struct file_operations name##_ops = { \ 107static const struct file_operations name##_ops = { \
84 .read = ieee80211_if_read_##name, \ 108 .read = ieee80211_if_read_##name, \
109 .write = (_write), \
85 .open = mac80211_open_file_generic, \ 110 .open = mac80211_open_file_generic, \
86} 111}
87 112
113#define __IEEE80211_IF_FILE_W(name) \
114static ssize_t ieee80211_if_write_##name(struct file *file, \
115 const char __user *userbuf, \
116 size_t count, loff_t *ppos) \
117{ \
118 return ieee80211_if_write(file->private_data, userbuf, count, \
119 ppos, ieee80211_if_parse_##name); \
120} \
121__IEEE80211_IF_FILE(name, ieee80211_if_write_##name)
122
123
88#define IEEE80211_IF_FILE(name, field, format) \ 124#define IEEE80211_IF_FILE(name, field, format) \
89 IEEE80211_IF_FMT_##format(name, field) \ 125 IEEE80211_IF_FMT_##format(name, field) \
90 __IEEE80211_IF_FILE(name) 126 __IEEE80211_IF_FILE(name, NULL)
91 127
92/* common attributes */ 128/* common attributes */
93IEEE80211_IF_FILE(drop_unencrypted, drop_unencrypted, DEC); 129IEEE80211_IF_FILE(drop_unencrypted, drop_unencrypted, DEC);
@@ -99,6 +135,70 @@ IEEE80211_IF_FILE(bssid, u.mgd.bssid, MAC);
99IEEE80211_IF_FILE(aid, u.mgd.aid, DEC); 135IEEE80211_IF_FILE(aid, u.mgd.aid, DEC);
100IEEE80211_IF_FILE(capab, u.mgd.capab, HEX); 136IEEE80211_IF_FILE(capab, u.mgd.capab, HEX);
101 137
138static int ieee80211_set_smps(struct ieee80211_sub_if_data *sdata,
139 enum ieee80211_smps_mode smps_mode)
140{
141 struct ieee80211_local *local = sdata->local;
142 int err;
143
144 if (!(local->hw.flags & IEEE80211_HW_SUPPORTS_STATIC_SMPS) &&
145 smps_mode == IEEE80211_SMPS_STATIC)
146 return -EINVAL;
147
148 /* auto should be dynamic if in PS mode */
149 if (!(local->hw.flags & IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS) &&
150 (smps_mode == IEEE80211_SMPS_DYNAMIC ||
151 smps_mode == IEEE80211_SMPS_AUTOMATIC))
152 return -EINVAL;
153
154 /* supported only on managed interfaces for now */
155 if (sdata->vif.type != NL80211_IFTYPE_STATION)
156 return -EOPNOTSUPP;
157
158 mutex_lock(&local->iflist_mtx);
159 err = __ieee80211_request_smps(sdata, smps_mode);
160 mutex_unlock(&local->iflist_mtx);
161
162 return err;
163}
164
165static const char *smps_modes[IEEE80211_SMPS_NUM_MODES] = {
166 [IEEE80211_SMPS_AUTOMATIC] = "auto",
167 [IEEE80211_SMPS_OFF] = "off",
168 [IEEE80211_SMPS_STATIC] = "static",
169 [IEEE80211_SMPS_DYNAMIC] = "dynamic",
170};
171
172static ssize_t ieee80211_if_fmt_smps(const struct ieee80211_sub_if_data *sdata,
173 char *buf, int buflen)
174{
175 if (sdata->vif.type != NL80211_IFTYPE_STATION)
176 return -EOPNOTSUPP;
177
178 return snprintf(buf, buflen, "request: %s\nused: %s\n",
179 smps_modes[sdata->u.mgd.req_smps],
180 smps_modes[sdata->u.mgd.ap_smps]);
181}
182
183static ssize_t ieee80211_if_parse_smps(struct ieee80211_sub_if_data *sdata,
184 const char *buf, int buflen)
185{
186 enum ieee80211_smps_mode mode;
187
188 for (mode = 0; mode < IEEE80211_SMPS_NUM_MODES; mode++) {
189 if (strncmp(buf, smps_modes[mode], buflen) == 0) {
190 int err = ieee80211_set_smps(sdata, mode);
191 if (!err)
192 return buflen;
193 return err;
194 }
195 }
196
197 return -EINVAL;
198}
199
200__IEEE80211_IF_FILE_W(smps);
201
102/* AP attributes */ 202/* AP attributes */
103IEEE80211_IF_FILE(num_sta_ps, u.ap.num_sta_ps, ATOMIC); 203IEEE80211_IF_FILE(num_sta_ps, u.ap.num_sta_ps, ATOMIC);
104IEEE80211_IF_FILE(dtim_count, u.ap.dtim_count, DEC); 204IEEE80211_IF_FILE(dtim_count, u.ap.dtim_count, DEC);
@@ -109,7 +209,7 @@ static ssize_t ieee80211_if_fmt_num_buffered_multicast(
109 return scnprintf(buf, buflen, "%u\n", 209 return scnprintf(buf, buflen, "%u\n",
110 skb_queue_len(&sdata->u.ap.ps_bc_buf)); 210 skb_queue_len(&sdata->u.ap.ps_bc_buf));
111} 211}
112__IEEE80211_IF_FILE(num_buffered_multicast); 212__IEEE80211_IF_FILE(num_buffered_multicast, NULL);
113 213
114/* WDS attributes */ 214/* WDS attributes */
115IEEE80211_IF_FILE(peer, u.wds.remote_addr, MAC); 215IEEE80211_IF_FILE(peer, u.wds.remote_addr, MAC);
@@ -158,6 +258,10 @@ IEEE80211_IF_FILE(dot11MeshHWMPRootMode,
158 debugfs_create_file(#name, 0400, sdata->debugfs.dir, \ 258 debugfs_create_file(#name, 0400, sdata->debugfs.dir, \
159 sdata, &name##_ops); 259 sdata, &name##_ops);
160 260
261#define DEBUGFS_ADD_MODE(name, mode) \
262 debugfs_create_file(#name, mode, sdata->debugfs.dir, \
263 sdata, &name##_ops);
264
161static void add_sta_files(struct ieee80211_sub_if_data *sdata) 265static void add_sta_files(struct ieee80211_sub_if_data *sdata)
162{ 266{
163 DEBUGFS_ADD(drop_unencrypted, sta); 267 DEBUGFS_ADD(drop_unencrypted, sta);
@@ -167,6 +271,7 @@ static void add_sta_files(struct ieee80211_sub_if_data *sdata)
167 DEBUGFS_ADD(bssid, sta); 271 DEBUGFS_ADD(bssid, sta);
168 DEBUGFS_ADD(aid, sta); 272 DEBUGFS_ADD(aid, sta);
169 DEBUGFS_ADD(capab, sta); 273 DEBUGFS_ADD(capab, sta);
274 DEBUGFS_ADD_MODE(smps, 0600);
170} 275}
171 276
172static void add_ap_files(struct ieee80211_sub_if_data *sdata) 277static void add_ap_files(struct ieee80211_sub_if_data *sdata)
@@ -280,16 +385,11 @@ static void add_files(struct ieee80211_sub_if_data *sdata)
280 } 385 }
281} 386}
282 387
283static int notif_registered;
284
285void ieee80211_debugfs_add_netdev(struct ieee80211_sub_if_data *sdata) 388void ieee80211_debugfs_add_netdev(struct ieee80211_sub_if_data *sdata)
286{ 389{
287 char buf[10+IFNAMSIZ]; 390 char buf[10+IFNAMSIZ];
288 391
289 if (!notif_registered) 392 sprintf(buf, "netdev:%s", sdata->name);
290 return;
291
292 sprintf(buf, "netdev:%s", sdata->dev->name);
293 sdata->debugfs.dir = debugfs_create_dir(buf, 393 sdata->debugfs.dir = debugfs_create_dir(buf,
294 sdata->local->hw.wiphy->debugfsdir); 394 sdata->local->hw.wiphy->debugfsdir);
295 add_files(sdata); 395 add_files(sdata);
@@ -304,58 +404,18 @@ void ieee80211_debugfs_remove_netdev(struct ieee80211_sub_if_data *sdata)
304 sdata->debugfs.dir = NULL; 404 sdata->debugfs.dir = NULL;
305} 405}
306 406
307static int netdev_notify(struct notifier_block *nb, 407void ieee80211_debugfs_rename_netdev(struct ieee80211_sub_if_data *sdata)
308 unsigned long state,
309 void *ndev)
310{ 408{
311 struct net_device *dev = ndev;
312 struct dentry *dir; 409 struct dentry *dir;
313 struct ieee80211_sub_if_data *sdata; 410 char buf[10 + IFNAMSIZ];
314 char buf[10+IFNAMSIZ];
315
316 if (state != NETDEV_CHANGENAME)
317 return 0;
318
319 if (!dev->ieee80211_ptr || !dev->ieee80211_ptr->wiphy)
320 return 0;
321
322 if (dev->ieee80211_ptr->wiphy->privid != mac80211_wiphy_privid)
323 return 0;
324
325 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
326 411
327 dir = sdata->debugfs.dir; 412 dir = sdata->debugfs.dir;
328 413
329 if (!dir) 414 if (!dir)
330 return 0; 415 return;
331 416
332 sprintf(buf, "netdev:%s", dev->name); 417 sprintf(buf, "netdev:%s", sdata->name);
333 if (!debugfs_rename(dir->d_parent, dir, dir->d_parent, buf)) 418 if (!debugfs_rename(dir->d_parent, dir, dir->d_parent, buf))
334 printk(KERN_ERR "mac80211: debugfs: failed to rename debugfs " 419 printk(KERN_ERR "mac80211: debugfs: failed to rename debugfs "
335 "dir to %s\n", buf); 420 "dir to %s\n", buf);
336
337 return 0;
338}
339
340static struct notifier_block mac80211_debugfs_netdev_notifier = {
341 .notifier_call = netdev_notify,
342};
343
344void ieee80211_debugfs_netdev_init(void)
345{
346 int err;
347
348 err = register_netdevice_notifier(&mac80211_debugfs_netdev_notifier);
349 if (err) {
350 printk(KERN_ERR
351 "mac80211: failed to install netdev notifier,"
352 " disabling per-netdev debugfs!\n");
353 } else
354 notif_registered = 1;
355}
356
357void ieee80211_debugfs_netdev_exit(void)
358{
359 unregister_netdevice_notifier(&mac80211_debugfs_netdev_notifier);
360 notif_registered = 0;
361} 421}
diff --git a/net/mac80211/debugfs_netdev.h b/net/mac80211/debugfs_netdev.h
index 7af731f0b731..79025e79f4d6 100644
--- a/net/mac80211/debugfs_netdev.h
+++ b/net/mac80211/debugfs_netdev.h
@@ -6,8 +6,7 @@
6#ifdef CONFIG_MAC80211_DEBUGFS 6#ifdef CONFIG_MAC80211_DEBUGFS
7void ieee80211_debugfs_add_netdev(struct ieee80211_sub_if_data *sdata); 7void ieee80211_debugfs_add_netdev(struct ieee80211_sub_if_data *sdata);
8void ieee80211_debugfs_remove_netdev(struct ieee80211_sub_if_data *sdata); 8void ieee80211_debugfs_remove_netdev(struct ieee80211_sub_if_data *sdata);
9void ieee80211_debugfs_netdev_init(void); 9void ieee80211_debugfs_rename_netdev(struct ieee80211_sub_if_data *sdata);
10void ieee80211_debugfs_netdev_exit(void);
11#else 10#else
12static inline void ieee80211_debugfs_add_netdev( 11static inline void ieee80211_debugfs_add_netdev(
13 struct ieee80211_sub_if_data *sdata) 12 struct ieee80211_sub_if_data *sdata)
@@ -15,10 +14,8 @@ static inline void ieee80211_debugfs_add_netdev(
15static inline void ieee80211_debugfs_remove_netdev( 14static inline void ieee80211_debugfs_remove_netdev(
16 struct ieee80211_sub_if_data *sdata) 15 struct ieee80211_sub_if_data *sdata)
17{} 16{}
18static inline void ieee80211_debugfs_netdev_init(void) 17static inline void ieee80211_debugfs_rename_netdev(
19{} 18 struct ieee80211_sub_if_data *sdata)
20
21static inline void ieee80211_debugfs_netdev_exit(void)
22{} 19{}
23#endif 20#endif
24 21
diff --git a/net/mac80211/debugfs_sta.c b/net/mac80211/debugfs_sta.c
index 3f41608c8081..0d4a759ba72c 100644
--- a/net/mac80211/debugfs_sta.c
+++ b/net/mac80211/debugfs_sta.c
@@ -44,7 +44,7 @@ static const struct file_operations sta_ ##name## _ops = { \
44 STA_OPS(name) 44 STA_OPS(name)
45 45
46STA_FILE(aid, sta.aid, D); 46STA_FILE(aid, sta.aid, D);
47STA_FILE(dev, sdata->dev->name, S); 47STA_FILE(dev, sdata->name, S);
48STA_FILE(rx_packets, rx_packets, LU); 48STA_FILE(rx_packets, rx_packets, LU);
49STA_FILE(tx_packets, tx_packets, LU); 49STA_FILE(tx_packets, tx_packets, LU);
50STA_FILE(rx_bytes, rx_bytes, LU); 50STA_FILE(rx_bytes, rx_bytes, LU);
@@ -160,7 +160,12 @@ STA_OPS(agg_status);
160static ssize_t sta_ht_capa_read(struct file *file, char __user *userbuf, 160static ssize_t sta_ht_capa_read(struct file *file, char __user *userbuf,
161 size_t count, loff_t *ppos) 161 size_t count, loff_t *ppos)
162{ 162{
163 char buf[200], *p = buf; 163#define PRINT_HT_CAP(_cond, _str) \
164 do { \
165 if (_cond) \
166 p += scnprintf(p, sizeof(buf)+buf-p, "\t" _str "\n"); \
167 } while (0)
168 char buf[1024], *p = buf;
164 int i; 169 int i;
165 struct sta_info *sta = file->private_data; 170 struct sta_info *sta = file->private_data;
166 struct ieee80211_sta_ht_cap *htc = &sta->sta.ht_cap; 171 struct ieee80211_sta_ht_cap *htc = &sta->sta.ht_cap;
@@ -168,15 +173,64 @@ static ssize_t sta_ht_capa_read(struct file *file, char __user *userbuf,
168 p += scnprintf(p, sizeof(buf) + buf - p, "ht %ssupported\n", 173 p += scnprintf(p, sizeof(buf) + buf - p, "ht %ssupported\n",
169 htc->ht_supported ? "" : "not "); 174 htc->ht_supported ? "" : "not ");
170 if (htc->ht_supported) { 175 if (htc->ht_supported) {
171 p += scnprintf(p, sizeof(buf)+buf-p, "cap: %#.2x\n", htc->cap); 176 p += scnprintf(p, sizeof(buf)+buf-p, "cap: %#.4x\n", htc->cap);
177
178 PRINT_HT_CAP((htc->cap & BIT(0)), "RX LDCP");
179 PRINT_HT_CAP((htc->cap & BIT(1)), "HT20/HT40");
180 PRINT_HT_CAP(!(htc->cap & BIT(1)), "HT20");
181
182 PRINT_HT_CAP(((htc->cap >> 2) & 0x3) == 0, "Static SM Power Save");
183 PRINT_HT_CAP(((htc->cap >> 2) & 0x3) == 1, "Dynamic SM Power Save");
184 PRINT_HT_CAP(((htc->cap >> 2) & 0x3) == 3, "SM Power Save disabled");
185
186 PRINT_HT_CAP((htc->cap & BIT(4)), "RX Greenfield");
187 PRINT_HT_CAP((htc->cap & BIT(5)), "RX HT20 SGI");
188 PRINT_HT_CAP((htc->cap & BIT(6)), "RX HT40 SGI");
189 PRINT_HT_CAP((htc->cap & BIT(7)), "TX STBC");
190
191 PRINT_HT_CAP(((htc->cap >> 8) & 0x3) == 0, "No RX STBC");
192 PRINT_HT_CAP(((htc->cap >> 8) & 0x3) == 1, "RX STBC 1-stream");
193 PRINT_HT_CAP(((htc->cap >> 8) & 0x3) == 2, "RX STBC 2-streams");
194 PRINT_HT_CAP(((htc->cap >> 8) & 0x3) == 3, "RX STBC 3-streams");
195
196 PRINT_HT_CAP((htc->cap & BIT(10)), "HT Delayed Block Ack");
197
198 PRINT_HT_CAP((htc->cap & BIT(11)), "Max AMSDU length: "
199 "3839 bytes");
200 PRINT_HT_CAP(!(htc->cap & BIT(11)), "Max AMSDU length: "
201 "7935 bytes");
202
203 /*
204 * For beacons and probe response this would mean the BSS
205 * does or does not allow the usage of DSSS/CCK HT40.
206 * Otherwise it means the STA does or does not use
207 * DSSS/CCK HT40.
208 */
209 PRINT_HT_CAP((htc->cap & BIT(12)), "DSSS/CCK HT40");
210 PRINT_HT_CAP(!(htc->cap & BIT(12)), "No DSSS/CCK HT40");
211
212 /* BIT(13) is reserved */
213
214 PRINT_HT_CAP((htc->cap & BIT(14)), "40 MHz Intolerant");
215
216 PRINT_HT_CAP((htc->cap & BIT(15)), "L-SIG TXOP protection");
217
172 p += scnprintf(p, sizeof(buf)+buf-p, "ampdu factor/density: %d/%d\n", 218 p += scnprintf(p, sizeof(buf)+buf-p, "ampdu factor/density: %d/%d\n",
173 htc->ampdu_factor, htc->ampdu_density); 219 htc->ampdu_factor, htc->ampdu_density);
174 p += scnprintf(p, sizeof(buf)+buf-p, "MCS mask:"); 220 p += scnprintf(p, sizeof(buf)+buf-p, "MCS mask:");
221
175 for (i = 0; i < IEEE80211_HT_MCS_MASK_LEN; i++) 222 for (i = 0; i < IEEE80211_HT_MCS_MASK_LEN; i++)
176 p += scnprintf(p, sizeof(buf)+buf-p, " %.2x", 223 p += scnprintf(p, sizeof(buf)+buf-p, " %.2x",
177 htc->mcs.rx_mask[i]); 224 htc->mcs.rx_mask[i]);
178 p += scnprintf(p, sizeof(buf)+buf-p, "\nMCS rx highest: %d\n", 225 p += scnprintf(p, sizeof(buf)+buf-p, "\n");
179 le16_to_cpu(htc->mcs.rx_highest)); 226
227 /* If not set this is meaningless */
228 if (le16_to_cpu(htc->mcs.rx_highest)) {
229 p += scnprintf(p, sizeof(buf)+buf-p,
230 "MCS rx highest: %d Mbps\n",
231 le16_to_cpu(htc->mcs.rx_highest));
232 }
233
180 p += scnprintf(p, sizeof(buf)+buf-p, "MCS tx params: %x\n", 234 p += scnprintf(p, sizeof(buf)+buf-p, "MCS tx params: %x\n",
181 htc->mcs.tx_params); 235 htc->mcs.tx_params);
182 } 236 }
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h
index 921dd9c9ff62..727e4cf7b8a6 100644
--- a/net/mac80211/driver-ops.h
+++ b/net/mac80211/driver-ops.h
@@ -39,7 +39,7 @@ static inline int drv_add_interface(struct ieee80211_local *local,
39 struct ieee80211_if_init_conf *conf) 39 struct ieee80211_if_init_conf *conf)
40{ 40{
41 int ret = local->ops->add_interface(&local->hw, conf); 41 int ret = local->ops->add_interface(&local->hw, conf);
42 trace_drv_add_interface(local, conf->mac_addr, conf->vif, ret); 42 trace_drv_add_interface(local, vif_to_sdata(conf->vif), ret);
43 return ret; 43 return ret;
44} 44}
45 45
@@ -47,7 +47,7 @@ static inline void drv_remove_interface(struct ieee80211_local *local,
47 struct ieee80211_if_init_conf *conf) 47 struct ieee80211_if_init_conf *conf)
48{ 48{
49 local->ops->remove_interface(&local->hw, conf); 49 local->ops->remove_interface(&local->hw, conf);
50 trace_drv_remove_interface(local, conf->mac_addr, conf->vif); 50 trace_drv_remove_interface(local, vif_to_sdata(conf->vif));
51} 51}
52 52
53static inline int drv_config(struct ieee80211_local *local, u32 changed) 53static inline int drv_config(struct ieee80211_local *local, u32 changed)
@@ -58,13 +58,13 @@ static inline int drv_config(struct ieee80211_local *local, u32 changed)
58} 58}
59 59
60static inline void drv_bss_info_changed(struct ieee80211_local *local, 60static inline void drv_bss_info_changed(struct ieee80211_local *local,
61 struct ieee80211_vif *vif, 61 struct ieee80211_sub_if_data *sdata,
62 struct ieee80211_bss_conf *info, 62 struct ieee80211_bss_conf *info,
63 u32 changed) 63 u32 changed)
64{ 64{
65 if (local->ops->bss_info_changed) 65 if (local->ops->bss_info_changed)
66 local->ops->bss_info_changed(&local->hw, vif, info, changed); 66 local->ops->bss_info_changed(&local->hw, &sdata->vif, info, changed);
67 trace_drv_bss_info_changed(local, vif, info, changed); 67 trace_drv_bss_info_changed(local, sdata, info, changed);
68} 68}
69 69
70static inline u64 drv_prepare_multicast(struct ieee80211_local *local, 70static inline u64 drv_prepare_multicast(struct ieee80211_local *local,
@@ -106,12 +106,13 @@ static inline int drv_set_tim(struct ieee80211_local *local,
106} 106}
107 107
108static inline int drv_set_key(struct ieee80211_local *local, 108static inline int drv_set_key(struct ieee80211_local *local,
109 enum set_key_cmd cmd, struct ieee80211_vif *vif, 109 enum set_key_cmd cmd,
110 struct ieee80211_sub_if_data *sdata,
110 struct ieee80211_sta *sta, 111 struct ieee80211_sta *sta,
111 struct ieee80211_key_conf *key) 112 struct ieee80211_key_conf *key)
112{ 113{
113 int ret = local->ops->set_key(&local->hw, cmd, vif, sta, key); 114 int ret = local->ops->set_key(&local->hw, cmd, &sdata->vif, sta, key);
114 trace_drv_set_key(local, cmd, vif, sta, key, ret); 115 trace_drv_set_key(local, cmd, sdata, sta, key, ret);
115 return ret; 116 return ret;
116} 117}
117 118
@@ -179,13 +180,13 @@ static inline int drv_set_rts_threshold(struct ieee80211_local *local,
179} 180}
180 181
181static inline void drv_sta_notify(struct ieee80211_local *local, 182static inline void drv_sta_notify(struct ieee80211_local *local,
182 struct ieee80211_vif *vif, 183 struct ieee80211_sub_if_data *sdata,
183 enum sta_notify_cmd cmd, 184 enum sta_notify_cmd cmd,
184 struct ieee80211_sta *sta) 185 struct ieee80211_sta *sta)
185{ 186{
186 if (local->ops->sta_notify) 187 if (local->ops->sta_notify)
187 local->ops->sta_notify(&local->hw, vif, cmd, sta); 188 local->ops->sta_notify(&local->hw, &sdata->vif, cmd, sta);
188 trace_drv_sta_notify(local, vif, cmd, sta); 189 trace_drv_sta_notify(local, sdata, cmd, sta);
189} 190}
190 191
191static inline int drv_conf_tx(struct ieee80211_local *local, u16 queue, 192static inline int drv_conf_tx(struct ieee80211_local *local, u16 queue,
@@ -239,16 +240,16 @@ static inline int drv_tx_last_beacon(struct ieee80211_local *local)
239} 240}
240 241
241static inline int drv_ampdu_action(struct ieee80211_local *local, 242static inline int drv_ampdu_action(struct ieee80211_local *local,
242 struct ieee80211_vif *vif, 243 struct ieee80211_sub_if_data *sdata,
243 enum ieee80211_ampdu_mlme_action action, 244 enum ieee80211_ampdu_mlme_action action,
244 struct ieee80211_sta *sta, u16 tid, 245 struct ieee80211_sta *sta, u16 tid,
245 u16 *ssn) 246 u16 *ssn)
246{ 247{
247 int ret = -EOPNOTSUPP; 248 int ret = -EOPNOTSUPP;
248 if (local->ops->ampdu_action) 249 if (local->ops->ampdu_action)
249 ret = local->ops->ampdu_action(&local->hw, vif, action, 250 ret = local->ops->ampdu_action(&local->hw, &sdata->vif, action,
250 sta, tid, ssn); 251 sta, tid, ssn);
251 trace_drv_ampdu_action(local, vif, action, sta, tid, ssn, ret); 252 trace_drv_ampdu_action(local, sdata, action, sta, tid, ssn, ret);
252 return ret; 253 return ret;
253} 254}
254 255
diff --git a/net/mac80211/driver-trace.h b/net/mac80211/driver-trace.h
index ee94ea0c67e9..7a849b920165 100644
--- a/net/mac80211/driver-trace.h
+++ b/net/mac80211/driver-trace.h
@@ -25,10 +25,12 @@ static inline void trace_ ## name(proto) {}
25#define STA_PR_FMT " sta:%pM" 25#define STA_PR_FMT " sta:%pM"
26#define STA_PR_ARG __entry->sta_addr 26#define STA_PR_ARG __entry->sta_addr
27 27
28#define VIF_ENTRY __field(enum nl80211_iftype, vif_type) __field(void *, vif) 28#define VIF_ENTRY __field(enum nl80211_iftype, vif_type) __field(void *, sdata) \
29#define VIF_ASSIGN __entry->vif_type = vif ? vif->type : 0; __entry->vif = vif 29 __string(vif_name, sdata->dev ? sdata->dev->name : "<nodev>")
30#define VIF_PR_FMT " vif:%p(%d)" 30#define VIF_ASSIGN __entry->vif_type = sdata->vif.type; __entry->sdata = sdata; \
31#define VIF_PR_ARG __entry->vif, __entry->vif_type 31 __assign_str(vif_name, sdata->dev ? sdata->dev->name : "<nodev>")
32#define VIF_PR_FMT " vif:%s(%d)"
33#define VIF_PR_ARG __get_str(vif_name), __entry->vif_type
32 34
33TRACE_EVENT(drv_start, 35TRACE_EVENT(drv_start,
34 TP_PROTO(struct ieee80211_local *local, int ret), 36 TP_PROTO(struct ieee80211_local *local, int ret),
@@ -70,11 +72,10 @@ TRACE_EVENT(drv_stop,
70 72
71TRACE_EVENT(drv_add_interface, 73TRACE_EVENT(drv_add_interface,
72 TP_PROTO(struct ieee80211_local *local, 74 TP_PROTO(struct ieee80211_local *local,
73 const u8 *addr, 75 struct ieee80211_sub_if_data *sdata,
74 struct ieee80211_vif *vif,
75 int ret), 76 int ret),
76 77
77 TP_ARGS(local, addr, vif, ret), 78 TP_ARGS(local, sdata, ret),
78 79
79 TP_STRUCT__entry( 80 TP_STRUCT__entry(
80 LOCAL_ENTRY 81 LOCAL_ENTRY
@@ -86,7 +87,7 @@ TRACE_EVENT(drv_add_interface,
86 TP_fast_assign( 87 TP_fast_assign(
87 LOCAL_ASSIGN; 88 LOCAL_ASSIGN;
88 VIF_ASSIGN; 89 VIF_ASSIGN;
89 memcpy(__entry->addr, addr, 6); 90 memcpy(__entry->addr, sdata->vif.addr, 6);
90 __entry->ret = ret; 91 __entry->ret = ret;
91 ), 92 ),
92 93
@@ -97,10 +98,9 @@ TRACE_EVENT(drv_add_interface,
97); 98);
98 99
99TRACE_EVENT(drv_remove_interface, 100TRACE_EVENT(drv_remove_interface,
100 TP_PROTO(struct ieee80211_local *local, 101 TP_PROTO(struct ieee80211_local *local, struct ieee80211_sub_if_data *sdata),
101 const u8 *addr, struct ieee80211_vif *vif),
102 102
103 TP_ARGS(local, addr, vif), 103 TP_ARGS(local, sdata),
104 104
105 TP_STRUCT__entry( 105 TP_STRUCT__entry(
106 LOCAL_ENTRY 106 LOCAL_ENTRY
@@ -111,7 +111,7 @@ TRACE_EVENT(drv_remove_interface,
111 TP_fast_assign( 111 TP_fast_assign(
112 LOCAL_ASSIGN; 112 LOCAL_ASSIGN;
113 VIF_ASSIGN; 113 VIF_ASSIGN;
114 memcpy(__entry->addr, addr, 6); 114 memcpy(__entry->addr, sdata->vif.addr, 6);
115 ), 115 ),
116 116
117 TP_printk( 117 TP_printk(
@@ -140,6 +140,7 @@ TRACE_EVENT(drv_config,
140 __field(u8, short_frame_max_tx_count) 140 __field(u8, short_frame_max_tx_count)
141 __field(int, center_freq) 141 __field(int, center_freq)
142 __field(int, channel_type) 142 __field(int, channel_type)
143 __field(int, smps)
143 ), 144 ),
144 145
145 TP_fast_assign( 146 TP_fast_assign(
@@ -155,6 +156,7 @@ TRACE_EVENT(drv_config,
155 __entry->short_frame_max_tx_count = local->hw.conf.short_frame_max_tx_count; 156 __entry->short_frame_max_tx_count = local->hw.conf.short_frame_max_tx_count;
156 __entry->center_freq = local->hw.conf.channel->center_freq; 157 __entry->center_freq = local->hw.conf.channel->center_freq;
157 __entry->channel_type = local->hw.conf.channel_type; 158 __entry->channel_type = local->hw.conf.channel_type;
159 __entry->smps = local->hw.conf.smps_mode;
158 ), 160 ),
159 161
160 TP_printk( 162 TP_printk(
@@ -165,11 +167,11 @@ TRACE_EVENT(drv_config,
165 167
166TRACE_EVENT(drv_bss_info_changed, 168TRACE_EVENT(drv_bss_info_changed,
167 TP_PROTO(struct ieee80211_local *local, 169 TP_PROTO(struct ieee80211_local *local,
168 struct ieee80211_vif *vif, 170 struct ieee80211_sub_if_data *sdata,
169 struct ieee80211_bss_conf *info, 171 struct ieee80211_bss_conf *info,
170 u32 changed), 172 u32 changed),
171 173
172 TP_ARGS(local, vif, info, changed), 174 TP_ARGS(local, sdata, info, changed),
173 175
174 TP_STRUCT__entry( 176 TP_STRUCT__entry(
175 LOCAL_ENTRY 177 LOCAL_ENTRY
@@ -293,11 +295,11 @@ TRACE_EVENT(drv_set_tim,
293 295
294TRACE_EVENT(drv_set_key, 296TRACE_EVENT(drv_set_key,
295 TP_PROTO(struct ieee80211_local *local, 297 TP_PROTO(struct ieee80211_local *local,
296 enum set_key_cmd cmd, struct ieee80211_vif *vif, 298 enum set_key_cmd cmd, struct ieee80211_sub_if_data *sdata,
297 struct ieee80211_sta *sta, 299 struct ieee80211_sta *sta,
298 struct ieee80211_key_conf *key, int ret), 300 struct ieee80211_key_conf *key, int ret),
299 301
300 TP_ARGS(local, cmd, vif, sta, key, ret), 302 TP_ARGS(local, cmd, sdata, sta, key, ret),
301 303
302 TP_STRUCT__entry( 304 TP_STRUCT__entry(
303 LOCAL_ENTRY 305 LOCAL_ENTRY
@@ -491,11 +493,11 @@ TRACE_EVENT(drv_set_rts_threshold,
491 493
492TRACE_EVENT(drv_sta_notify, 494TRACE_EVENT(drv_sta_notify,
493 TP_PROTO(struct ieee80211_local *local, 495 TP_PROTO(struct ieee80211_local *local,
494 struct ieee80211_vif *vif, 496 struct ieee80211_sub_if_data *sdata,
495 enum sta_notify_cmd cmd, 497 enum sta_notify_cmd cmd,
496 struct ieee80211_sta *sta), 498 struct ieee80211_sta *sta),
497 499
498 TP_ARGS(local, vif, cmd, sta), 500 TP_ARGS(local, sdata, cmd, sta),
499 501
500 TP_STRUCT__entry( 502 TP_STRUCT__entry(
501 LOCAL_ENTRY 503 LOCAL_ENTRY
@@ -656,12 +658,12 @@ TRACE_EVENT(drv_tx_last_beacon,
656 658
657TRACE_EVENT(drv_ampdu_action, 659TRACE_EVENT(drv_ampdu_action,
658 TP_PROTO(struct ieee80211_local *local, 660 TP_PROTO(struct ieee80211_local *local,
659 struct ieee80211_vif *vif, 661 struct ieee80211_sub_if_data *sdata,
660 enum ieee80211_ampdu_mlme_action action, 662 enum ieee80211_ampdu_mlme_action action,
661 struct ieee80211_sta *sta, u16 tid, 663 struct ieee80211_sta *sta, u16 tid,
662 u16 *ssn, int ret), 664 u16 *ssn, int ret),
663 665
664 TP_ARGS(local, vif, action, sta, tid, ssn, ret), 666 TP_ARGS(local, sdata, action, sta, tid, ssn, ret),
665 667
666 TP_STRUCT__entry( 668 TP_STRUCT__entry(
667 LOCAL_ENTRY 669 LOCAL_ENTRY
diff --git a/net/mac80211/ht.c b/net/mac80211/ht.c
index d7dcee680728..bb677a73b7c9 100644
--- a/net/mac80211/ht.c
+++ b/net/mac80211/ht.c
@@ -125,7 +125,7 @@ void ieee80211_send_delba(struct ieee80211_sub_if_data *sdata,
125 125
126 if (!skb) { 126 if (!skb) {
127 printk(KERN_ERR "%s: failed to allocate buffer " 127 printk(KERN_ERR "%s: failed to allocate buffer "
128 "for delba frame\n", sdata->dev->name); 128 "for delba frame\n", sdata->name);
129 return; 129 return;
130 } 130 }
131 131
@@ -133,10 +133,10 @@ void ieee80211_send_delba(struct ieee80211_sub_if_data *sdata,
133 mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24); 133 mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24);
134 memset(mgmt, 0, 24); 134 memset(mgmt, 0, 24);
135 memcpy(mgmt->da, da, ETH_ALEN); 135 memcpy(mgmt->da, da, ETH_ALEN);
136 memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN); 136 memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN);
137 if (sdata->vif.type == NL80211_IFTYPE_AP || 137 if (sdata->vif.type == NL80211_IFTYPE_AP ||
138 sdata->vif.type == NL80211_IFTYPE_AP_VLAN) 138 sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
139 memcpy(mgmt->bssid, sdata->dev->dev_addr, ETH_ALEN); 139 memcpy(mgmt->bssid, sdata->vif.addr, ETH_ALEN);
140 else if (sdata->vif.type == NL80211_IFTYPE_STATION) 140 else if (sdata->vif.type == NL80211_IFTYPE_STATION)
141 memcpy(mgmt->bssid, sdata->u.mgd.bssid, ETH_ALEN); 141 memcpy(mgmt->bssid, sdata->u.mgd.bssid, ETH_ALEN);
142 142
@@ -185,3 +185,50 @@ void ieee80211_process_delba(struct ieee80211_sub_if_data *sdata,
185 spin_unlock_bh(&sta->lock); 185 spin_unlock_bh(&sta->lock);
186 } 186 }
187} 187}
188
189int ieee80211_send_smps_action(struct ieee80211_sub_if_data *sdata,
190 enum ieee80211_smps_mode smps, const u8 *da,
191 const u8 *bssid)
192{
193 struct ieee80211_local *local = sdata->local;
194 struct sk_buff *skb;
195 struct ieee80211_mgmt *action_frame;
196
197 /* 27 = header + category + action + smps mode */
198 skb = dev_alloc_skb(27 + local->hw.extra_tx_headroom);
199 if (!skb)
200 return -ENOMEM;
201
202 skb_reserve(skb, local->hw.extra_tx_headroom);
203 action_frame = (void *)skb_put(skb, 27);
204 memcpy(action_frame->da, da, ETH_ALEN);
205 memcpy(action_frame->sa, sdata->dev->dev_addr, ETH_ALEN);
206 memcpy(action_frame->bssid, bssid, ETH_ALEN);
207 action_frame->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
208 IEEE80211_STYPE_ACTION);
209 action_frame->u.action.category = WLAN_CATEGORY_HT;
210 action_frame->u.action.u.ht_smps.action = WLAN_HT_ACTION_SMPS;
211 switch (smps) {
212 case IEEE80211_SMPS_AUTOMATIC:
213 case IEEE80211_SMPS_NUM_MODES:
214 WARN_ON(1);
215 case IEEE80211_SMPS_OFF:
216 action_frame->u.action.u.ht_smps.smps_control =
217 WLAN_HT_SMPS_CONTROL_DISABLED;
218 break;
219 case IEEE80211_SMPS_STATIC:
220 action_frame->u.action.u.ht_smps.smps_control =
221 WLAN_HT_SMPS_CONTROL_STATIC;
222 break;
223 case IEEE80211_SMPS_DYNAMIC:
224 action_frame->u.action.u.ht_smps.smps_control =
225 WLAN_HT_SMPS_CONTROL_DYNAMIC;
226 break;
227 }
228
229 /* we'll do more on status of this frame */
230 IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_CTL_REQ_TX_STATUS;
231 ieee80211_tx_skb(sdata, skb);
232
233 return 0;
234}
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
index 10d13856f86c..ef6c6b2401d1 100644
--- a/net/mac80211/ibss.c
+++ b/net/mac80211/ibss.c
@@ -117,7 +117,7 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
117 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | 117 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
118 IEEE80211_STYPE_PROBE_RESP); 118 IEEE80211_STYPE_PROBE_RESP);
119 memset(mgmt->da, 0xff, ETH_ALEN); 119 memset(mgmt->da, 0xff, ETH_ALEN);
120 memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN); 120 memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN);
121 memcpy(mgmt->bssid, ifibss->bssid, ETH_ALEN); 121 memcpy(mgmt->bssid, ifibss->bssid, ETH_ALEN);
122 mgmt->u.beacon.beacon_int = cpu_to_le16(beacon_int); 122 mgmt->u.beacon.beacon_int = cpu_to_le16(beacon_int);
123 mgmt->u.beacon.timestamp = cpu_to_le64(tsf); 123 mgmt->u.beacon.timestamp = cpu_to_le64(tsf);
@@ -252,7 +252,7 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
252 252
253 rcu_read_lock(); 253 rcu_read_lock();
254 254
255 sta = sta_info_get(local, mgmt->sa); 255 sta = sta_info_get(sdata, mgmt->sa);
256 if (sta) { 256 if (sta) {
257 u32 prev_rates; 257 u32 prev_rates;
258 258
@@ -266,7 +266,7 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
266 printk(KERN_DEBUG "%s: updated supp_rates set " 266 printk(KERN_DEBUG "%s: updated supp_rates set "
267 "for %pM based on beacon info (0x%llx | " 267 "for %pM based on beacon info (0x%llx | "
268 "0x%llx -> 0x%llx)\n", 268 "0x%llx -> 0x%llx)\n",
269 sdata->dev->name, 269 sdata->name,
270 sta->sta.addr, 270 sta->sta.addr,
271 (unsigned long long) prev_rates, 271 (unsigned long long) prev_rates,
272 (unsigned long long) supp_rates, 272 (unsigned long long) supp_rates,
@@ -364,7 +364,7 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
364#ifdef CONFIG_MAC80211_IBSS_DEBUG 364#ifdef CONFIG_MAC80211_IBSS_DEBUG
365 printk(KERN_DEBUG "%s: beacon TSF higher than " 365 printk(KERN_DEBUG "%s: beacon TSF higher than "
366 "local TSF - IBSS merge with BSSID %pM\n", 366 "local TSF - IBSS merge with BSSID %pM\n",
367 sdata->dev->name, mgmt->bssid); 367 sdata->name, mgmt->bssid);
368#endif 368#endif
369 ieee80211_sta_join_ibss(sdata, bss); 369 ieee80211_sta_join_ibss(sdata, bss);
370 ieee80211_ibss_add_sta(sdata, mgmt->bssid, mgmt->sa, supp_rates); 370 ieee80211_ibss_add_sta(sdata, mgmt->bssid, mgmt->sa, supp_rates);
@@ -393,7 +393,7 @@ struct sta_info *ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata,
393 if (local->num_sta >= IEEE80211_IBSS_MAX_STA_ENTRIES) { 393 if (local->num_sta >= IEEE80211_IBSS_MAX_STA_ENTRIES) {
394 if (net_ratelimit()) 394 if (net_ratelimit())
395 printk(KERN_DEBUG "%s: No room for a new IBSS STA entry %pM\n", 395 printk(KERN_DEBUG "%s: No room for a new IBSS STA entry %pM\n",
396 sdata->dev->name, addr); 396 sdata->name, addr);
397 return NULL; 397 return NULL;
398 } 398 }
399 399
@@ -402,7 +402,7 @@ struct sta_info *ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata,
402 402
403#ifdef CONFIG_MAC80211_VERBOSE_DEBUG 403#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
404 printk(KERN_DEBUG "%s: Adding new IBSS station %pM (dev=%s)\n", 404 printk(KERN_DEBUG "%s: Adding new IBSS station %pM (dev=%s)\n",
405 wiphy_name(local->hw.wiphy), addr, sdata->dev->name); 405 wiphy_name(local->hw.wiphy), addr, sdata->name);
406#endif 406#endif
407 407
408 sta = sta_info_alloc(sdata, addr, GFP_ATOMIC); 408 sta = sta_info_alloc(sdata, addr, GFP_ATOMIC);
@@ -466,7 +466,7 @@ static void ieee80211_sta_merge_ibss(struct ieee80211_sub_if_data *sdata)
466 return; 466 return;
467 467
468 printk(KERN_DEBUG "%s: No active IBSS STAs - trying to scan for other " 468 printk(KERN_DEBUG "%s: No active IBSS STAs - trying to scan for other "
469 "IBSS networks with same SSID (merge)\n", sdata->dev->name); 469 "IBSS networks with same SSID (merge)\n", sdata->name);
470 470
471 ieee80211_request_internal_scan(sdata, ifibss->ssid, ifibss->ssid_len); 471 ieee80211_request_internal_scan(sdata, ifibss->ssid, ifibss->ssid_len);
472} 472}
@@ -488,13 +488,13 @@ static void ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata)
488 * random number generator get different BSSID. */ 488 * random number generator get different BSSID. */
489 get_random_bytes(bssid, ETH_ALEN); 489 get_random_bytes(bssid, ETH_ALEN);
490 for (i = 0; i < ETH_ALEN; i++) 490 for (i = 0; i < ETH_ALEN; i++)
491 bssid[i] ^= sdata->dev->dev_addr[i]; 491 bssid[i] ^= sdata->vif.addr[i];
492 bssid[0] &= ~0x01; 492 bssid[0] &= ~0x01;
493 bssid[0] |= 0x02; 493 bssid[0] |= 0x02;
494 } 494 }
495 495
496 printk(KERN_DEBUG "%s: Creating new IBSS network, BSSID %pM\n", 496 printk(KERN_DEBUG "%s: Creating new IBSS network, BSSID %pM\n",
497 sdata->dev->name, bssid); 497 sdata->name, bssid);
498 498
499 sband = local->hw.wiphy->bands[ifibss->channel->band]; 499 sband = local->hw.wiphy->bands[ifibss->channel->band];
500 500
@@ -523,7 +523,7 @@ static void ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata)
523 active_ibss = ieee80211_sta_active_ibss(sdata); 523 active_ibss = ieee80211_sta_active_ibss(sdata);
524#ifdef CONFIG_MAC80211_IBSS_DEBUG 524#ifdef CONFIG_MAC80211_IBSS_DEBUG
525 printk(KERN_DEBUG "%s: sta_find_ibss (active_ibss=%d)\n", 525 printk(KERN_DEBUG "%s: sta_find_ibss (active_ibss=%d)\n",
526 sdata->dev->name, active_ibss); 526 sdata->name, active_ibss);
527#endif /* CONFIG_MAC80211_IBSS_DEBUG */ 527#endif /* CONFIG_MAC80211_IBSS_DEBUG */
528 528
529 if (active_ibss) 529 if (active_ibss)
@@ -552,7 +552,7 @@ static void ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata)
552 552
553 printk(KERN_DEBUG "%s: Selected IBSS BSSID %pM" 553 printk(KERN_DEBUG "%s: Selected IBSS BSSID %pM"
554 " based on configured SSID\n", 554 " based on configured SSID\n",
555 sdata->dev->name, bss->cbss.bssid); 555 sdata->name, bss->cbss.bssid);
556 556
557 ieee80211_sta_join_ibss(sdata, bss); 557 ieee80211_sta_join_ibss(sdata, bss);
558 ieee80211_rx_bss_put(local, bss); 558 ieee80211_rx_bss_put(local, bss);
@@ -571,7 +571,7 @@ static void ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata)
571 } else if (time_after(jiffies, ifibss->last_scan_completed + 571 } else if (time_after(jiffies, ifibss->last_scan_completed +
572 IEEE80211_SCAN_INTERVAL)) { 572 IEEE80211_SCAN_INTERVAL)) {
573 printk(KERN_DEBUG "%s: Trigger new scan to find an IBSS to " 573 printk(KERN_DEBUG "%s: Trigger new scan to find an IBSS to "
574 "join\n", sdata->dev->name); 574 "join\n", sdata->name);
575 575
576 ieee80211_request_internal_scan(sdata, ifibss->ssid, 576 ieee80211_request_internal_scan(sdata, ifibss->ssid,
577 ifibss->ssid_len); 577 ifibss->ssid_len);
@@ -585,7 +585,7 @@ static void ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata)
585 return; 585 return;
586 } 586 }
587 printk(KERN_DEBUG "%s: IBSS not allowed on" 587 printk(KERN_DEBUG "%s: IBSS not allowed on"
588 " %d MHz\n", sdata->dev->name, 588 " %d MHz\n", sdata->name,
589 local->hw.conf.channel->center_freq); 589 local->hw.conf.channel->center_freq);
590 590
591 /* No IBSS found - decrease scan interval and continue 591 /* No IBSS found - decrease scan interval and continue
@@ -619,7 +619,7 @@ static void ieee80211_rx_mgmt_probe_req(struct ieee80211_sub_if_data *sdata,
619#ifdef CONFIG_MAC80211_IBSS_DEBUG 619#ifdef CONFIG_MAC80211_IBSS_DEBUG
620 printk(KERN_DEBUG "%s: RX ProbeReq SA=%pM DA=%pM BSSID=%pM" 620 printk(KERN_DEBUG "%s: RX ProbeReq SA=%pM DA=%pM BSSID=%pM"
621 " (tx_last_beacon=%d)\n", 621 " (tx_last_beacon=%d)\n",
622 sdata->dev->name, mgmt->sa, mgmt->da, 622 sdata->name, mgmt->sa, mgmt->da,
623 mgmt->bssid, tx_last_beacon); 623 mgmt->bssid, tx_last_beacon);
624#endif /* CONFIG_MAC80211_IBSS_DEBUG */ 624#endif /* CONFIG_MAC80211_IBSS_DEBUG */
625 625
@@ -637,7 +637,7 @@ static void ieee80211_rx_mgmt_probe_req(struct ieee80211_sub_if_data *sdata,
637#ifdef CONFIG_MAC80211_IBSS_DEBUG 637#ifdef CONFIG_MAC80211_IBSS_DEBUG
638 printk(KERN_DEBUG "%s: Invalid SSID IE in ProbeReq " 638 printk(KERN_DEBUG "%s: Invalid SSID IE in ProbeReq "
639 "from %pM\n", 639 "from %pM\n",
640 sdata->dev->name, mgmt->sa); 640 sdata->name, mgmt->sa);
641#endif 641#endif
642 return; 642 return;
643 } 643 }
@@ -657,7 +657,7 @@ static void ieee80211_rx_mgmt_probe_req(struct ieee80211_sub_if_data *sdata,
657 memcpy(resp->da, mgmt->sa, ETH_ALEN); 657 memcpy(resp->da, mgmt->sa, ETH_ALEN);
658#ifdef CONFIG_MAC80211_IBSS_DEBUG 658#ifdef CONFIG_MAC80211_IBSS_DEBUG
659 printk(KERN_DEBUG "%s: Sending ProbeResp to %pM\n", 659 printk(KERN_DEBUG "%s: Sending ProbeResp to %pM\n",
660 sdata->dev->name, resp->da); 660 sdata->name, resp->da);
661#endif /* CONFIG_MAC80211_IBSS_DEBUG */ 661#endif /* CONFIG_MAC80211_IBSS_DEBUG */
662 IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT; 662 IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT;
663 ieee80211_tx_skb(sdata, skb); 663 ieee80211_tx_skb(sdata, skb);
@@ -671,7 +671,7 @@ static void ieee80211_rx_mgmt_probe_resp(struct ieee80211_sub_if_data *sdata,
671 size_t baselen; 671 size_t baselen;
672 struct ieee802_11_elems elems; 672 struct ieee802_11_elems elems;
673 673
674 if (memcmp(mgmt->da, sdata->dev->dev_addr, ETH_ALEN)) 674 if (memcmp(mgmt->da, sdata->vif.addr, ETH_ALEN))
675 return; /* ignore ProbeResp to foreign address */ 675 return; /* ignore ProbeResp to foreign address */
676 676
677 baselen = (u8 *) mgmt->u.probe_resp.variable - (u8 *) mgmt; 677 baselen = (u8 *) mgmt->u.probe_resp.variable - (u8 *) mgmt;
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 91dc8636d644..88b0ba6c7484 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -140,7 +140,6 @@ typedef unsigned __bitwise__ ieee80211_tx_result;
140 140
141struct ieee80211_tx_data { 141struct ieee80211_tx_data {
142 struct sk_buff *skb; 142 struct sk_buff *skb;
143 struct net_device *dev;
144 struct ieee80211_local *local; 143 struct ieee80211_local *local;
145 struct ieee80211_sub_if_data *sdata; 144 struct ieee80211_sub_if_data *sdata;
146 struct sta_info *sta; 145 struct sta_info *sta;
@@ -298,6 +297,8 @@ struct ieee80211_if_managed {
298 297
299 unsigned long timers_running; /* used for quiesce/restart */ 298 unsigned long timers_running; /* used for quiesce/restart */
300 bool powersave; /* powersave requested for this iface */ 299 bool powersave; /* powersave requested for this iface */
300 enum ieee80211_smps_mode req_smps, /* requested smps mode */
301 ap_smps; /* smps mode AP thinks we're in */
301 302
302 unsigned long request; 303 unsigned long request;
303 304
@@ -433,6 +434,8 @@ struct ieee80211_sub_if_data {
433 434
434 int drop_unencrypted; 435 int drop_unencrypted;
435 436
437 char name[IFNAMSIZ];
438
436 /* 439 /*
437 * keep track of whether the HT opmode (stored in 440 * keep track of whether the HT opmode (stored in
438 * vif.bss_info.ht_operation_mode) is valid. 441 * vif.bss_info.ht_operation_mode) is valid.
@@ -586,6 +589,9 @@ struct ieee80211_local {
586 /* used for uploading changed mc list */ 589 /* used for uploading changed mc list */
587 struct work_struct reconfig_filter; 590 struct work_struct reconfig_filter;
588 591
592 /* used to reconfigure hardware SM PS */
593 struct work_struct recalc_smps;
594
589 /* aggregated multicast list */ 595 /* aggregated multicast list */
590 struct dev_addr_list *mc_list; 596 struct dev_addr_list *mc_list;
591 int mc_count; 597 int mc_count;
@@ -760,6 +766,8 @@ struct ieee80211_local {
760 int user_power_level; /* in dBm */ 766 int user_power_level; /* in dBm */
761 int power_constr_level; /* in dBm */ 767 int power_constr_level; /* in dBm */
762 768
769 enum ieee80211_smps_mode smps_mode;
770
763 struct work_struct restart_work; 771 struct work_struct restart_work;
764 772
765#ifdef CONFIG_MAC80211_DEBUGFS 773#ifdef CONFIG_MAC80211_DEBUGFS
@@ -874,6 +882,8 @@ void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata,
874void ieee80211_configure_filter(struct ieee80211_local *local); 882void ieee80211_configure_filter(struct ieee80211_local *local);
875u32 ieee80211_reset_erp_info(struct ieee80211_sub_if_data *sdata); 883u32 ieee80211_reset_erp_info(struct ieee80211_sub_if_data *sdata);
876 884
885extern bool ieee80211_disable_40mhz_24ghz;
886
877/* STA code */ 887/* STA code */
878void ieee80211_sta_setup_sdata(struct ieee80211_sub_if_data *sdata); 888void ieee80211_sta_setup_sdata(struct ieee80211_sub_if_data *sdata);
879int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata, 889int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata,
@@ -938,6 +948,8 @@ void ieee80211_rx_bss_put(struct ieee80211_local *local,
938 struct ieee80211_bss *bss); 948 struct ieee80211_bss *bss);
939 949
940/* interface handling */ 950/* interface handling */
951int ieee80211_iface_init(void);
952void ieee80211_iface_exit(void);
941int ieee80211_if_add(struct ieee80211_local *local, const char *name, 953int ieee80211_if_add(struct ieee80211_local *local, const char *name,
942 struct net_device **new_dev, enum nl80211_iftype type, 954 struct net_device **new_dev, enum nl80211_iftype type,
943 struct vif_params *params); 955 struct vif_params *params);
@@ -976,6 +988,9 @@ void ieee80211_send_bar(struct ieee80211_sub_if_data *sdata, u8 *ra, u16 tid, u1
976void ieee80211_send_delba(struct ieee80211_sub_if_data *sdata, 988void ieee80211_send_delba(struct ieee80211_sub_if_data *sdata,
977 const u8 *da, u16 tid, 989 const u8 *da, u16 tid,
978 u16 initiator, u16 reason_code); 990 u16 initiator, u16 reason_code);
991int ieee80211_send_smps_action(struct ieee80211_sub_if_data *sdata,
992 enum ieee80211_smps_mode smps, const u8 *da,
993 const u8 *bssid);
979 994
980void ieee80211_sta_stop_rx_ba_session(struct ieee80211_sub_if_data *sdata, u8 *da, 995void ieee80211_sta_stop_rx_ba_session(struct ieee80211_sub_if_data *sdata, u8 *da,
981 u16 tid, u16 initiator, u16 reason); 996 u16 tid, u16 initiator, u16 reason);
@@ -1086,6 +1101,10 @@ void ieee80211_sta_def_wmm_params(struct ieee80211_sub_if_data *sdata,
1086u32 ieee80211_sta_get_rates(struct ieee80211_local *local, 1101u32 ieee80211_sta_get_rates(struct ieee80211_local *local,
1087 struct ieee802_11_elems *elems, 1102 struct ieee802_11_elems *elems,
1088 enum ieee80211_band band); 1103 enum ieee80211_band band);
1104int __ieee80211_request_smps(struct ieee80211_sub_if_data *sdata,
1105 enum ieee80211_smps_mode smps_mode);
1106void ieee80211_recalc_smps(struct ieee80211_local *local,
1107 struct ieee80211_sub_if_data *forsdata);
1089 1108
1090#ifdef CONFIG_MAC80211_NOINLINE 1109#ifdef CONFIG_MAC80211_NOINLINE
1091#define debug_noinline noinline 1110#define debug_noinline noinline
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index 80c16f6e2af6..a6e6da3cab70 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -60,6 +60,22 @@ static int ieee80211_change_mtu(struct net_device *dev, int new_mtu)
60 return 0; 60 return 0;
61} 61}
62 62
63static int ieee80211_change_mac(struct net_device *dev, void *addr)
64{
65 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
66 int ret;
67
68 if (netif_running(dev))
69 return -EBUSY;
70
71 ret = eth_mac_addr(dev, addr);
72
73 if (ret == 0)
74 memcpy(sdata->vif.addr, addr, ETH_ALEN);
75
76 return ret;
77}
78
63static inline int identical_mac_addr_allowed(int type1, int type2) 79static inline int identical_mac_addr_allowed(int type1, int type2)
64{ 80{
65 return type1 == NL80211_IFTYPE_MONITOR || 81 return type1 == NL80211_IFTYPE_MONITOR ||
@@ -234,7 +250,7 @@ static int ieee80211_open(struct net_device *dev)
234 default: 250 default:
235 conf.vif = &sdata->vif; 251 conf.vif = &sdata->vif;
236 conf.type = sdata->vif.type; 252 conf.type = sdata->vif.type;
237 conf.mac_addr = dev->dev_addr; 253 conf.mac_addr = sdata->vif.addr;
238 res = drv_add_interface(local, &conf); 254 res = drv_add_interface(local, &conf);
239 if (res) 255 if (res)
240 goto err_stop; 256 goto err_stop;
@@ -514,7 +530,7 @@ static int ieee80211_stop(struct net_device *dev)
514 530
515 conf.vif = &sdata->vif; 531 conf.vif = &sdata->vif;
516 conf.type = sdata->vif.type; 532 conf.type = sdata->vif.type;
517 conf.mac_addr = dev->dev_addr; 533 conf.mac_addr = sdata->vif.addr;
518 /* disable all keys for as long as this netdev is down */ 534 /* disable all keys for as long as this netdev is down */
519 ieee80211_disable_keys(sdata); 535 ieee80211_disable_keys(sdata);
520 drv_remove_interface(local, &conf); 536 drv_remove_interface(local, &conf);
@@ -651,7 +667,7 @@ static const struct net_device_ops ieee80211_dataif_ops = {
651 .ndo_start_xmit = ieee80211_subif_start_xmit, 667 .ndo_start_xmit = ieee80211_subif_start_xmit,
652 .ndo_set_multicast_list = ieee80211_set_multicast_list, 668 .ndo_set_multicast_list = ieee80211_set_multicast_list,
653 .ndo_change_mtu = ieee80211_change_mtu, 669 .ndo_change_mtu = ieee80211_change_mtu,
654 .ndo_set_mac_address = eth_mac_addr, 670 .ndo_set_mac_address = ieee80211_change_mac,
655}; 671};
656 672
657static const struct net_device_ops ieee80211_monitorif_ops = { 673static const struct net_device_ops ieee80211_monitorif_ops = {
@@ -794,6 +810,8 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name,
794 /* don't use IEEE80211_DEV_TO_SUB_IF because it checks too much */ 810 /* don't use IEEE80211_DEV_TO_SUB_IF because it checks too much */
795 sdata = netdev_priv(ndev); 811 sdata = netdev_priv(ndev);
796 ndev->ieee80211_ptr = &sdata->wdev; 812 ndev->ieee80211_ptr = &sdata->wdev;
813 memcpy(sdata->vif.addr, ndev->dev_addr, ETH_ALEN);
814 memcpy(sdata->name, ndev->name, IFNAMSIZ);
797 815
798 /* initialise type-independent data */ 816 /* initialise type-independent data */
799 sdata->wdev.wiphy = local->hw.wiphy; 817 sdata->wdev.wiphy = local->hw.wiphy;
@@ -945,3 +963,41 @@ void ieee80211_recalc_idle(struct ieee80211_local *local)
945 if (chg) 963 if (chg)
946 ieee80211_hw_config(local, chg); 964 ieee80211_hw_config(local, chg);
947} 965}
966
967static int netdev_notify(struct notifier_block *nb,
968 unsigned long state,
969 void *ndev)
970{
971 struct net_device *dev = ndev;
972 struct ieee80211_sub_if_data *sdata;
973
974 if (state != NETDEV_CHANGENAME)
975 return 0;
976
977 if (!dev->ieee80211_ptr || !dev->ieee80211_ptr->wiphy)
978 return 0;
979
980 if (dev->ieee80211_ptr->wiphy->privid != mac80211_wiphy_privid)
981 return 0;
982
983 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
984
985 memcpy(sdata->name, sdata->name, IFNAMSIZ);
986
987 ieee80211_debugfs_rename_netdev(sdata);
988 return 0;
989}
990
991static struct notifier_block mac80211_netdev_notifier = {
992 .notifier_call = netdev_notify,
993};
994
995int ieee80211_iface_init(void)
996{
997 return register_netdevice_notifier(&mac80211_netdev_notifier);
998}
999
1000void ieee80211_iface_exit(void)
1001{
1002 unregister_netdevice_notifier(&mac80211_netdev_notifier);
1003}
diff --git a/net/mac80211/key.c b/net/mac80211/key.c
index 659a42d529e3..32ee6d0ee34d 100644
--- a/net/mac80211/key.c
+++ b/net/mac80211/key.c
@@ -139,7 +139,7 @@ static void ieee80211_key_enable_hw_accel(struct ieee80211_key *key)
139 struct ieee80211_sub_if_data, 139 struct ieee80211_sub_if_data,
140 u.ap); 140 u.ap);
141 141
142 ret = drv_set_key(key->local, SET_KEY, &sdata->vif, sta, &key->conf); 142 ret = drv_set_key(key->local, SET_KEY, sdata, sta, &key->conf);
143 143
144 if (!ret) { 144 if (!ret) {
145 spin_lock_bh(&todo_lock); 145 spin_lock_bh(&todo_lock);
@@ -181,7 +181,7 @@ static void ieee80211_key_disable_hw_accel(struct ieee80211_key *key)
181 struct ieee80211_sub_if_data, 181 struct ieee80211_sub_if_data,
182 u.ap); 182 u.ap);
183 183
184 ret = drv_set_key(key->local, DISABLE_KEY, &sdata->vif, 184 ret = drv_set_key(key->local, DISABLE_KEY, sdata,
185 sta, &key->conf); 185 sta, &key->conf);
186 186
187 if (ret) 187 if (ret)
@@ -421,7 +421,7 @@ void ieee80211_key_link(struct ieee80211_key *key,
421 */ 421 */
422 422
423 /* same here, the AP could be using QoS */ 423 /* same here, the AP could be using QoS */
424 ap = sta_info_get(key->local, key->sdata->u.mgd.bssid); 424 ap = sta_info_get(key->sdata, key->sdata->u.mgd.bssid);
425 if (ap) { 425 if (ap) {
426 if (test_sta_flags(ap, WLAN_STA_WME)) 426 if (test_sta_flags(ap, WLAN_STA_WME))
427 key->conf.flags |= 427 key->conf.flags |=
diff --git a/net/mac80211/key.h b/net/mac80211/key.h
index a49f93b79e92..bdc2968c2bbe 100644
--- a/net/mac80211/key.h
+++ b/net/mac80211/key.h
@@ -59,11 +59,17 @@ enum ieee80211_internal_key_flags {
59 KEY_FLAG_TODO_DEFMGMTKEY = BIT(6), 59 KEY_FLAG_TODO_DEFMGMTKEY = BIT(6),
60}; 60};
61 61
62enum ieee80211_internal_tkip_state {
63 TKIP_STATE_NOT_INIT,
64 TKIP_STATE_PHASE1_DONE,
65 TKIP_STATE_PHASE1_HW_UPLOADED,
66};
67
62struct tkip_ctx { 68struct tkip_ctx {
63 u32 iv32; 69 u32 iv32;
64 u16 iv16; 70 u16 iv16;
65 u16 p1k[5]; 71 u16 p1k[5];
66 int initialized; 72 enum ieee80211_internal_tkip_state state;
67}; 73};
68 74
69struct ieee80211_key { 75struct ieee80211_key {
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index 0d2d94881f1f..d4426748ab10 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -32,7 +32,12 @@
32#include "led.h" 32#include "led.h"
33#include "cfg.h" 33#include "cfg.h"
34#include "debugfs.h" 34#include "debugfs.h"
35#include "debugfs_netdev.h" 35
36
37bool ieee80211_disable_40mhz_24ghz;
38module_param(ieee80211_disable_40mhz_24ghz, bool, 0644);
39MODULE_PARM_DESC(ieee80211_disable_40mhz_24ghz,
40 "Disable 40MHz support in the 2.4GHz band");
36 41
37void ieee80211_configure_filter(struct ieee80211_local *local) 42void ieee80211_configure_filter(struct ieee80211_local *local)
38{ 43{
@@ -114,6 +119,18 @@ int ieee80211_hw_config(struct ieee80211_local *local, u32 changed)
114 changed |= IEEE80211_CONF_CHANGE_CHANNEL; 119 changed |= IEEE80211_CONF_CHANGE_CHANNEL;
115 } 120 }
116 121
122 if (!conf_is_ht(&local->hw.conf)) {
123 /*
124 * mac80211.h documents that this is only valid
125 * when the channel is set to an HT type, and
126 * that otherwise STATIC is used.
127 */
128 local->hw.conf.smps_mode = IEEE80211_SMPS_STATIC;
129 } else if (local->hw.conf.smps_mode != local->smps_mode) {
130 local->hw.conf.smps_mode = local->smps_mode;
131 changed |= IEEE80211_CONF_CHANGE_SMPS;
132 }
133
117 if (scan_chan) 134 if (scan_chan)
118 power = chan->max_power; 135 power = chan->max_power;
119 else 136 else
@@ -173,7 +190,7 @@ void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata,
173 } else if (sdata->vif.type == NL80211_IFTYPE_ADHOC) 190 } else if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
174 sdata->vif.bss_conf.bssid = sdata->u.ibss.bssid; 191 sdata->vif.bss_conf.bssid = sdata->u.ibss.bssid;
175 else if (sdata->vif.type == NL80211_IFTYPE_AP) 192 else if (sdata->vif.type == NL80211_IFTYPE_AP)
176 sdata->vif.bss_conf.bssid = sdata->dev->dev_addr; 193 sdata->vif.bss_conf.bssid = sdata->vif.addr;
177 else if (ieee80211_vif_is_mesh(&sdata->vif)) { 194 else if (ieee80211_vif_is_mesh(&sdata->vif)) {
178 sdata->vif.bss_conf.bssid = zero; 195 sdata->vif.bss_conf.bssid = zero;
179 } else { 196 } else {
@@ -223,8 +240,7 @@ void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata,
223 } 240 }
224 } 241 }
225 242
226 drv_bss_info_changed(local, &sdata->vif, 243 drv_bss_info_changed(local, sdata, &sdata->vif.bss_conf, changed);
227 &sdata->vif.bss_conf, changed);
228} 244}
229 245
230u32 ieee80211_reset_erp_info(struct ieee80211_sub_if_data *sdata) 246u32 ieee80211_reset_erp_info(struct ieee80211_sub_if_data *sdata)
@@ -299,6 +315,16 @@ void ieee80211_restart_hw(struct ieee80211_hw *hw)
299} 315}
300EXPORT_SYMBOL(ieee80211_restart_hw); 316EXPORT_SYMBOL(ieee80211_restart_hw);
301 317
318static void ieee80211_recalc_smps_work(struct work_struct *work)
319{
320 struct ieee80211_local *local =
321 container_of(work, struct ieee80211_local, recalc_smps);
322
323 mutex_lock(&local->iflist_mtx);
324 ieee80211_recalc_smps(local, NULL);
325 mutex_unlock(&local->iflist_mtx);
326}
327
302struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, 328struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
303 const struct ieee80211_ops *ops) 329 const struct ieee80211_ops *ops)
304{ 330{
@@ -372,6 +398,8 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
372 INIT_WORK(&local->restart_work, ieee80211_restart_work); 398 INIT_WORK(&local->restart_work, ieee80211_restart_work);
373 399
374 INIT_WORK(&local->reconfig_filter, ieee80211_reconfig_filter); 400 INIT_WORK(&local->reconfig_filter, ieee80211_reconfig_filter);
401 INIT_WORK(&local->recalc_smps, ieee80211_recalc_smps_work);
402 local->smps_mode = IEEE80211_SMPS_OFF;
375 403
376 INIT_WORK(&local->dynamic_ps_enable_work, 404 INIT_WORK(&local->dynamic_ps_enable_work,
377 ieee80211_dynamic_ps_enable_work); 405 ieee80211_dynamic_ps_enable_work);
@@ -674,11 +702,19 @@ static int __init ieee80211_init(void)
674 702
675 ret = rc80211_pid_init(); 703 ret = rc80211_pid_init();
676 if (ret) 704 if (ret)
677 return ret; 705 goto err_pid;
678 706
679 ieee80211_debugfs_netdev_init(); 707 ret = ieee80211_iface_init();
708 if (ret)
709 goto err_netdev;
680 710
681 return 0; 711 return 0;
712 err_netdev:
713 rc80211_pid_exit();
714 err_pid:
715 rc80211_minstrel_exit();
716
717 return ret;
682} 718}
683 719
684static void __exit ieee80211_exit(void) 720static void __exit ieee80211_exit(void)
@@ -695,7 +731,7 @@ static void __exit ieee80211_exit(void)
695 if (mesh_allocated) 731 if (mesh_allocated)
696 ieee80211s_stop(); 732 ieee80211s_stop();
697 733
698 ieee80211_debugfs_netdev_exit(); 734 ieee80211_iface_exit();
699} 735}
700 736
701 737
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index 6a4331429598..e0bd85e3d4b6 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -457,7 +457,7 @@ static void ieee80211_mesh_housekeeping(struct ieee80211_sub_if_data *sdata,
457 457
458#ifdef CONFIG_MAC80211_VERBOSE_DEBUG 458#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
459 printk(KERN_DEBUG "%s: running mesh housekeeping\n", 459 printk(KERN_DEBUG "%s: running mesh housekeeping\n",
460 sdata->dev->name); 460 sdata->name);
461#endif 461#endif
462 462
463 ieee80211_sta_expire(sdata, IEEE80211_MESH_PEER_INACTIVITY_LIMIT); 463 ieee80211_sta_expire(sdata, IEEE80211_MESH_PEER_INACTIVITY_LIMIT);
@@ -565,7 +565,7 @@ static void ieee80211_mesh_rx_bcn_presp(struct ieee80211_sub_if_data *sdata,
565 565
566 /* ignore ProbeResp to foreign address */ 566 /* ignore ProbeResp to foreign address */
567 if (stype == IEEE80211_STYPE_PROBE_RESP && 567 if (stype == IEEE80211_STYPE_PROBE_RESP &&
568 compare_ether_addr(mgmt->da, sdata->dev->dev_addr)) 568 compare_ether_addr(mgmt->da, sdata->vif.addr))
569 return; 569 return;
570 570
571 baselen = (u8 *) mgmt->u.probe_resp.variable - (u8 *) mgmt; 571 baselen = (u8 *) mgmt->u.probe_resp.variable - (u8 *) mgmt;
diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c
index d28acb6b1f81..ce84237ebad3 100644
--- a/net/mac80211/mesh_hwmp.c
+++ b/net/mac80211/mesh_hwmp.c
@@ -128,9 +128,9 @@ static int mesh_path_sel_frame_tx(enum mpath_frame_type action, u8 flags,
128 IEEE80211_STYPE_ACTION); 128 IEEE80211_STYPE_ACTION);
129 129
130 memcpy(mgmt->da, da, ETH_ALEN); 130 memcpy(mgmt->da, da, ETH_ALEN);
131 memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN); 131 memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN);
132 /* BSSID == SA */ 132 /* BSSID == SA */
133 memcpy(mgmt->bssid, sdata->dev->dev_addr, ETH_ALEN); 133 memcpy(mgmt->bssid, sdata->vif.addr, ETH_ALEN);
134 mgmt->u.action.category = MESH_PATH_SEL_CATEGORY; 134 mgmt->u.action.category = MESH_PATH_SEL_CATEGORY;
135 mgmt->u.action.u.mesh_action.action_code = MESH_PATH_SEL_ACTION; 135 mgmt->u.action.u.mesh_action.action_code = MESH_PATH_SEL_ACTION;
136 136
@@ -222,7 +222,7 @@ int mesh_path_error_tx(u8 ttl, u8 *target, __le32 target_sn,
222 IEEE80211_STYPE_ACTION); 222 IEEE80211_STYPE_ACTION);
223 223
224 memcpy(mgmt->da, ra, ETH_ALEN); 224 memcpy(mgmt->da, ra, ETH_ALEN);
225 memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN); 225 memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN);
226 /* BSSID is left zeroed, wildcard value */ 226 /* BSSID is left zeroed, wildcard value */
227 mgmt->u.action.category = MESH_PATH_SEL_CATEGORY; 227 mgmt->u.action.category = MESH_PATH_SEL_CATEGORY;
228 mgmt->u.action.u.mesh_action.action_code = MESH_PATH_SEL_ACTION; 228 mgmt->u.action.u.mesh_action.action_code = MESH_PATH_SEL_ACTION;
@@ -335,7 +335,7 @@ static u32 hwmp_route_info_get(struct ieee80211_sub_if_data *sdata,
335 bool process = true; 335 bool process = true;
336 336
337 rcu_read_lock(); 337 rcu_read_lock();
338 sta = sta_info_get(local, mgmt->sa); 338 sta = sta_info_get(sdata, mgmt->sa);
339 if (!sta) { 339 if (!sta) {
340 rcu_read_unlock(); 340 rcu_read_unlock();
341 return 0; 341 return 0;
@@ -374,7 +374,7 @@ static u32 hwmp_route_info_get(struct ieee80211_sub_if_data *sdata,
374 new_metric = MAX_METRIC; 374 new_metric = MAX_METRIC;
375 exp_time = TU_TO_EXP_TIME(orig_lifetime); 375 exp_time = TU_TO_EXP_TIME(orig_lifetime);
376 376
377 if (memcmp(orig_addr, sdata->dev->dev_addr, ETH_ALEN) == 0) { 377 if (memcmp(orig_addr, sdata->vif.addr, ETH_ALEN) == 0) {
378 /* This MP is the originator, we are not interested in this 378 /* This MP is the originator, we are not interested in this
379 * frame, except for updating transmitter's path info. 379 * frame, except for updating transmitter's path info.
380 */ 380 */
@@ -486,7 +486,7 @@ static void hwmp_preq_frame_process(struct ieee80211_sub_if_data *sdata,
486 486
487 mhwmp_dbg("received PREQ from %pM\n", orig_addr); 487 mhwmp_dbg("received PREQ from %pM\n", orig_addr);
488 488
489 if (memcmp(target_addr, sdata->dev->dev_addr, ETH_ALEN) == 0) { 489 if (memcmp(target_addr, sdata->vif.addr, ETH_ALEN) == 0) {
490 mhwmp_dbg("PREQ is for us\n"); 490 mhwmp_dbg("PREQ is for us\n");
491 forward = false; 491 forward = false;
492 reply = true; 492 reply = true;
@@ -579,7 +579,7 @@ static void hwmp_prep_frame_process(struct ieee80211_sub_if_data *sdata,
579 * replies 579 * replies
580 */ 580 */
581 target_addr = PREP_IE_TARGET_ADDR(prep_elem); 581 target_addr = PREP_IE_TARGET_ADDR(prep_elem);
582 if (memcmp(target_addr, sdata->dev->dev_addr, ETH_ALEN) == 0) 582 if (memcmp(target_addr, sdata->vif.addr, ETH_ALEN) == 0)
583 /* destination, no forwarding required */ 583 /* destination, no forwarding required */
584 return; 584 return;
585 585
@@ -890,7 +890,7 @@ void mesh_path_start_discovery(struct ieee80211_sub_if_data *sdata)
890 target_flags = MP_F_RF; 890 target_flags = MP_F_RF;
891 891
892 spin_unlock_bh(&mpath->state_lock); 892 spin_unlock_bh(&mpath->state_lock);
893 mesh_path_sel_frame_tx(MPATH_PREQ, 0, sdata->dev->dev_addr, 893 mesh_path_sel_frame_tx(MPATH_PREQ, 0, sdata->vif.addr,
894 cpu_to_le32(ifmsh->sn), target_flags, mpath->dst, 894 cpu_to_le32(ifmsh->sn), target_flags, mpath->dst,
895 cpu_to_le32(mpath->sn), broadcast_addr, 0, 895 cpu_to_le32(mpath->sn), broadcast_addr, 0,
896 ttl, cpu_to_le32(lifetime), 0, 896 ttl, cpu_to_le32(lifetime), 0,
@@ -939,7 +939,7 @@ int mesh_nexthop_lookup(struct sk_buff *skb,
939 if (time_after(jiffies, 939 if (time_after(jiffies,
940 mpath->exp_time - 940 mpath->exp_time -
941 msecs_to_jiffies(sdata->u.mesh.mshcfg.path_refresh_time)) && 941 msecs_to_jiffies(sdata->u.mesh.mshcfg.path_refresh_time)) &&
942 !memcmp(sdata->dev->dev_addr, hdr->addr4, ETH_ALEN) && 942 !memcmp(sdata->vif.addr, hdr->addr4, ETH_ALEN) &&
943 !(mpath->flags & MESH_PATH_RESOLVING) && 943 !(mpath->flags & MESH_PATH_RESOLVING) &&
944 !(mpath->flags & MESH_PATH_FIXED)) { 944 !(mpath->flags & MESH_PATH_FIXED)) {
945 mesh_queue_preq(mpath, 945 mesh_queue_preq(mpath,
@@ -1010,7 +1010,7 @@ mesh_path_tx_root_frame(struct ieee80211_sub_if_data *sdata)
1010{ 1010{
1011 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; 1011 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
1012 1012
1013 mesh_path_sel_frame_tx(MPATH_RANN, 0, sdata->dev->dev_addr, 1013 mesh_path_sel_frame_tx(MPATH_RANN, 0, sdata->vif.addr,
1014 cpu_to_le32(++ifmsh->sn), 1014 cpu_to_le32(++ifmsh->sn),
1015 0, NULL, 0, broadcast_addr, 1015 0, NULL, 0, broadcast_addr,
1016 0, MESH_TTL, 0, 0, 0, sdata); 1016 0, MESH_TTL, 0, 0, 0, sdata);
diff --git a/net/mac80211/mesh_pathtbl.c b/net/mac80211/mesh_pathtbl.c
index 0192cfdacae4..2312efe04c62 100644
--- a/net/mac80211/mesh_pathtbl.c
+++ b/net/mac80211/mesh_pathtbl.c
@@ -260,7 +260,7 @@ int mesh_path_add(u8 *dst, struct ieee80211_sub_if_data *sdata)
260 int err = 0; 260 int err = 0;
261 u32 hash_idx; 261 u32 hash_idx;
262 262
263 if (memcmp(dst, sdata->dev->dev_addr, ETH_ALEN) == 0) 263 if (memcmp(dst, sdata->vif.addr, ETH_ALEN) == 0)
264 /* never add ourselves as neighbours */ 264 /* never add ourselves as neighbours */
265 return -ENOTSUPP; 265 return -ENOTSUPP;
266 266
@@ -377,7 +377,7 @@ int mpp_path_add(u8 *dst, u8 *mpp, struct ieee80211_sub_if_data *sdata)
377 int err = 0; 377 int err = 0;
378 u32 hash_idx; 378 u32 hash_idx;
379 379
380 if (memcmp(dst, sdata->dev->dev_addr, ETH_ALEN) == 0) 380 if (memcmp(dst, sdata->vif.addr, ETH_ALEN) == 0)
381 /* never add ourselves as neighbours */ 381 /* never add ourselves as neighbours */
382 return -ENOTSUPP; 382 return -ENOTSUPP;
383 383
@@ -605,7 +605,7 @@ void mesh_path_discard_frame(struct sk_buff *skb,
605 struct mesh_path *mpath; 605 struct mesh_path *mpath;
606 u32 sn = 0; 606 u32 sn = 0;
607 607
608 if (memcmp(hdr->addr4, sdata->dev->dev_addr, ETH_ALEN) != 0) { 608 if (memcmp(hdr->addr4, sdata->vif.addr, ETH_ALEN) != 0) {
609 u8 *ra, *da; 609 u8 *ra, *da;
610 610
611 da = hdr->addr3; 611 da = hdr->addr3;
diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c
index 0f7c6e6a4248..7985e5150898 100644
--- a/net/mac80211/mesh_plink.c
+++ b/net/mac80211/mesh_plink.c
@@ -169,7 +169,7 @@ static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata,
169 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | 169 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
170 IEEE80211_STYPE_ACTION); 170 IEEE80211_STYPE_ACTION);
171 memcpy(mgmt->da, da, ETH_ALEN); 171 memcpy(mgmt->da, da, ETH_ALEN);
172 memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN); 172 memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN);
173 /* BSSID is left zeroed, wildcard value */ 173 /* BSSID is left zeroed, wildcard value */
174 mgmt->u.action.category = MESH_PLINK_CATEGORY; 174 mgmt->u.action.category = MESH_PLINK_CATEGORY;
175 mgmt->u.action.u.plink_action.action_code = action; 175 mgmt->u.action.u.plink_action.action_code = action;
@@ -234,7 +234,7 @@ void mesh_neighbour_update(u8 *hw_addr, u32 rates, struct ieee80211_sub_if_data
234 234
235 rcu_read_lock(); 235 rcu_read_lock();
236 236
237 sta = sta_info_get(local, hw_addr); 237 sta = sta_info_get(sdata, hw_addr);
238 if (!sta) { 238 if (!sta) {
239 sta = mesh_plink_alloc(sdata, hw_addr, rates); 239 sta = mesh_plink_alloc(sdata, hw_addr, rates);
240 if (!sta) { 240 if (!sta) {
@@ -455,7 +455,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
455 455
456 rcu_read_lock(); 456 rcu_read_lock();
457 457
458 sta = sta_info_get(local, mgmt->sa); 458 sta = sta_info_get(sdata, mgmt->sa);
459 if (!sta && ftype != PLINK_OPEN) { 459 if (!sta && ftype != PLINK_OPEN) {
460 mpl_dbg("Mesh plink: cls or cnf from unknown peer\n"); 460 mpl_dbg("Mesh plink: cls or cnf from unknown peer\n");
461 rcu_read_unlock(); 461 rcu_read_unlock();
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index c79e59f82fd9..2f9ed8b9c3f0 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -75,6 +75,9 @@ enum rx_mgmt_action {
75 /* caller must call cfg80211_send_disassoc() */ 75 /* caller must call cfg80211_send_disassoc() */
76 RX_MGMT_CFG80211_DISASSOC, 76 RX_MGMT_CFG80211_DISASSOC,
77 77
78 /* caller must tell cfg80211 about internal error */
79 RX_MGMT_CFG80211_ASSOC_ERROR,
80
78 /* caller must call cfg80211_auth_timeout() & free work */ 81 /* caller must call cfg80211_auth_timeout() & free work */
79 RX_MGMT_CFG80211_AUTH_TO, 82 RX_MGMT_CFG80211_AUTH_TO,
80 83
@@ -202,7 +205,7 @@ static u32 ieee80211_enable_ht(struct ieee80211_sub_if_data *sdata,
202 ieee80211_hw_config(local, 0); 205 ieee80211_hw_config(local, 0);
203 206
204 rcu_read_lock(); 207 rcu_read_lock();
205 sta = sta_info_get(local, bssid); 208 sta = sta_info_get(sdata, bssid);
206 if (sta) 209 if (sta)
207 rate_control_rate_update(local, sband, sta, 210 rate_control_rate_update(local, sband, sta,
208 IEEE80211_RC_HT_CHANGED); 211 IEEE80211_RC_HT_CHANGED);
@@ -248,7 +251,7 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata,
248 wk->ssid_len); 251 wk->ssid_len);
249 if (!skb) { 252 if (!skb) {
250 printk(KERN_DEBUG "%s: failed to allocate buffer for assoc " 253 printk(KERN_DEBUG "%s: failed to allocate buffer for assoc "
251 "frame\n", sdata->dev->name); 254 "frame\n", sdata->name);
252 return; 255 return;
253 } 256 }
254 skb_reserve(skb, local->hw.extra_tx_headroom); 257 skb_reserve(skb, local->hw.extra_tx_headroom);
@@ -282,7 +285,7 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata,
282 mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24); 285 mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24);
283 memset(mgmt, 0, 24); 286 memset(mgmt, 0, 24);
284 memcpy(mgmt->da, wk->bss->cbss.bssid, ETH_ALEN); 287 memcpy(mgmt->da, wk->bss->cbss.bssid, ETH_ALEN);
285 memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN); 288 memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN);
286 memcpy(mgmt->bssid, wk->bss->cbss.bssid, ETH_ALEN); 289 memcpy(mgmt->bssid, wk->bss->cbss.bssid, ETH_ALEN);
287 290
288 if (!is_zero_ether_addr(wk->prev_bssid)) { 291 if (!is_zero_ether_addr(wk->prev_bssid)) {
@@ -398,6 +401,14 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata,
398 __le16 tmp; 401 __le16 tmp;
399 u32 flags = local->hw.conf.channel->flags; 402 u32 flags = local->hw.conf.channel->flags;
400 403
404 /* determine capability flags */
405
406 if (ieee80211_disable_40mhz_24ghz &&
407 sband->band == IEEE80211_BAND_2GHZ) {
408 cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
409 cap &= ~IEEE80211_HT_CAP_SGI_40;
410 }
411
401 switch (ht_info->ht_param & IEEE80211_HT_PARAM_CHA_SEC_OFFSET) { 412 switch (ht_info->ht_param & IEEE80211_HT_PARAM_CHA_SEC_OFFSET) {
402 case IEEE80211_HT_PARAM_CHA_SEC_ABOVE: 413 case IEEE80211_HT_PARAM_CHA_SEC_ABOVE:
403 if (flags & IEEE80211_CHAN_NO_HT40PLUS) { 414 if (flags & IEEE80211_CHAN_NO_HT40PLUS) {
@@ -413,17 +424,64 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata,
413 break; 424 break;
414 } 425 }
415 426
416 tmp = cpu_to_le16(cap); 427 /* set SM PS mode properly */
417 pos = skb_put(skb, sizeof(struct ieee80211_ht_cap)+2); 428 cap &= ~IEEE80211_HT_CAP_SM_PS;
429 /* new association always uses requested smps mode */
430 if (ifmgd->req_smps == IEEE80211_SMPS_AUTOMATIC) {
431 if (ifmgd->powersave)
432 ifmgd->ap_smps = IEEE80211_SMPS_DYNAMIC;
433 else
434 ifmgd->ap_smps = IEEE80211_SMPS_OFF;
435 } else
436 ifmgd->ap_smps = ifmgd->req_smps;
437
438 switch (ifmgd->ap_smps) {
439 case IEEE80211_SMPS_AUTOMATIC:
440 case IEEE80211_SMPS_NUM_MODES:
441 WARN_ON(1);
442 case IEEE80211_SMPS_OFF:
443 cap |= WLAN_HT_CAP_SM_PS_DISABLED <<
444 IEEE80211_HT_CAP_SM_PS_SHIFT;
445 break;
446 case IEEE80211_SMPS_STATIC:
447 cap |= WLAN_HT_CAP_SM_PS_STATIC <<
448 IEEE80211_HT_CAP_SM_PS_SHIFT;
449 break;
450 case IEEE80211_SMPS_DYNAMIC:
451 cap |= WLAN_HT_CAP_SM_PS_DYNAMIC <<
452 IEEE80211_HT_CAP_SM_PS_SHIFT;
453 break;
454 }
455
456 /* reserve and fill IE */
457
458 pos = skb_put(skb, sizeof(struct ieee80211_ht_cap) + 2);
418 *pos++ = WLAN_EID_HT_CAPABILITY; 459 *pos++ = WLAN_EID_HT_CAPABILITY;
419 *pos++ = sizeof(struct ieee80211_ht_cap); 460 *pos++ = sizeof(struct ieee80211_ht_cap);
420 memset(pos, 0, sizeof(struct ieee80211_ht_cap)); 461 memset(pos, 0, sizeof(struct ieee80211_ht_cap));
462
463 /* capability flags */
464 tmp = cpu_to_le16(cap);
421 memcpy(pos, &tmp, sizeof(u16)); 465 memcpy(pos, &tmp, sizeof(u16));
422 pos += sizeof(u16); 466 pos += sizeof(u16);
423 /* TODO: needs a define here for << 2 */ 467
468 /* AMPDU parameters */
424 *pos++ = sband->ht_cap.ampdu_factor | 469 *pos++ = sband->ht_cap.ampdu_factor |
425 (sband->ht_cap.ampdu_density << 2); 470 (sband->ht_cap.ampdu_density <<
471 IEEE80211_HT_AMPDU_PARM_DENSITY_SHIFT);
472
473 /* MCS set */
426 memcpy(pos, &sband->ht_cap.mcs, sizeof(sband->ht_cap.mcs)); 474 memcpy(pos, &sband->ht_cap.mcs, sizeof(sband->ht_cap.mcs));
475 pos += sizeof(sband->ht_cap.mcs);
476
477 /* extended capabilities */
478 pos += sizeof(__le16);
479
480 /* BF capabilities */
481 pos += sizeof(__le32);
482
483 /* antenna selection */
484 pos += sizeof(u8);
427 } 485 }
428 486
429 IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT; 487 IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT;
@@ -443,7 +501,7 @@ static void ieee80211_send_deauth_disassoc(struct ieee80211_sub_if_data *sdata,
443 skb = dev_alloc_skb(local->hw.extra_tx_headroom + sizeof(*mgmt)); 501 skb = dev_alloc_skb(local->hw.extra_tx_headroom + sizeof(*mgmt));
444 if (!skb) { 502 if (!skb) {
445 printk(KERN_DEBUG "%s: failed to allocate buffer for " 503 printk(KERN_DEBUG "%s: failed to allocate buffer for "
446 "deauth/disassoc frame\n", sdata->dev->name); 504 "deauth/disassoc frame\n", sdata->name);
447 return; 505 return;
448 } 506 }
449 skb_reserve(skb, local->hw.extra_tx_headroom); 507 skb_reserve(skb, local->hw.extra_tx_headroom);
@@ -451,7 +509,7 @@ static void ieee80211_send_deauth_disassoc(struct ieee80211_sub_if_data *sdata,
451 mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24); 509 mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24);
452 memset(mgmt, 0, 24); 510 memset(mgmt, 0, 24);
453 memcpy(mgmt->da, bssid, ETH_ALEN); 511 memcpy(mgmt->da, bssid, ETH_ALEN);
454 memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN); 512 memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN);
455 memcpy(mgmt->bssid, bssid, ETH_ALEN); 513 memcpy(mgmt->bssid, bssid, ETH_ALEN);
456 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | stype); 514 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | stype);
457 skb_put(skb, 2); 515 skb_put(skb, 2);
@@ -484,7 +542,7 @@ void ieee80211_send_pspoll(struct ieee80211_local *local,
484 skb = dev_alloc_skb(local->hw.extra_tx_headroom + sizeof(*pspoll)); 542 skb = dev_alloc_skb(local->hw.extra_tx_headroom + sizeof(*pspoll));
485 if (!skb) { 543 if (!skb) {
486 printk(KERN_DEBUG "%s: failed to allocate buffer for " 544 printk(KERN_DEBUG "%s: failed to allocate buffer for "
487 "pspoll frame\n", sdata->dev->name); 545 "pspoll frame\n", sdata->name);
488 return; 546 return;
489 } 547 }
490 skb_reserve(skb, local->hw.extra_tx_headroom); 548 skb_reserve(skb, local->hw.extra_tx_headroom);
@@ -499,7 +557,7 @@ void ieee80211_send_pspoll(struct ieee80211_local *local,
499 pspoll->aid |= cpu_to_le16(1 << 15 | 1 << 14); 557 pspoll->aid |= cpu_to_le16(1 << 15 | 1 << 14);
500 558
501 memcpy(pspoll->bssid, ifmgd->bssid, ETH_ALEN); 559 memcpy(pspoll->bssid, ifmgd->bssid, ETH_ALEN);
502 memcpy(pspoll->ta, sdata->dev->dev_addr, ETH_ALEN); 560 memcpy(pspoll->ta, sdata->vif.addr, ETH_ALEN);
503 561
504 IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT; 562 IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT;
505 ieee80211_tx_skb(sdata, skb); 563 ieee80211_tx_skb(sdata, skb);
@@ -519,7 +577,7 @@ void ieee80211_send_nullfunc(struct ieee80211_local *local,
519 skb = dev_alloc_skb(local->hw.extra_tx_headroom + 24); 577 skb = dev_alloc_skb(local->hw.extra_tx_headroom + 24);
520 if (!skb) { 578 if (!skb) {
521 printk(KERN_DEBUG "%s: failed to allocate buffer for nullfunc " 579 printk(KERN_DEBUG "%s: failed to allocate buffer for nullfunc "
522 "frame\n", sdata->dev->name); 580 "frame\n", sdata->name);
523 return; 581 return;
524 } 582 }
525 skb_reserve(skb, local->hw.extra_tx_headroom); 583 skb_reserve(skb, local->hw.extra_tx_headroom);
@@ -532,7 +590,7 @@ void ieee80211_send_nullfunc(struct ieee80211_local *local,
532 fc |= cpu_to_le16(IEEE80211_FCTL_PM); 590 fc |= cpu_to_le16(IEEE80211_FCTL_PM);
533 nullfunc->frame_control = fc; 591 nullfunc->frame_control = fc;
534 memcpy(nullfunc->addr1, sdata->u.mgd.bssid, ETH_ALEN); 592 memcpy(nullfunc->addr1, sdata->u.mgd.bssid, ETH_ALEN);
535 memcpy(nullfunc->addr2, sdata->dev->dev_addr, ETH_ALEN); 593 memcpy(nullfunc->addr2, sdata->vif.addr, ETH_ALEN);
536 memcpy(nullfunc->addr3, sdata->u.mgd.bssid, ETH_ALEN); 594 memcpy(nullfunc->addr3, sdata->u.mgd.bssid, ETH_ALEN);
537 595
538 IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT; 596 IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT;
@@ -940,6 +998,7 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata,
940 998
941 mutex_lock(&local->iflist_mtx); 999 mutex_lock(&local->iflist_mtx);
942 ieee80211_recalc_ps(local, -1); 1000 ieee80211_recalc_ps(local, -1);
1001 ieee80211_recalc_smps(local, sdata);
943 mutex_unlock(&local->iflist_mtx); 1002 mutex_unlock(&local->iflist_mtx);
944 1003
945 netif_start_queue(sdata->dev); 1004 netif_start_queue(sdata->dev);
@@ -956,7 +1015,7 @@ ieee80211_direct_probe(struct ieee80211_sub_if_data *sdata,
956 wk->tries++; 1015 wk->tries++;
957 if (wk->tries > IEEE80211_AUTH_MAX_TRIES) { 1016 if (wk->tries > IEEE80211_AUTH_MAX_TRIES) {
958 printk(KERN_DEBUG "%s: direct probe to AP %pM timed out\n", 1017 printk(KERN_DEBUG "%s: direct probe to AP %pM timed out\n",
959 sdata->dev->name, wk->bss->cbss.bssid); 1018 sdata->name, wk->bss->cbss.bssid);
960 1019
961 /* 1020 /*
962 * Most likely AP is not in the range so remove the 1021 * Most likely AP is not in the range so remove the
@@ -974,7 +1033,7 @@ ieee80211_direct_probe(struct ieee80211_sub_if_data *sdata,
974 } 1033 }
975 1034
976 printk(KERN_DEBUG "%s: direct probe to AP %pM (try %d)\n", 1035 printk(KERN_DEBUG "%s: direct probe to AP %pM (try %d)\n",
977 sdata->dev->name, wk->bss->cbss.bssid, 1036 sdata->name, wk->bss->cbss.bssid,
978 wk->tries); 1037 wk->tries);
979 1038
980 /* 1039 /*
@@ -1001,7 +1060,7 @@ ieee80211_authenticate(struct ieee80211_sub_if_data *sdata,
1001 if (wk->tries > IEEE80211_AUTH_MAX_TRIES) { 1060 if (wk->tries > IEEE80211_AUTH_MAX_TRIES) {
1002 printk(KERN_DEBUG "%s: authentication with AP %pM" 1061 printk(KERN_DEBUG "%s: authentication with AP %pM"
1003 " timed out\n", 1062 " timed out\n",
1004 sdata->dev->name, wk->bss->cbss.bssid); 1063 sdata->name, wk->bss->cbss.bssid);
1005 1064
1006 /* 1065 /*
1007 * Most likely AP is not in the range so remove the 1066 * Most likely AP is not in the range so remove the
@@ -1019,7 +1078,7 @@ ieee80211_authenticate(struct ieee80211_sub_if_data *sdata,
1019 } 1078 }
1020 1079
1021 printk(KERN_DEBUG "%s: authenticate with AP %pM (try %d)\n", 1080 printk(KERN_DEBUG "%s: authenticate with AP %pM (try %d)\n",
1022 sdata->dev->name, wk->bss->cbss.bssid, wk->tries); 1081 sdata->name, wk->bss->cbss.bssid, wk->tries);
1023 1082
1024 ieee80211_send_auth(sdata, 1, wk->auth_alg, wk->ie, wk->ie_len, 1083 ieee80211_send_auth(sdata, 1, wk->auth_alg, wk->ie, wk->ie_len,
1025 wk->bss->cbss.bssid, NULL, 0, 0); 1084 wk->bss->cbss.bssid, NULL, 0, 0);
@@ -1078,7 +1137,7 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
1078 netif_carrier_off(sdata->dev); 1137 netif_carrier_off(sdata->dev);
1079 1138
1080 rcu_read_lock(); 1139 rcu_read_lock();
1081 sta = sta_info_get(local, bssid); 1140 sta = sta_info_get(sdata, bssid);
1082 if (sta) 1141 if (sta)
1083 ieee80211_sta_tear_down_BA_sessions(sta); 1142 ieee80211_sta_tear_down_BA_sessions(sta);
1084 rcu_read_unlock(); 1143 rcu_read_unlock();
@@ -1115,7 +1174,7 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
1115 1174
1116 rcu_read_lock(); 1175 rcu_read_lock();
1117 1176
1118 sta = sta_info_get(local, bssid); 1177 sta = sta_info_get(sdata, bssid);
1119 if (!sta) { 1178 if (!sta) {
1120 rcu_read_unlock(); 1179 rcu_read_unlock();
1121 return; 1180 return;
@@ -1139,7 +1198,7 @@ ieee80211_associate(struct ieee80211_sub_if_data *sdata,
1139 if (wk->tries > IEEE80211_ASSOC_MAX_TRIES) { 1198 if (wk->tries > IEEE80211_ASSOC_MAX_TRIES) {
1140 printk(KERN_DEBUG "%s: association with AP %pM" 1199 printk(KERN_DEBUG "%s: association with AP %pM"
1141 " timed out\n", 1200 " timed out\n",
1142 sdata->dev->name, wk->bss->cbss.bssid); 1201 sdata->name, wk->bss->cbss.bssid);
1143 1202
1144 /* 1203 /*
1145 * Most likely AP is not in the range so remove the 1204 * Most likely AP is not in the range so remove the
@@ -1157,7 +1216,7 @@ ieee80211_associate(struct ieee80211_sub_if_data *sdata,
1157 } 1216 }
1158 1217
1159 printk(KERN_DEBUG "%s: associate with AP %pM (try %d)\n", 1218 printk(KERN_DEBUG "%s: associate with AP %pM (try %d)\n",
1160 sdata->dev->name, wk->bss->cbss.bssid, wk->tries); 1219 sdata->name, wk->bss->cbss.bssid, wk->tries);
1161 ieee80211_send_assoc(sdata, wk); 1220 ieee80211_send_assoc(sdata, wk);
1162 1221
1163 wk->timeout = jiffies + IEEE80211_ASSOC_TIMEOUT; 1222 wk->timeout = jiffies + IEEE80211_ASSOC_TIMEOUT;
@@ -1218,7 +1277,7 @@ static void ieee80211_mgd_probe_ap(struct ieee80211_sub_if_data *sdata,
1218#ifdef CONFIG_MAC80211_VERBOSE_DEBUG 1277#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
1219 if (beacon && net_ratelimit()) 1278 if (beacon && net_ratelimit())
1220 printk(KERN_DEBUG "%s: detected beacon loss from AP " 1279 printk(KERN_DEBUG "%s: detected beacon loss from AP "
1221 "- sending probe request\n", sdata->dev->name); 1280 "- sending probe request\n", sdata->name);
1222#endif 1281#endif
1223 1282
1224 /* 1283 /*
@@ -1275,7 +1334,7 @@ static void ieee80211_auth_completed(struct ieee80211_sub_if_data *sdata,
1275 struct ieee80211_mgd_work *wk) 1334 struct ieee80211_mgd_work *wk)
1276{ 1335{
1277 wk->state = IEEE80211_MGD_STATE_IDLE; 1336 wk->state = IEEE80211_MGD_STATE_IDLE;
1278 printk(KERN_DEBUG "%s: authenticated\n", sdata->dev->name); 1337 printk(KERN_DEBUG "%s: authenticated\n", sdata->name);
1279} 1338}
1280 1339
1281 1340
@@ -1372,7 +1431,7 @@ ieee80211_rx_mgmt_deauth(struct ieee80211_sub_if_data *sdata,
1372 reason_code = le16_to_cpu(mgmt->u.deauth.reason_code); 1431 reason_code = le16_to_cpu(mgmt->u.deauth.reason_code);
1373 1432
1374 printk(KERN_DEBUG "%s: deauthenticated from %pM (Reason: %u)\n", 1433 printk(KERN_DEBUG "%s: deauthenticated from %pM (Reason: %u)\n",
1375 sdata->dev->name, bssid, reason_code); 1434 sdata->name, bssid, reason_code);
1376 1435
1377 if (!wk) { 1436 if (!wk) {
1378 ieee80211_set_disassoc(sdata, true); 1437 ieee80211_set_disassoc(sdata, true);
@@ -1407,7 +1466,7 @@ ieee80211_rx_mgmt_disassoc(struct ieee80211_sub_if_data *sdata,
1407 reason_code = le16_to_cpu(mgmt->u.disassoc.reason_code); 1466 reason_code = le16_to_cpu(mgmt->u.disassoc.reason_code);
1408 1467
1409 printk(KERN_DEBUG "%s: disassociated from %pM (Reason: %u)\n", 1468 printk(KERN_DEBUG "%s: disassociated from %pM (Reason: %u)\n",
1410 sdata->dev->name, mgmt->sa, reason_code); 1469 sdata->name, mgmt->sa, reason_code);
1411 1470
1412 ieee80211_set_disassoc(sdata, false); 1471 ieee80211_set_disassoc(sdata, false);
1413 ieee80211_recalc_idle(sdata->local); 1472 ieee80211_recalc_idle(sdata->local);
@@ -1431,8 +1490,8 @@ ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
1431 struct ieee80211_bss_conf *bss_conf = &sdata->vif.bss_conf; 1490 struct ieee80211_bss_conf *bss_conf = &sdata->vif.bss_conf;
1432 u8 *pos; 1491 u8 *pos;
1433 u32 changed = 0; 1492 u32 changed = 0;
1434 int i, j; 1493 int i, j, err;
1435 bool have_higher_than_11mbit = false, newsta = false; 1494 bool have_higher_than_11mbit = false;
1436 u16 ap_ht_cap_flags; 1495 u16 ap_ht_cap_flags;
1437 1496
1438 /* 1497 /*
@@ -1452,7 +1511,7 @@ ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
1452 1511
1453 printk(KERN_DEBUG "%s: RX %sssocResp from %pM (capab=0x%x " 1512 printk(KERN_DEBUG "%s: RX %sssocResp from %pM (capab=0x%x "
1454 "status=%d aid=%d)\n", 1513 "status=%d aid=%d)\n",
1455 sdata->dev->name, reassoc ? "Rea" : "A", mgmt->sa, 1514 sdata->name, reassoc ? "Rea" : "A", mgmt->sa,
1456 capab_info, status_code, (u16)(aid & ~(BIT(15) | BIT(14)))); 1515 capab_info, status_code, (u16)(aid & ~(BIT(15) | BIT(14))));
1457 1516
1458 pos = mgmt->u.assoc_resp.variable; 1517 pos = mgmt->u.assoc_resp.variable;
@@ -1466,7 +1525,7 @@ ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
1466 ms = tu * 1024 / 1000; 1525 ms = tu * 1024 / 1000;
1467 printk(KERN_DEBUG "%s: AP rejected association temporarily; " 1526 printk(KERN_DEBUG "%s: AP rejected association temporarily; "
1468 "comeback duration %u TU (%u ms)\n", 1527 "comeback duration %u TU (%u ms)\n",
1469 sdata->dev->name, tu, ms); 1528 sdata->name, tu, ms);
1470 wk->timeout = jiffies + msecs_to_jiffies(ms); 1529 wk->timeout = jiffies + msecs_to_jiffies(ms);
1471 if (ms > IEEE80211_ASSOC_TIMEOUT) 1530 if (ms > IEEE80211_ASSOC_TIMEOUT)
1472 run_again(ifmgd, jiffies + msecs_to_jiffies(ms)); 1531 run_again(ifmgd, jiffies + msecs_to_jiffies(ms));
@@ -1475,49 +1534,37 @@ ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
1475 1534
1476 if (status_code != WLAN_STATUS_SUCCESS) { 1535 if (status_code != WLAN_STATUS_SUCCESS) {
1477 printk(KERN_DEBUG "%s: AP denied association (code=%d)\n", 1536 printk(KERN_DEBUG "%s: AP denied association (code=%d)\n",
1478 sdata->dev->name, status_code); 1537 sdata->name, status_code);
1479 wk->state = IEEE80211_MGD_STATE_IDLE; 1538 wk->state = IEEE80211_MGD_STATE_IDLE;
1480 return RX_MGMT_CFG80211_ASSOC; 1539 return RX_MGMT_CFG80211_ASSOC;
1481 } 1540 }
1482 1541
1483 if ((aid & (BIT(15) | BIT(14))) != (BIT(15) | BIT(14))) 1542 if ((aid & (BIT(15) | BIT(14))) != (BIT(15) | BIT(14)))
1484 printk(KERN_DEBUG "%s: invalid aid value %d; bits 15:14 not " 1543 printk(KERN_DEBUG "%s: invalid aid value %d; bits 15:14 not "
1485 "set\n", sdata->dev->name, aid); 1544 "set\n", sdata->name, aid);
1486 aid &= ~(BIT(15) | BIT(14)); 1545 aid &= ~(BIT(15) | BIT(14));
1487 1546
1488 if (!elems.supp_rates) { 1547 if (!elems.supp_rates) {
1489 printk(KERN_DEBUG "%s: no SuppRates element in AssocResp\n", 1548 printk(KERN_DEBUG "%s: no SuppRates element in AssocResp\n",
1490 sdata->dev->name); 1549 sdata->name);
1491 return RX_MGMT_NONE; 1550 return RX_MGMT_NONE;
1492 } 1551 }
1493 1552
1494 printk(KERN_DEBUG "%s: associated\n", sdata->dev->name); 1553 printk(KERN_DEBUG "%s: associated\n", sdata->name);
1495 ifmgd->aid = aid; 1554 ifmgd->aid = aid;
1496 1555
1497 rcu_read_lock(); 1556 sta = sta_info_alloc(sdata, wk->bss->cbss.bssid, GFP_KERNEL);
1498
1499 /* Add STA entry for the AP */
1500 sta = sta_info_get(local, wk->bss->cbss.bssid);
1501 if (!sta) { 1557 if (!sta) {
1502 newsta = true; 1558 printk(KERN_DEBUG "%s: failed to alloc STA entry for"
1503 1559 " the AP\n", sdata->name);
1504 rcu_read_unlock(); 1560 return RX_MGMT_CFG80211_ASSOC_ERROR;
1505
1506 sta = sta_info_alloc(sdata, wk->bss->cbss.bssid, GFP_KERNEL);
1507 if (!sta) {
1508 printk(KERN_DEBUG "%s: failed to alloc STA entry for"
1509 " the AP\n", sdata->dev->name);
1510 return RX_MGMT_NONE;
1511 }
1512
1513 set_sta_flags(sta, WLAN_STA_AUTH | WLAN_STA_ASSOC |
1514 WLAN_STA_ASSOC_AP);
1515 if (!(ifmgd->flags & IEEE80211_STA_CONTROL_PORT))
1516 set_sta_flags(sta, WLAN_STA_AUTHORIZED);
1517
1518 rcu_read_lock();
1519 } 1561 }
1520 1562
1563 set_sta_flags(sta, WLAN_STA_AUTH | WLAN_STA_ASSOC |
1564 WLAN_STA_ASSOC_AP);
1565 if (!(ifmgd->flags & IEEE80211_STA_CONTROL_PORT))
1566 set_sta_flags(sta, WLAN_STA_AUTHORIZED);
1567
1521 rates = 0; 1568 rates = 0;
1522 basic_rates = 0; 1569 basic_rates = 0;
1523 sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; 1570 sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
@@ -1580,18 +1627,14 @@ ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
1580 if (elems.wmm_param) 1627 if (elems.wmm_param)
1581 set_sta_flags(sta, WLAN_STA_WME); 1628 set_sta_flags(sta, WLAN_STA_WME);
1582 1629
1583 if (newsta) { 1630 err = sta_info_insert(sta);
1584 int err = sta_info_insert(sta); 1631 sta = NULL;
1585 if (err) { 1632 if (err) {
1586 printk(KERN_DEBUG "%s: failed to insert STA entry for" 1633 printk(KERN_DEBUG "%s: failed to insert STA entry for"
1587 " the AP (error %d)\n", sdata->dev->name, err); 1634 " the AP (error %d)\n", sdata->name, err);
1588 rcu_read_unlock(); 1635 return RX_MGMT_CFG80211_ASSOC_ERROR;
1589 return RX_MGMT_NONE;
1590 }
1591 } 1636 }
1592 1637
1593 rcu_read_unlock();
1594
1595 if (elems.wmm_param) 1638 if (elems.wmm_param)
1596 ieee80211_sta_wmm_params(local, ifmgd, elems.wmm_param, 1639 ieee80211_sta_wmm_params(local, ifmgd, elems.wmm_param,
1597 elems.wmm_param_len); 1640 elems.wmm_param_len);
@@ -1679,7 +1722,7 @@ static void ieee80211_rx_mgmt_probe_resp(struct ieee80211_sub_if_data *sdata,
1679 1722
1680 ASSERT_MGD_MTX(ifmgd); 1723 ASSERT_MGD_MTX(ifmgd);
1681 1724
1682 if (memcmp(mgmt->da, sdata->dev->dev_addr, ETH_ALEN)) 1725 if (memcmp(mgmt->da, sdata->vif.addr, ETH_ALEN))
1683 return; /* ignore ProbeResp to foreign address */ 1726 return; /* ignore ProbeResp to foreign address */
1684 1727
1685 baselen = (u8 *) mgmt->u.probe_resp.variable - (u8 *) mgmt; 1728 baselen = (u8 *) mgmt->u.probe_resp.variable - (u8 *) mgmt;
@@ -1694,7 +1737,7 @@ static void ieee80211_rx_mgmt_probe_resp(struct ieee80211_sub_if_data *sdata,
1694 /* direct probe may be part of the association flow */ 1737 /* direct probe may be part of the association flow */
1695 if (wk && wk->state == IEEE80211_MGD_STATE_PROBE) { 1738 if (wk && wk->state == IEEE80211_MGD_STATE_PROBE) {
1696 printk(KERN_DEBUG "%s: direct probe responded\n", 1739 printk(KERN_DEBUG "%s: direct probe responded\n",
1697 sdata->dev->name); 1740 sdata->name);
1698 wk->tries = 0; 1741 wk->tries = 0;
1699 wk->state = IEEE80211_MGD_STATE_AUTH; 1742 wk->state = IEEE80211_MGD_STATE_AUTH;
1700 WARN_ON(ieee80211_authenticate(sdata, wk) != RX_MGMT_NONE); 1743 WARN_ON(ieee80211_authenticate(sdata, wk) != RX_MGMT_NONE);
@@ -1787,7 +1830,7 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
1787#ifdef CONFIG_MAC80211_VERBOSE_DEBUG 1830#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
1788 if (net_ratelimit()) { 1831 if (net_ratelimit()) {
1789 printk(KERN_DEBUG "%s: cancelling probereq poll due " 1832 printk(KERN_DEBUG "%s: cancelling probereq poll due "
1790 "to a received beacon\n", sdata->dev->name); 1833 "to a received beacon\n", sdata->name);
1791 } 1834 }
1792#endif 1835#endif
1793 ifmgd->flags &= ~IEEE80211_STA_BEACON_POLL; 1836 ifmgd->flags &= ~IEEE80211_STA_BEACON_POLL;
@@ -1865,7 +1908,7 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
1865 1908
1866 rcu_read_lock(); 1909 rcu_read_lock();
1867 1910
1868 sta = sta_info_get(local, bssid); 1911 sta = sta_info_get(sdata, bssid);
1869 if (WARN_ON(!sta)) { 1912 if (WARN_ON(!sta)) {
1870 rcu_read_unlock(); 1913 rcu_read_unlock();
1871 return; 1914 return;
@@ -2036,6 +2079,10 @@ static void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
2036 case RX_MGMT_CFG80211_DEAUTH: 2079 case RX_MGMT_CFG80211_DEAUTH:
2037 cfg80211_send_deauth(sdata->dev, (u8 *)mgmt, skb->len); 2080 cfg80211_send_deauth(sdata->dev, (u8 *)mgmt, skb->len);
2038 break; 2081 break;
2082 case RX_MGMT_CFG80211_ASSOC_ERROR:
2083 /* an internal error -- pretend timeout for now */
2084 cfg80211_send_assoc_timeout(sdata->dev, mgmt->bssid);
2085 break;
2039 default: 2086 default:
2040 WARN(1, "unexpected: %d", rma); 2087 WARN(1, "unexpected: %d", rma);
2041 } 2088 }
@@ -2336,6 +2383,11 @@ void ieee80211_sta_setup_sdata(struct ieee80211_sub_if_data *sdata)
2336 ifmgd->flags |= IEEE80211_STA_WMM_ENABLED; 2383 ifmgd->flags |= IEEE80211_STA_WMM_ENABLED;
2337 2384
2338 mutex_init(&ifmgd->mtx); 2385 mutex_init(&ifmgd->mtx);
2386
2387 if (sdata->local->hw.flags & IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS)
2388 ifmgd->req_smps = IEEE80211_SMPS_AUTOMATIC;
2389 else
2390 ifmgd->req_smps = IEEE80211_SMPS_OFF;
2339} 2391}
2340 2392
2341/* scan finished notification */ 2393/* scan finished notification */
@@ -2563,7 +2615,7 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata,
2563 mutex_unlock(&ifmgd->mtx); 2615 mutex_unlock(&ifmgd->mtx);
2564 2616
2565 printk(KERN_DEBUG "%s: deauthenticating from %pM by local choice (reason=%d)\n", 2617 printk(KERN_DEBUG "%s: deauthenticating from %pM by local choice (reason=%d)\n",
2566 sdata->dev->name, bssid, req->reason_code); 2618 sdata->name, bssid, req->reason_code);
2567 2619
2568 ieee80211_send_deauth_disassoc(sdata, bssid, 2620 ieee80211_send_deauth_disassoc(sdata, bssid,
2569 IEEE80211_STYPE_DEAUTH, req->reason_code, 2621 IEEE80211_STYPE_DEAUTH, req->reason_code,
@@ -2594,7 +2646,7 @@ int ieee80211_mgd_disassoc(struct ieee80211_sub_if_data *sdata,
2594 } 2646 }
2595 2647
2596 printk(KERN_DEBUG "%s: disassociating from %pM by local choice (reason=%d)\n", 2648 printk(KERN_DEBUG "%s: disassociating from %pM by local choice (reason=%d)\n",
2597 sdata->dev->name, req->bss->bssid, req->reason_code); 2649 sdata->name, req->bss->bssid, req->reason_code);
2598 2650
2599 ieee80211_set_disassoc(sdata, false); 2651 ieee80211_set_disassoc(sdata, false);
2600 2652
diff --git a/net/mac80211/pm.c b/net/mac80211/pm.c
index e535f1c988fe..05e161c3cbc5 100644
--- a/net/mac80211/pm.c
+++ b/net/mac80211/pm.c
@@ -65,7 +65,7 @@ int __ieee80211_suspend(struct ieee80211_hw *hw)
65 struct ieee80211_sub_if_data, 65 struct ieee80211_sub_if_data,
66 u.ap); 66 u.ap);
67 67
68 drv_sta_notify(local, &sdata->vif, STA_NOTIFY_REMOVE, 68 drv_sta_notify(local, sdata, STA_NOTIFY_REMOVE,
69 &sta->sta); 69 &sta->sta);
70 } 70 }
71 71
@@ -102,7 +102,7 @@ int __ieee80211_suspend(struct ieee80211_hw *hw)
102 102
103 conf.vif = &sdata->vif; 103 conf.vif = &sdata->vif;
104 conf.type = sdata->vif.type; 104 conf.type = sdata->vif.type;
105 conf.mac_addr = sdata->dev->dev_addr; 105 conf.mac_addr = sdata->vif.addr;
106 drv_remove_interface(local, &conf); 106 drv_remove_interface(local, &conf);
107 } 107 }
108 108
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 9f2807aeaf52..6cbf1a7b3157 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -283,15 +283,15 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb,
283 skb->protocol = htons(ETH_P_802_2); 283 skb->protocol = htons(ETH_P_802_2);
284 284
285 list_for_each_entry_rcu(sdata, &local->interfaces, list) { 285 list_for_each_entry_rcu(sdata, &local->interfaces, list) {
286 if (!netif_running(sdata->dev))
287 continue;
288
289 if (sdata->vif.type != NL80211_IFTYPE_MONITOR) 286 if (sdata->vif.type != NL80211_IFTYPE_MONITOR)
290 continue; 287 continue;
291 288
292 if (sdata->u.mntr_flags & MONITOR_FLAG_COOK_FRAMES) 289 if (sdata->u.mntr_flags & MONITOR_FLAG_COOK_FRAMES)
293 continue; 290 continue;
294 291
292 if (!netif_running(sdata->dev))
293 continue;
294
295 if (prev_dev) { 295 if (prev_dev) {
296 skb2 = skb_clone(skb, GFP_ATOMIC); 296 skb2 = skb_clone(skb, GFP_ATOMIC);
297 if (skb2) { 297 if (skb2) {
@@ -361,7 +361,9 @@ static void ieee80211_parse_qos(struct ieee80211_rx_data *rx)
361 * boundary. In the case of regular frames, this simply means aligning the 361 * boundary. In the case of regular frames, this simply means aligning the
362 * payload to a four-byte boundary (because either the IP header is directly 362 * payload to a four-byte boundary (because either the IP header is directly
363 * contained, or IV/RFC1042 headers that have a length divisible by four are 363 * contained, or IV/RFC1042 headers that have a length divisible by four are
364 * in front of it). 364 * in front of it). If the payload data is not properly aligned and the
365 * architecture doesn't support efficient unaligned operations, mac80211
366 * will align the data.
365 * 367 *
366 * With A-MSDU frames, however, the payload data address must yield two modulo 368 * With A-MSDU frames, however, the payload data address must yield two modulo
367 * four because there are 14-byte 802.3 headers within the A-MSDU frames that 369 * four because there are 14-byte 802.3 headers within the A-MSDU frames that
@@ -375,25 +377,10 @@ static void ieee80211_parse_qos(struct ieee80211_rx_data *rx)
375 */ 377 */
376static void ieee80211_verify_alignment(struct ieee80211_rx_data *rx) 378static void ieee80211_verify_alignment(struct ieee80211_rx_data *rx)
377{ 379{
378 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data; 380#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
379 int hdrlen; 381 WARN_ONCE((unsigned long)rx->skb->data & 1,
380 382 "unaligned packet at 0x%p\n", rx->skb->data);
381#ifndef CONFIG_MAC80211_DEBUG_PACKET_ALIGNMENT
382 return;
383#endif 383#endif
384
385 if (WARN_ONCE((unsigned long)rx->skb->data & 1,
386 "unaligned packet at 0x%p\n", rx->skb->data))
387 return;
388
389 if (!ieee80211_is_data_present(hdr->frame_control))
390 return;
391
392 hdrlen = ieee80211_hdrlen(hdr->frame_control);
393 if (rx->flags & IEEE80211_RX_AMSDU)
394 hdrlen += ETH_HLEN;
395 WARN_ONCE(((unsigned long)(rx->skb->data + hdrlen)) & 3,
396 "unaligned IP payload at 0x%p\n", rx->skb->data + hdrlen);
397} 384}
398 385
399 386
@@ -476,7 +463,7 @@ ieee80211_rx_mesh_check(struct ieee80211_rx_data *rx)
476{ 463{
477 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data; 464 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data;
478 unsigned int hdrlen = ieee80211_hdrlen(hdr->frame_control); 465 unsigned int hdrlen = ieee80211_hdrlen(hdr->frame_control);
479 char *dev_addr = rx->sdata->dev->dev_addr; 466 char *dev_addr = rx->sdata->vif.addr;
480 467
481 if (ieee80211_is_data(hdr->frame_control)) { 468 if (ieee80211_is_data(hdr->frame_control)) {
482 if (is_multicast_ether_addr(hdr->addr1)) { 469 if (is_multicast_ether_addr(hdr->addr1)) {
@@ -1021,10 +1008,10 @@ static void ap_sta_ps_start(struct sta_info *sta)
1021 1008
1022 atomic_inc(&sdata->bss->num_sta_ps); 1009 atomic_inc(&sdata->bss->num_sta_ps);
1023 set_sta_flags(sta, WLAN_STA_PS_STA); 1010 set_sta_flags(sta, WLAN_STA_PS_STA);
1024 drv_sta_notify(local, &sdata->vif, STA_NOTIFY_SLEEP, &sta->sta); 1011 drv_sta_notify(local, sdata, STA_NOTIFY_SLEEP, &sta->sta);
1025#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG 1012#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG
1026 printk(KERN_DEBUG "%s: STA %pM aid %d enters power save mode\n", 1013 printk(KERN_DEBUG "%s: STA %pM aid %d enters power save mode\n",
1027 sdata->dev->name, sta->sta.addr, sta->sta.aid); 1014 sdata->name, sta->sta.addr, sta->sta.aid);
1028#endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ 1015#endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */
1029} 1016}
1030 1017
@@ -1038,13 +1025,13 @@ static void ap_sta_ps_end(struct sta_info *sta)
1038 1025
1039#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG 1026#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG
1040 printk(KERN_DEBUG "%s: STA %pM aid %d exits power save mode\n", 1027 printk(KERN_DEBUG "%s: STA %pM aid %d exits power save mode\n",
1041 sdata->dev->name, sta->sta.addr, sta->sta.aid); 1028 sdata->name, sta->sta.addr, sta->sta.aid);
1042#endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ 1029#endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */
1043 1030
1044 if (test_sta_flags(sta, WLAN_STA_PS_DRIVER)) { 1031 if (test_sta_flags(sta, WLAN_STA_PS_DRIVER)) {
1045#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG 1032#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG
1046 printk(KERN_DEBUG "%s: STA %pM aid %d driver-ps-blocked\n", 1033 printk(KERN_DEBUG "%s: STA %pM aid %d driver-ps-blocked\n",
1047 sdata->dev->name, sta->sta.addr, sta->sta.aid); 1034 sdata->name, sta->sta.addr, sta->sta.aid);
1048#endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ 1035#endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */
1049 return; 1036 return;
1050 } 1037 }
@@ -1156,7 +1143,7 @@ ieee80211_reassemble_add(struct ieee80211_sub_if_data *sdata,
1156 printk(KERN_DEBUG "%s: RX reassembly removed oldest " 1143 printk(KERN_DEBUG "%s: RX reassembly removed oldest "
1157 "fragment entry (idx=%d age=%lu seq=%d last_frag=%d " 1144 "fragment entry (idx=%d age=%lu seq=%d last_frag=%d "
1158 "addr1=%pM addr2=%pM\n", 1145 "addr1=%pM addr2=%pM\n",
1159 sdata->dev->name, idx, 1146 sdata->name, idx,
1160 jiffies - entry->first_frag_time, entry->seq, 1147 jiffies - entry->first_frag_time, entry->seq,
1161 entry->last_frag, hdr->addr1, hdr->addr2); 1148 entry->last_frag, hdr->addr1, hdr->addr2);
1162#endif 1149#endif
@@ -1424,7 +1411,6 @@ static int
1424__ieee80211_data_to_8023(struct ieee80211_rx_data *rx) 1411__ieee80211_data_to_8023(struct ieee80211_rx_data *rx)
1425{ 1412{
1426 struct ieee80211_sub_if_data *sdata = rx->sdata; 1413 struct ieee80211_sub_if_data *sdata = rx->sdata;
1427 struct net_device *dev = sdata->dev;
1428 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data; 1414 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data;
1429 1415
1430 if (ieee80211_has_a4(hdr->frame_control) && 1416 if (ieee80211_has_a4(hdr->frame_control) &&
@@ -1436,7 +1422,7 @@ __ieee80211_data_to_8023(struct ieee80211_rx_data *rx)
1436 (sdata->vif.type == NL80211_IFTYPE_STATION && sdata->u.mgd.use_4addr))) 1422 (sdata->vif.type == NL80211_IFTYPE_STATION && sdata->u.mgd.use_4addr)))
1437 return -1; 1423 return -1;
1438 1424
1439 return ieee80211_data_to_8023(rx->skb, dev->dev_addr, sdata->vif.type); 1425 return ieee80211_data_to_8023(rx->skb, sdata->vif.addr, sdata->vif.type);
1440} 1426}
1441 1427
1442/* 1428/*
@@ -1453,7 +1439,7 @@ static bool ieee80211_frame_allowed(struct ieee80211_rx_data *rx, __le16 fc)
1453 * of whether the frame was encrypted or not. 1439 * of whether the frame was encrypted or not.
1454 */ 1440 */
1455 if (ehdr->h_proto == htons(ETH_P_PAE) && 1441 if (ehdr->h_proto == htons(ETH_P_PAE) &&
1456 (compare_ether_addr(ehdr->h_dest, rx->sdata->dev->dev_addr) == 0 || 1442 (compare_ether_addr(ehdr->h_dest, rx->sdata->vif.addr) == 0 ||
1457 compare_ether_addr(ehdr->h_dest, pae_group_addr) == 0)) 1443 compare_ether_addr(ehdr->h_dest, pae_group_addr) == 0))
1458 return true; 1444 return true;
1459 1445
@@ -1472,7 +1458,6 @@ ieee80211_deliver_skb(struct ieee80211_rx_data *rx)
1472{ 1458{
1473 struct ieee80211_sub_if_data *sdata = rx->sdata; 1459 struct ieee80211_sub_if_data *sdata = rx->sdata;
1474 struct net_device *dev = sdata->dev; 1460 struct net_device *dev = sdata->dev;
1475 struct ieee80211_local *local = rx->local;
1476 struct sk_buff *skb, *xmit_skb; 1461 struct sk_buff *skb, *xmit_skb;
1477 struct ethhdr *ehdr = (struct ethhdr *) rx->skb->data; 1462 struct ethhdr *ehdr = (struct ethhdr *) rx->skb->data;
1478 struct sta_info *dsta; 1463 struct sta_info *dsta;
@@ -1495,8 +1480,8 @@ ieee80211_deliver_skb(struct ieee80211_rx_data *rx)
1495 printk(KERN_DEBUG "%s: failed to clone " 1480 printk(KERN_DEBUG "%s: failed to clone "
1496 "multicast frame\n", dev->name); 1481 "multicast frame\n", dev->name);
1497 } else { 1482 } else {
1498 dsta = sta_info_get(local, skb->data); 1483 dsta = sta_info_get(sdata, skb->data);
1499 if (dsta && dsta->sdata->dev == dev) { 1484 if (dsta) {
1500 /* 1485 /*
1501 * The destination station is associated to 1486 * The destination station is associated to
1502 * this AP (in this VLAN), so send the frame 1487 * this AP (in this VLAN), so send the frame
@@ -1512,7 +1497,7 @@ ieee80211_deliver_skb(struct ieee80211_rx_data *rx)
1512 if (skb) { 1497 if (skb) {
1513 int align __maybe_unused; 1498 int align __maybe_unused;
1514 1499
1515#if defined(CONFIG_MAC80211_DEBUG_PACKET_ALIGNMENT) || !defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) 1500#ifndef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS
1516 /* 1501 /*
1517 * 'align' will only take the values 0 or 2 here 1502 * 'align' will only take the values 0 or 2 here
1518 * since all frames are required to be aligned 1503 * since all frames are required to be aligned
@@ -1556,16 +1541,10 @@ static ieee80211_rx_result debug_noinline
1556ieee80211_rx_h_amsdu(struct ieee80211_rx_data *rx) 1541ieee80211_rx_h_amsdu(struct ieee80211_rx_data *rx)
1557{ 1542{
1558 struct net_device *dev = rx->sdata->dev; 1543 struct net_device *dev = rx->sdata->dev;
1559 struct ieee80211_local *local = rx->local; 1544 struct sk_buff *skb = rx->skb;
1560 u16 ethertype;
1561 u8 *payload;
1562 struct sk_buff *skb = rx->skb, *frame = NULL;
1563 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; 1545 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
1564 __le16 fc = hdr->frame_control; 1546 __le16 fc = hdr->frame_control;
1565 const struct ethhdr *eth; 1547 struct sk_buff_head frame_list;
1566 int remaining, err;
1567 u8 dst[ETH_ALEN];
1568 u8 src[ETH_ALEN];
1569 1548
1570 if (unlikely(!ieee80211_is_data(fc))) 1549 if (unlikely(!ieee80211_is_data(fc)))
1571 return RX_CONTINUE; 1550 return RX_CONTINUE;
@@ -1576,94 +1555,34 @@ ieee80211_rx_h_amsdu(struct ieee80211_rx_data *rx)
1576 if (!(rx->flags & IEEE80211_RX_AMSDU)) 1555 if (!(rx->flags & IEEE80211_RX_AMSDU))
1577 return RX_CONTINUE; 1556 return RX_CONTINUE;
1578 1557
1579 err = __ieee80211_data_to_8023(rx); 1558 if (ieee80211_has_a4(hdr->frame_control) &&
1580 if (unlikely(err)) 1559 rx->sdata->vif.type == NL80211_IFTYPE_AP_VLAN &&
1560 !rx->sdata->u.vlan.sta)
1581 return RX_DROP_UNUSABLE; 1561 return RX_DROP_UNUSABLE;
1582 1562
1583 skb->dev = dev; 1563 if (is_multicast_ether_addr(hdr->addr1) &&
1584 1564 ((rx->sdata->vif.type == NL80211_IFTYPE_AP_VLAN &&
1585 dev->stats.rx_packets++; 1565 rx->sdata->u.vlan.sta) ||
1586 dev->stats.rx_bytes += skb->len; 1566 (rx->sdata->vif.type == NL80211_IFTYPE_STATION &&
1587 1567 rx->sdata->u.mgd.use_4addr)))
1588 /* skip the wrapping header */
1589 eth = (struct ethhdr *) skb_pull(skb, sizeof(struct ethhdr));
1590 if (!eth)
1591 return RX_DROP_UNUSABLE; 1568 return RX_DROP_UNUSABLE;
1592 1569
1593 while (skb != frame) { 1570 skb->dev = dev;
1594 u8 padding; 1571 __skb_queue_head_init(&frame_list);
1595 __be16 len = eth->h_proto;
1596 unsigned int subframe_len = sizeof(struct ethhdr) + ntohs(len);
1597
1598 remaining = skb->len;
1599 memcpy(dst, eth->h_dest, ETH_ALEN);
1600 memcpy(src, eth->h_source, ETH_ALEN);
1601
1602 padding = ((4 - subframe_len) & 0x3);
1603 /* the last MSDU has no padding */
1604 if (subframe_len > remaining)
1605 return RX_DROP_UNUSABLE;
1606 1572
1607 skb_pull(skb, sizeof(struct ethhdr)); 1573 ieee80211_amsdu_to_8023s(skb, &frame_list, dev->dev_addr,
1608 /* if last subframe reuse skb */ 1574 rx->sdata->vif.type,
1609 if (remaining <= subframe_len + padding) 1575 rx->local->hw.extra_tx_headroom);
1610 frame = skb;
1611 else {
1612 /*
1613 * Allocate and reserve two bytes more for payload
1614 * alignment since sizeof(struct ethhdr) is 14.
1615 */
1616 frame = dev_alloc_skb(
1617 ALIGN(local->hw.extra_tx_headroom, 4) +
1618 subframe_len + 2);
1619
1620 if (frame == NULL)
1621 return RX_DROP_UNUSABLE;
1622
1623 skb_reserve(frame,
1624 ALIGN(local->hw.extra_tx_headroom, 4) +
1625 sizeof(struct ethhdr) + 2);
1626 memcpy(skb_put(frame, ntohs(len)), skb->data,
1627 ntohs(len));
1628
1629 eth = (struct ethhdr *) skb_pull(skb, ntohs(len) +
1630 padding);
1631 if (!eth) {
1632 dev_kfree_skb(frame);
1633 return RX_DROP_UNUSABLE;
1634 }
1635 }
1636 1576
1637 skb_reset_network_header(frame); 1577 while (!skb_queue_empty(&frame_list)) {
1638 frame->dev = dev; 1578 rx->skb = __skb_dequeue(&frame_list);
1639 frame->priority = skb->priority;
1640 rx->skb = frame;
1641
1642 payload = frame->data;
1643 ethertype = (payload[6] << 8) | payload[7];
1644
1645 if (likely((compare_ether_addr(payload, rfc1042_header) == 0 &&
1646 ethertype != ETH_P_AARP && ethertype != ETH_P_IPX) ||
1647 compare_ether_addr(payload,
1648 bridge_tunnel_header) == 0)) {
1649 /* remove RFC1042 or Bridge-Tunnel
1650 * encapsulation and replace EtherType */
1651 skb_pull(frame, 6);
1652 memcpy(skb_push(frame, ETH_ALEN), src, ETH_ALEN);
1653 memcpy(skb_push(frame, ETH_ALEN), dst, ETH_ALEN);
1654 } else {
1655 memcpy(skb_push(frame, sizeof(__be16)),
1656 &len, sizeof(__be16));
1657 memcpy(skb_push(frame, ETH_ALEN), src, ETH_ALEN);
1658 memcpy(skb_push(frame, ETH_ALEN), dst, ETH_ALEN);
1659 }
1660 1579
1661 if (!ieee80211_frame_allowed(rx, fc)) { 1580 if (!ieee80211_frame_allowed(rx, fc)) {
1662 if (skb == frame) /* last frame */ 1581 dev_kfree_skb(rx->skb);
1663 return RX_DROP_UNUSABLE;
1664 dev_kfree_skb(frame);
1665 continue; 1582 continue;
1666 } 1583 }
1584 dev->stats.rx_packets++;
1585 dev->stats.rx_bytes += rx->skb->len;
1667 1586
1668 ieee80211_deliver_skb(rx); 1587 ieee80211_deliver_skb(rx);
1669 } 1588 }
@@ -1721,7 +1640,7 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
1721 1640
1722 /* Frame has reached destination. Don't forward */ 1641 /* Frame has reached destination. Don't forward */
1723 if (!is_multicast_ether_addr(hdr->addr1) && 1642 if (!is_multicast_ether_addr(hdr->addr1) &&
1724 compare_ether_addr(sdata->dev->dev_addr, hdr->addr3) == 0) 1643 compare_ether_addr(sdata->vif.addr, hdr->addr3) == 0)
1725 return RX_CONTINUE; 1644 return RX_CONTINUE;
1726 1645
1727 mesh_hdr->ttl--; 1646 mesh_hdr->ttl--;
@@ -1738,10 +1657,10 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
1738 1657
1739 if (!fwd_skb && net_ratelimit()) 1658 if (!fwd_skb && net_ratelimit())
1740 printk(KERN_DEBUG "%s: failed to clone mesh frame\n", 1659 printk(KERN_DEBUG "%s: failed to clone mesh frame\n",
1741 sdata->dev->name); 1660 sdata->name);
1742 1661
1743 fwd_hdr = (struct ieee80211_hdr *) fwd_skb->data; 1662 fwd_hdr = (struct ieee80211_hdr *) fwd_skb->data;
1744 memcpy(fwd_hdr->addr2, sdata->dev->dev_addr, ETH_ALEN); 1663 memcpy(fwd_hdr->addr2, sdata->vif.addr, ETH_ALEN);
1745 info = IEEE80211_SKB_CB(fwd_skb); 1664 info = IEEE80211_SKB_CB(fwd_skb);
1746 memset(info, 0, sizeof(*info)); 1665 memset(info, 0, sizeof(*info));
1747 info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING; 1666 info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING;
@@ -1870,7 +1789,7 @@ static void ieee80211_process_sa_query_req(struct ieee80211_sub_if_data *sdata,
1870 struct sk_buff *skb; 1789 struct sk_buff *skb;
1871 struct ieee80211_mgmt *resp; 1790 struct ieee80211_mgmt *resp;
1872 1791
1873 if (compare_ether_addr(mgmt->da, sdata->dev->dev_addr) != 0) { 1792 if (compare_ether_addr(mgmt->da, sdata->vif.addr) != 0) {
1874 /* Not to own unicast address */ 1793 /* Not to own unicast address */
1875 return; 1794 return;
1876 } 1795 }
@@ -1894,7 +1813,7 @@ static void ieee80211_process_sa_query_req(struct ieee80211_sub_if_data *sdata,
1894 resp = (struct ieee80211_mgmt *) skb_put(skb, 24); 1813 resp = (struct ieee80211_mgmt *) skb_put(skb, 24);
1895 memset(resp, 0, 24); 1814 memset(resp, 0, 24);
1896 memcpy(resp->da, mgmt->sa, ETH_ALEN); 1815 memcpy(resp->da, mgmt->sa, ETH_ALEN);
1897 memcpy(resp->sa, sdata->dev->dev_addr, ETH_ALEN); 1816 memcpy(resp->sa, sdata->vif.addr, ETH_ALEN);
1898 memcpy(resp->bssid, sdata->u.mgd.bssid, ETH_ALEN); 1817 memcpy(resp->bssid, sdata->u.mgd.bssid, ETH_ALEN);
1899 resp->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | 1818 resp->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
1900 IEEE80211_STYPE_ACTION); 1819 IEEE80211_STYPE_ACTION);
@@ -2274,7 +2193,7 @@ static int prepare_for_handlers(struct ieee80211_sub_if_data *sdata,
2274 if (!bssid && !sdata->u.mgd.use_4addr) 2193 if (!bssid && !sdata->u.mgd.use_4addr)
2275 return 0; 2194 return 0;
2276 if (!multicast && 2195 if (!multicast &&
2277 compare_ether_addr(sdata->dev->dev_addr, hdr->addr1) != 0) { 2196 compare_ether_addr(sdata->vif.addr, hdr->addr1) != 0) {
2278 if (!(sdata->dev->flags & IFF_PROMISC)) 2197 if (!(sdata->dev->flags & IFF_PROMISC))
2279 return 0; 2198 return 0;
2280 rx->flags &= ~IEEE80211_RX_RA_MATCH; 2199 rx->flags &= ~IEEE80211_RX_RA_MATCH;
@@ -2291,7 +2210,7 @@ static int prepare_for_handlers(struct ieee80211_sub_if_data *sdata,
2291 return 0; 2210 return 0;
2292 rx->flags &= ~IEEE80211_RX_RA_MATCH; 2211 rx->flags &= ~IEEE80211_RX_RA_MATCH;
2293 } else if (!multicast && 2212 } else if (!multicast &&
2294 compare_ether_addr(sdata->dev->dev_addr, 2213 compare_ether_addr(sdata->vif.addr,
2295 hdr->addr1) != 0) { 2214 hdr->addr1) != 0) {
2296 if (!(sdata->dev->flags & IFF_PROMISC)) 2215 if (!(sdata->dev->flags & IFF_PROMISC))
2297 return 0; 2216 return 0;
@@ -2308,7 +2227,7 @@ static int prepare_for_handlers(struct ieee80211_sub_if_data *sdata,
2308 break; 2227 break;
2309 case NL80211_IFTYPE_MESH_POINT: 2228 case NL80211_IFTYPE_MESH_POINT:
2310 if (!multicast && 2229 if (!multicast &&
2311 compare_ether_addr(sdata->dev->dev_addr, 2230 compare_ether_addr(sdata->vif.addr,
2312 hdr->addr1) != 0) { 2231 hdr->addr1) != 0) {
2313 if (!(sdata->dev->flags & IFF_PROMISC)) 2232 if (!(sdata->dev->flags & IFF_PROMISC))
2314 return 0; 2233 return 0;
@@ -2319,11 +2238,11 @@ static int prepare_for_handlers(struct ieee80211_sub_if_data *sdata,
2319 case NL80211_IFTYPE_AP_VLAN: 2238 case NL80211_IFTYPE_AP_VLAN:
2320 case NL80211_IFTYPE_AP: 2239 case NL80211_IFTYPE_AP:
2321 if (!bssid) { 2240 if (!bssid) {
2322 if (compare_ether_addr(sdata->dev->dev_addr, 2241 if (compare_ether_addr(sdata->vif.addr,
2323 hdr->addr1)) 2242 hdr->addr1))
2324 return 0; 2243 return 0;
2325 } else if (!ieee80211_bssid_match(bssid, 2244 } else if (!ieee80211_bssid_match(bssid,
2326 sdata->dev->dev_addr)) { 2245 sdata->vif.addr)) {
2327 if (!(rx->flags & IEEE80211_RX_IN_SCAN)) 2246 if (!(rx->flags & IEEE80211_RX_IN_SCAN))
2328 return 0; 2247 return 0;
2329 rx->flags &= ~IEEE80211_RX_RA_MATCH; 2248 rx->flags &= ~IEEE80211_RX_RA_MATCH;
@@ -2362,6 +2281,8 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
2362 int prepares; 2281 int prepares;
2363 struct ieee80211_sub_if_data *prev = NULL; 2282 struct ieee80211_sub_if_data *prev = NULL;
2364 struct sk_buff *skb_new; 2283 struct sk_buff *skb_new;
2284 struct sta_info *sta, *tmp;
2285 bool found_sta = false;
2365 2286
2366 hdr = (struct ieee80211_hdr *)skb->data; 2287 hdr = (struct ieee80211_hdr *)skb->data;
2367 memset(&rx, 0, sizeof(rx)); 2288 memset(&rx, 0, sizeof(rx));
@@ -2378,68 +2299,76 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
2378 ieee80211_parse_qos(&rx); 2299 ieee80211_parse_qos(&rx);
2379 ieee80211_verify_alignment(&rx); 2300 ieee80211_verify_alignment(&rx);
2380 2301
2381 rx.sta = sta_info_get(local, hdr->addr2); 2302 if (ieee80211_is_data(hdr->frame_control)) {
2382 if (rx.sta) 2303 for_each_sta_info(local, hdr->addr2, sta, tmp) {
2383 rx.sdata = rx.sta->sdata; 2304 rx.sta = sta;
2384 2305 found_sta = true;
2385 if (rx.sdata && ieee80211_is_data(hdr->frame_control)) { 2306 rx.sdata = sta->sdata;
2386 rx.flags |= IEEE80211_RX_RA_MATCH; 2307
2387 prepares = prepare_for_handlers(rx.sdata, &rx, hdr); 2308 rx.flags |= IEEE80211_RX_RA_MATCH;
2388 if (prepares) { 2309 prepares = prepare_for_handlers(rx.sdata, &rx, hdr);
2389 if (status->flag & RX_FLAG_MMIC_ERROR) { 2310 if (prepares) {
2390 if (rx.flags & IEEE80211_RX_RA_MATCH) 2311 if (status->flag & RX_FLAG_MMIC_ERROR) {
2391 ieee80211_rx_michael_mic_report(hdr, &rx); 2312 if (rx.flags & IEEE80211_RX_RA_MATCH)
2392 } else 2313 ieee80211_rx_michael_mic_report(hdr, &rx);
2393 prev = rx.sdata; 2314 } else
2315 prev = rx.sdata;
2316 }
2394 } 2317 }
2395 } else list_for_each_entry_rcu(sdata, &local->interfaces, list) { 2318 }
2396 if (!netif_running(sdata->dev)) 2319 if (!found_sta) {
2397 continue; 2320 list_for_each_entry_rcu(sdata, &local->interfaces, list) {
2321 if (!netif_running(sdata->dev))
2322 continue;
2398 2323
2399 if (sdata->vif.type == NL80211_IFTYPE_MONITOR || 2324 if (sdata->vif.type == NL80211_IFTYPE_MONITOR ||
2400 sdata->vif.type == NL80211_IFTYPE_AP_VLAN) 2325 sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
2401 continue; 2326 continue;
2402 2327
2403 rx.flags |= IEEE80211_RX_RA_MATCH; 2328 rx.sta = sta_info_get(sdata, hdr->addr2);
2404 prepares = prepare_for_handlers(sdata, &rx, hdr);
2405 2329
2406 if (!prepares) 2330 rx.flags |= IEEE80211_RX_RA_MATCH;
2407 continue; 2331 prepares = prepare_for_handlers(sdata, &rx, hdr);
2408 2332
2409 if (status->flag & RX_FLAG_MMIC_ERROR) { 2333 if (!prepares)
2410 rx.sdata = sdata; 2334 continue;
2411 if (rx.flags & IEEE80211_RX_RA_MATCH)
2412 ieee80211_rx_michael_mic_report(hdr, &rx);
2413 continue;
2414 }
2415 2335
2416 /* 2336 if (status->flag & RX_FLAG_MMIC_ERROR) {
2417 * frame is destined for this interface, but if it's not 2337 rx.sdata = sdata;
2418 * also for the previous one we handle that after the 2338 if (rx.flags & IEEE80211_RX_RA_MATCH)
2419 * loop to avoid copying the SKB once too much 2339 ieee80211_rx_michael_mic_report(hdr,
2420 */ 2340 &rx);
2341 continue;
2342 }
2421 2343
2422 if (!prev) { 2344 /*
2423 prev = sdata; 2345 * frame is destined for this interface, but if it's
2424 continue; 2346 * not also for the previous one we handle that after
2425 } 2347 * the loop to avoid copying the SKB once too much
2348 */
2426 2349
2427 /* 2350 if (!prev) {
2428 * frame was destined for the previous interface 2351 prev = sdata;
2429 * so invoke RX handlers for it 2352 continue;
2430 */ 2353 }
2431 2354
2432 skb_new = skb_copy(skb, GFP_ATOMIC); 2355 /*
2433 if (!skb_new) { 2356 * frame was destined for the previous interface
2434 if (net_ratelimit()) 2357 * so invoke RX handlers for it
2435 printk(KERN_DEBUG "%s: failed to copy " 2358 */
2436 "multicast frame for %s\n", 2359
2437 wiphy_name(local->hw.wiphy), 2360 skb_new = skb_copy(skb, GFP_ATOMIC);
2438 prev->dev->name); 2361 if (!skb_new) {
2439 continue; 2362 if (net_ratelimit())
2363 printk(KERN_DEBUG "%s: failed to copy "
2364 "multicast frame for %s\n",
2365 wiphy_name(local->hw.wiphy),
2366 prev->name);
2367 continue;
2368 }
2369 ieee80211_invoke_rx_handlers(prev, &rx, skb_new, rate);
2370 prev = sdata;
2440 } 2371 }
2441 ieee80211_invoke_rx_handlers(prev, &rx, skb_new, rate);
2442 prev = sdata;
2443 } 2372 }
2444 if (prev) 2373 if (prev)
2445 ieee80211_invoke_rx_handlers(prev, &rx, skb, rate); 2374 ieee80211_invoke_rx_handlers(prev, &rx, skb, rate);
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index f1a4c7160300..66da0ab1d8fa 100644
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -147,7 +147,7 @@ ieee80211_scan_rx(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb)
147 presp = ieee80211_is_probe_resp(fc); 147 presp = ieee80211_is_probe_resp(fc);
148 if (presp) { 148 if (presp) {
149 /* ignore ProbeResp to foreign address */ 149 /* ignore ProbeResp to foreign address */
150 if (memcmp(mgmt->da, sdata->dev->dev_addr, ETH_ALEN)) 150 if (memcmp(mgmt->da, sdata->vif.addr, ETH_ALEN))
151 return RX_DROP_MONITOR; 151 return RX_DROP_MONITOR;
152 152
153 presp = true; 153 presp = true;
diff --git a/net/mac80211/spectmgmt.c b/net/mac80211/spectmgmt.c
index aa743a895cf9..7733f66ee2c4 100644
--- a/net/mac80211/spectmgmt.c
+++ b/net/mac80211/spectmgmt.c
@@ -35,7 +35,7 @@ static void ieee80211_send_refuse_measurement_request(struct ieee80211_sub_if_da
35 35
36 if (!skb) { 36 if (!skb) {
37 printk(KERN_ERR "%s: failed to allocate buffer for " 37 printk(KERN_ERR "%s: failed to allocate buffer for "
38 "measurement report frame\n", sdata->dev->name); 38 "measurement report frame\n", sdata->name);
39 return; 39 return;
40 } 40 }
41 41
@@ -43,7 +43,7 @@ static void ieee80211_send_refuse_measurement_request(struct ieee80211_sub_if_da
43 msr_report = (struct ieee80211_mgmt *)skb_put(skb, 24); 43 msr_report = (struct ieee80211_mgmt *)skb_put(skb, 24);
44 memset(msr_report, 0, 24); 44 memset(msr_report, 0, 24);
45 memcpy(msr_report->da, da, ETH_ALEN); 45 memcpy(msr_report->da, da, ETH_ALEN);
46 memcpy(msr_report->sa, sdata->dev->dev_addr, ETH_ALEN); 46 memcpy(msr_report->sa, sdata->vif.addr, ETH_ALEN);
47 memcpy(msr_report->bssid, bssid, ETH_ALEN); 47 memcpy(msr_report->bssid, bssid, ETH_ALEN);
48 msr_report->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | 48 msr_report->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
49 IEEE80211_STYPE_ACTION); 49 IEEE80211_STYPE_ACTION);
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index 71f370dd24bc..d1a77e79d7a9 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -103,13 +103,16 @@ static int sta_info_hash_del(struct ieee80211_local *local,
103} 103}
104 104
105/* protected by RCU */ 105/* protected by RCU */
106struct sta_info *sta_info_get(struct ieee80211_local *local, const u8 *addr) 106struct sta_info *sta_info_get(struct ieee80211_sub_if_data *sdata,
107 const u8 *addr)
107{ 108{
109 struct ieee80211_local *local = sdata->local;
108 struct sta_info *sta; 110 struct sta_info *sta;
109 111
110 sta = rcu_dereference(local->sta_hash[STA_HASH(addr)]); 112 sta = rcu_dereference(local->sta_hash[STA_HASH(addr)]);
111 while (sta) { 113 while (sta) {
112 if (memcmp(sta->sta.addr, addr, ETH_ALEN) == 0) 114 if (sta->sdata == sdata &&
115 memcmp(sta->sta.addr, addr, ETH_ALEN) == 0)
113 break; 116 break;
114 sta = rcu_dereference(sta->hnext); 117 sta = rcu_dereference(sta->hnext);
115 } 118 }
@@ -369,7 +372,7 @@ int sta_info_insert(struct sta_info *sta)
369 goto out_free; 372 goto out_free;
370 } 373 }
371 374
372 if (WARN_ON(compare_ether_addr(sta->sta.addr, sdata->dev->dev_addr) == 0 || 375 if (WARN_ON(compare_ether_addr(sta->sta.addr, sdata->vif.addr) == 0 ||
373 is_multicast_ether_addr(sta->sta.addr))) { 376 is_multicast_ether_addr(sta->sta.addr))) {
374 err = -EINVAL; 377 err = -EINVAL;
375 goto out_free; 378 goto out_free;
@@ -377,7 +380,7 @@ int sta_info_insert(struct sta_info *sta)
377 380
378 spin_lock_irqsave(&local->sta_lock, flags); 381 spin_lock_irqsave(&local->sta_lock, flags);
379 /* check if STA exists already */ 382 /* check if STA exists already */
380 if (sta_info_get(local, sta->sta.addr)) { 383 if (sta_info_get(sdata, sta->sta.addr)) {
381 spin_unlock_irqrestore(&local->sta_lock, flags); 384 spin_unlock_irqrestore(&local->sta_lock, flags);
382 err = -EEXIST; 385 err = -EEXIST;
383 goto out_free; 386 goto out_free;
@@ -394,7 +397,7 @@ int sta_info_insert(struct sta_info *sta)
394 struct ieee80211_sub_if_data, 397 struct ieee80211_sub_if_data,
395 u.ap); 398 u.ap);
396 399
397 drv_sta_notify(local, &sdata->vif, STA_NOTIFY_ADD, &sta->sta); 400 drv_sta_notify(local, sdata, STA_NOTIFY_ADD, &sta->sta);
398 sdata = sta->sdata; 401 sdata = sta->sdata;
399 } 402 }
400 403
@@ -534,7 +537,7 @@ static void __sta_info_unlink(struct sta_info **sta)
534 struct ieee80211_sub_if_data, 537 struct ieee80211_sub_if_data,
535 u.ap); 538 u.ap);
536 539
537 drv_sta_notify(local, &sdata->vif, STA_NOTIFY_REMOVE, 540 drv_sta_notify(local, sdata, STA_NOTIFY_REMOVE,
538 &(*sta)->sta); 541 &(*sta)->sta);
539 sdata = (*sta)->sdata; 542 sdata = (*sta)->sdata;
540 } 543 }
@@ -828,7 +831,7 @@ void ieee80211_sta_expire(struct ieee80211_sub_if_data *sdata,
828 if (time_after(jiffies, sta->last_rx + exp_time)) { 831 if (time_after(jiffies, sta->last_rx + exp_time)) {
829#ifdef CONFIG_MAC80211_IBSS_DEBUG 832#ifdef CONFIG_MAC80211_IBSS_DEBUG
830 printk(KERN_DEBUG "%s: expiring inactive STA %pM\n", 833 printk(KERN_DEBUG "%s: expiring inactive STA %pM\n",
831 sdata->dev->name, sta->sta.addr); 834 sdata->name, sta->sta.addr);
832#endif 835#endif
833 __sta_info_unlink(&sta); 836 __sta_info_unlink(&sta);
834 if (sta) 837 if (sta)
@@ -843,11 +846,12 @@ void ieee80211_sta_expire(struct ieee80211_sub_if_data *sdata,
843struct ieee80211_sta *ieee80211_find_sta_by_hw(struct ieee80211_hw *hw, 846struct ieee80211_sta *ieee80211_find_sta_by_hw(struct ieee80211_hw *hw,
844 const u8 *addr) 847 const u8 *addr)
845{ 848{
846 struct sta_info *sta = sta_info_get(hw_to_local(hw), addr); 849 struct sta_info *sta, *nxt;
847 850
848 if (!sta) 851 /* Just return a random station ... first in list ... */
849 return NULL; 852 for_each_sta_info(hw_to_local(hw), addr, sta, nxt)
850 return &sta->sta; 853 return &sta->sta;
854 return NULL;
851} 855}
852EXPORT_SYMBOL_GPL(ieee80211_find_sta_by_hw); 856EXPORT_SYMBOL_GPL(ieee80211_find_sta_by_hw);
853 857
@@ -872,7 +876,7 @@ void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta)
872 struct ieee80211_local *local = sdata->local; 876 struct ieee80211_local *local = sdata->local;
873 int sent, buffered; 877 int sent, buffered;
874 878
875 drv_sta_notify(local, &sdata->vif, STA_NOTIFY_AWAKE, &sta->sta); 879 drv_sta_notify(local, sdata, STA_NOTIFY_AWAKE, &sta->sta);
876 880
877 if (!skb_queue_empty(&sta->ps_tx_buf)) 881 if (!skb_queue_empty(&sta->ps_tx_buf))
878 sta_info_clear_tim_bit(sta); 882 sta_info_clear_tim_bit(sta);
@@ -885,7 +889,7 @@ void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta)
885 889
886#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG 890#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG
887 printk(KERN_DEBUG "%s: STA %pM aid %d sending %d filtered/%d PS frames " 891 printk(KERN_DEBUG "%s: STA %pM aid %d sending %d filtered/%d PS frames "
888 "since STA not sleeping anymore\n", sdata->dev->name, 892 "since STA not sleeping anymore\n", sdata->name,
889 sta->sta.addr, sta->sta.aid, sent - buffered, buffered); 893 sta->sta.addr, sta->sta.aid, sent - buffered, buffered);
890#endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ 894#endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */
891} 895}
@@ -944,7 +948,7 @@ void ieee80211_sta_ps_deliver_poll_response(struct sta_info *sta)
944 */ 948 */
945 printk(KERN_DEBUG "%s: STA %pM sent PS Poll even " 949 printk(KERN_DEBUG "%s: STA %pM sent PS Poll even "
946 "though there are no buffered frames for it\n", 950 "though there are no buffered frames for it\n",
947 sdata->dev->name, sta->sta.addr); 951 sdata->name, sta->sta.addr);
948#endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ 952#endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */
949 } 953 }
950} 954}
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h
index b4810f6aa94f..c8208236e896 100644
--- a/net/mac80211/sta_info.h
+++ b/net/mac80211/sta_info.h
@@ -403,9 +403,34 @@ static inline u32 get_sta_flags(struct sta_info *sta)
403#define STA_INFO_CLEANUP_INTERVAL (10 * HZ) 403#define STA_INFO_CLEANUP_INTERVAL (10 * HZ)
404 404
405/* 405/*
406 * Get a STA info, must have be under RCU read lock. 406 * Get a STA info, must be under RCU read lock.
407 */ 407 */
408struct sta_info *sta_info_get(struct ieee80211_local *local, const u8 *addr); 408struct sta_info *sta_info_get(struct ieee80211_sub_if_data *sdata,
409 const u8 *addr);
410
411static inline
412void for_each_sta_info_type_check(struct ieee80211_local *local,
413 const u8 *addr,
414 struct sta_info *sta,
415 struct sta_info *nxt)
416{
417}
418
419#define for_each_sta_info(local, _addr, sta, nxt) \
420 for ( /* initialise loop */ \
421 sta = rcu_dereference(local->sta_hash[STA_HASH(_addr)]),\
422 nxt = sta ? rcu_dereference(sta->hnext) : NULL; \
423 /* typecheck */ \
424 for_each_sta_info_type_check(local, (_addr), sta, nxt), \
425 /* continue condition */ \
426 sta; \
427 /* advance loop */ \
428 sta = nxt, \
429 nxt = sta ? rcu_dereference(sta->hnext) : NULL \
430 ) \
431 /* compare address and run code only if it matches */ \
432 if (memcmp(sta->sta.addr, (_addr), ETH_ALEN) == 0)
433
409/* 434/*
410 * Get STA info by index, BROKEN! 435 * Get STA info by index, BROKEN!
411 */ 436 */
diff --git a/net/mac80211/status.c b/net/mac80211/status.c
index d78f36c64c7b..0c0850d37dda 100644
--- a/net/mac80211/status.c
+++ b/net/mac80211/status.c
@@ -134,6 +134,40 @@ static void ieee80211_handle_filtered_frame(struct ieee80211_local *local,
134 dev_kfree_skb(skb); 134 dev_kfree_skb(skb);
135} 135}
136 136
137static void ieee80211_frame_acked(struct sta_info *sta, struct sk_buff *skb)
138{
139 struct ieee80211_mgmt *mgmt = (void *) skb->data;
140 struct ieee80211_local *local = sta->local;
141 struct ieee80211_sub_if_data *sdata = sta->sdata;
142
143 if (ieee80211_is_action(mgmt->frame_control) &&
144 sdata->vif.type == NL80211_IFTYPE_STATION &&
145 mgmt->u.action.category == WLAN_CATEGORY_HT &&
146 mgmt->u.action.u.ht_smps.action == WLAN_HT_ACTION_SMPS) {
147 /*
148 * This update looks racy, but isn't -- if we come
149 * here we've definitely got a station that we're
150 * talking to, and on a managed interface that can
151 * only be the AP. And the only other place updating
152 * this variable is before we're associated.
153 */
154 switch (mgmt->u.action.u.ht_smps.smps_control) {
155 case WLAN_HT_SMPS_CONTROL_DYNAMIC:
156 sta->sdata->u.mgd.ap_smps = IEEE80211_SMPS_DYNAMIC;
157 break;
158 case WLAN_HT_SMPS_CONTROL_STATIC:
159 sta->sdata->u.mgd.ap_smps = IEEE80211_SMPS_STATIC;
160 break;
161 case WLAN_HT_SMPS_CONTROL_DISABLED:
162 default: /* shouldn't happen since we don't send that */
163 sta->sdata->u.mgd.ap_smps = IEEE80211_SMPS_OFF;
164 break;
165 }
166
167 ieee80211_queue_work(&local->hw, &local->recalc_smps);
168 }
169}
170
137void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb) 171void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
138{ 172{
139 struct sk_buff *skb2; 173 struct sk_buff *skb2;
@@ -146,7 +180,7 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
146 struct ieee80211_tx_status_rtap_hdr *rthdr; 180 struct ieee80211_tx_status_rtap_hdr *rthdr;
147 struct ieee80211_sub_if_data *sdata; 181 struct ieee80211_sub_if_data *sdata;
148 struct net_device *prev_dev = NULL; 182 struct net_device *prev_dev = NULL;
149 struct sta_info *sta; 183 struct sta_info *sta, *tmp;
150 int retry_count = -1, i; 184 int retry_count = -1, i;
151 bool injected; 185 bool injected;
152 186
@@ -166,9 +200,11 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
166 200
167 sband = local->hw.wiphy->bands[info->band]; 201 sband = local->hw.wiphy->bands[info->band];
168 202
169 sta = sta_info_get(local, hdr->addr1); 203 for_each_sta_info(local, hdr->addr1, sta, tmp) {
204 /* skip wrong virtual interface */
205 if (memcmp(hdr->addr2, sta->sdata->vif.addr, ETH_ALEN))
206 continue;
170 207
171 if (sta) {
172 if (!(info->flags & IEEE80211_TX_STAT_ACK) && 208 if (!(info->flags & IEEE80211_TX_STAT_ACK) &&
173 test_sta_flags(sta, WLAN_STA_PS_STA)) { 209 test_sta_flags(sta, WLAN_STA_PS_STA)) {
174 /* 210 /*
@@ -208,6 +244,10 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
208 rate_control_tx_status(local, sband, sta, skb); 244 rate_control_tx_status(local, sband, sta, skb);
209 if (ieee80211_vif_is_mesh(&sta->sdata->vif)) 245 if (ieee80211_vif_is_mesh(&sta->sdata->vif))
210 ieee80211s_update_metric(local, sta, skb); 246 ieee80211s_update_metric(local, sta, skb);
247
248 if (!(info->flags & IEEE80211_TX_CTL_INJECTED) &&
249 (info->flags & IEEE80211_TX_STAT_ACK))
250 ieee80211_frame_acked(sta, skb);
211 } 251 }
212 252
213 rcu_read_unlock(); 253 rcu_read_unlock();
diff --git a/net/mac80211/tkip.c b/net/mac80211/tkip.c
index 4921d724b6c7..b73454a507f9 100644
--- a/net/mac80211/tkip.c
+++ b/net/mac80211/tkip.c
@@ -100,7 +100,7 @@ static void tkip_mixing_phase1(const u8 *tk, struct tkip_ctx *ctx,
100 p1k[3] += tkipS(p1k[2] ^ get_unaligned_le16(tk + 12 + j)); 100 p1k[3] += tkipS(p1k[2] ^ get_unaligned_le16(tk + 12 + j));
101 p1k[4] += tkipS(p1k[3] ^ get_unaligned_le16(tk + 0 + j)) + i; 101 p1k[4] += tkipS(p1k[3] ^ get_unaligned_le16(tk + 0 + j)) + i;
102 } 102 }
103 ctx->initialized = 1; 103 ctx->state = TKIP_STATE_PHASE1_DONE;
104} 104}
105 105
106static void tkip_mixing_phase2(const u8 *tk, struct tkip_ctx *ctx, 106static void tkip_mixing_phase2(const u8 *tk, struct tkip_ctx *ctx,
@@ -183,7 +183,7 @@ void ieee80211_get_tkip_key(struct ieee80211_key_conf *keyconf,
183 /* Update the p1k only when the iv16 in the packet wraps around, this 183 /* Update the p1k only when the iv16 in the packet wraps around, this
184 * might occur after the wrap around of iv16 in the key in case of 184 * might occur after the wrap around of iv16 in the key in case of
185 * fragmented packets. */ 185 * fragmented packets. */
186 if (iv16 == 0 || !ctx->initialized) 186 if (iv16 == 0 || ctx->state == TKIP_STATE_NOT_INIT)
187 tkip_mixing_phase1(tk, ctx, hdr->addr2, iv32); 187 tkip_mixing_phase1(tk, ctx, hdr->addr2, iv32);
188 188
189 if (type == IEEE80211_TKIP_P1_KEY) { 189 if (type == IEEE80211_TKIP_P1_KEY) {
@@ -209,7 +209,7 @@ void ieee80211_tkip_encrypt_data(struct crypto_blkcipher *tfm,
209 const u8 *tk = &key->conf.key[NL80211_TKIP_DATA_OFFSET_ENCR_KEY]; 209 const u8 *tk = &key->conf.key[NL80211_TKIP_DATA_OFFSET_ENCR_KEY];
210 210
211 /* Calculate per-packet key */ 211 /* Calculate per-packet key */
212 if (ctx->iv16 == 0 || !ctx->initialized) 212 if (ctx->iv16 == 0 || ctx->state == TKIP_STATE_NOT_INIT)
213 tkip_mixing_phase1(tk, ctx, ta, ctx->iv32); 213 tkip_mixing_phase1(tk, ctx, ta, ctx->iv32);
214 214
215 tkip_mixing_phase2(tk, ctx, ctx->iv16, rc4key); 215 tkip_mixing_phase2(tk, ctx, ctx->iv16, rc4key);
@@ -259,7 +259,7 @@ int ieee80211_tkip_decrypt_data(struct crypto_blkcipher *tfm,
259 if ((keyid >> 6) != key->conf.keyidx) 259 if ((keyid >> 6) != key->conf.keyidx)
260 return TKIP_DECRYPT_INVALID_KEYIDX; 260 return TKIP_DECRYPT_INVALID_KEYIDX;
261 261
262 if (key->u.tkip.rx[queue].initialized && 262 if (key->u.tkip.rx[queue].state != TKIP_STATE_NOT_INIT &&
263 (iv32 < key->u.tkip.rx[queue].iv32 || 263 (iv32 < key->u.tkip.rx[queue].iv32 ||
264 (iv32 == key->u.tkip.rx[queue].iv32 && 264 (iv32 == key->u.tkip.rx[queue].iv32 &&
265 iv16 <= key->u.tkip.rx[queue].iv16))) { 265 iv16 <= key->u.tkip.rx[queue].iv16))) {
@@ -275,11 +275,11 @@ int ieee80211_tkip_decrypt_data(struct crypto_blkcipher *tfm,
275 275
276 if (only_iv) { 276 if (only_iv) {
277 res = TKIP_DECRYPT_OK; 277 res = TKIP_DECRYPT_OK;
278 key->u.tkip.rx[queue].initialized = 1; 278 key->u.tkip.rx[queue].state = TKIP_STATE_PHASE1_HW_UPLOADED;
279 goto done; 279 goto done;
280 } 280 }
281 281
282 if (!key->u.tkip.rx[queue].initialized || 282 if (key->u.tkip.rx[queue].state == TKIP_STATE_NOT_INIT ||
283 key->u.tkip.rx[queue].iv32 != iv32) { 283 key->u.tkip.rx[queue].iv32 != iv32) {
284 /* IV16 wrapped around - perform TKIP phase 1 */ 284 /* IV16 wrapped around - perform TKIP phase 1 */
285 tkip_mixing_phase1(tk, &key->u.tkip.rx[queue], ta, iv32); 285 tkip_mixing_phase1(tk, &key->u.tkip.rx[queue], ta, iv32);
@@ -299,18 +299,20 @@ int ieee80211_tkip_decrypt_data(struct crypto_blkcipher *tfm,
299 printk("\n"); 299 printk("\n");
300 } 300 }
301#endif 301#endif
302 if (key->local->ops->update_tkip_key && 302 }
303 key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) { 303 if (key->local->ops->update_tkip_key &&
304 static const u8 bcast[ETH_ALEN] = 304 key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE &&
305 {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; 305 key->u.tkip.rx[queue].state != TKIP_STATE_PHASE1_HW_UPLOADED) {
306 const u8 *sta_addr = key->sta->sta.addr; 306 static const u8 bcast[ETH_ALEN] =
307 307 {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
308 if (is_multicast_ether_addr(ra)) 308 const u8 *sta_addr = key->sta->sta.addr;
309 sta_addr = bcast; 309
310 310 if (is_multicast_ether_addr(ra))
311 drv_update_tkip_key(key->local, &key->conf, sta_addr, 311 sta_addr = bcast;
312 iv32, key->u.tkip.rx[queue].p1k); 312
313 } 313 drv_update_tkip_key(key->local, &key->conf, sta_addr,
314 iv32, key->u.tkip.rx[queue].p1k);
315 key->u.tkip.rx[queue].state = TKIP_STATE_PHASE1_HW_UPLOADED;
314 } 316 }
315 317
316 tkip_mixing_phase2(tk, &key->u.tkip.rx[queue], iv16, rc4key); 318 tkip_mixing_phase2(tk, &key->u.tkip.rx[queue], iv16, rc4key);
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 8834cc93c716..ac48c86ae6b3 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -223,7 +223,7 @@ ieee80211_tx_h_check_assoc(struct ieee80211_tx_data *tx)
223#ifdef CONFIG_MAC80211_VERBOSE_DEBUG 223#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
224 printk(KERN_DEBUG "%s: dropped data frame to not " 224 printk(KERN_DEBUG "%s: dropped data frame to not "
225 "associated station %pM\n", 225 "associated station %pM\n",
226 tx->dev->name, hdr->addr1); 226 tx->sdata->name, hdr->addr1);
227#endif /* CONFIG_MAC80211_VERBOSE_DEBUG */ 227#endif /* CONFIG_MAC80211_VERBOSE_DEBUG */
228 I802_DEBUG_INC(tx->local->tx_handlers_drop_not_assoc); 228 I802_DEBUG_INC(tx->local->tx_handlers_drop_not_assoc);
229 return TX_DROP; 229 return TX_DROP;
@@ -331,7 +331,7 @@ ieee80211_tx_h_multicast_ps_buf(struct ieee80211_tx_data *tx)
331#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG 331#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG
332 if (net_ratelimit()) 332 if (net_ratelimit())
333 printk(KERN_DEBUG "%s: BC TX buffer full - dropping the oldest frame\n", 333 printk(KERN_DEBUG "%s: BC TX buffer full - dropping the oldest frame\n",
334 tx->dev->name); 334 tx->sdata->name);
335#endif 335#endif
336 dev_kfree_skb(skb_dequeue(&tx->sdata->bss->ps_bc_buf)); 336 dev_kfree_skb(skb_dequeue(&tx->sdata->bss->ps_bc_buf));
337 } else 337 } else
@@ -391,7 +391,7 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx)
391 if (net_ratelimit()) { 391 if (net_ratelimit()) {
392 printk(KERN_DEBUG "%s: STA %pM TX " 392 printk(KERN_DEBUG "%s: STA %pM TX "
393 "buffer full - dropping oldest frame\n", 393 "buffer full - dropping oldest frame\n",
394 tx->dev->name, sta->sta.addr); 394 tx->sdata->name, sta->sta.addr);
395 } 395 }
396#endif 396#endif
397 dev_kfree_skb(old); 397 dev_kfree_skb(old);
@@ -416,7 +416,7 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx)
416#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG 416#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG
417 else if (unlikely(staflags & WLAN_STA_PS_STA)) { 417 else if (unlikely(staflags & WLAN_STA_PS_STA)) {
418 printk(KERN_DEBUG "%s: STA %pM in PS mode, but pspoll " 418 printk(KERN_DEBUG "%s: STA %pM in PS mode, but pspoll "
419 "set -> send frame\n", tx->dev->name, 419 "set -> send frame\n", tx->sdata->name,
420 sta->sta.addr); 420 sta->sta.addr);
421 } 421 }
422#endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ 422#endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */
@@ -549,7 +549,7 @@ ieee80211_tx_h_rate_ctrl(struct ieee80211_tx_data *tx)
549 "%s: Dropped data frame as no usable bitrate found while " 549 "%s: Dropped data frame as no usable bitrate found while "
550 "scanning and associated. Target station: " 550 "scanning and associated. Target station: "
551 "%pM on %d GHz band\n", 551 "%pM on %d GHz band\n",
552 tx->dev->name, hdr->addr1, 552 tx->sdata->name, hdr->addr1,
553 tx->channel->band ? 5 : 2)) 553 tx->channel->band ? 5 : 2))
554 return TX_DROP; 554 return TX_DROP;
555 555
@@ -1021,7 +1021,6 @@ ieee80211_tx_prepare(struct ieee80211_sub_if_data *sdata,
1021 1021
1022 memset(tx, 0, sizeof(*tx)); 1022 memset(tx, 0, sizeof(*tx));
1023 tx->skb = skb; 1023 tx->skb = skb;
1024 tx->dev = sdata->dev; /* use original interface */
1025 tx->local = local; 1024 tx->local = local;
1026 tx->sdata = sdata; 1025 tx->sdata = sdata;
1027 tx->channel = local->hw.conf.channel; 1026 tx->channel = local->hw.conf.channel;
@@ -1055,7 +1054,7 @@ ieee80211_tx_prepare(struct ieee80211_sub_if_data *sdata,
1055 if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) 1054 if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
1056 tx->sta = rcu_dereference(sdata->u.vlan.sta); 1055 tx->sta = rcu_dereference(sdata->u.vlan.sta);
1057 if (!tx->sta) 1056 if (!tx->sta)
1058 tx->sta = sta_info_get(local, hdr->addr1); 1057 tx->sta = sta_info_get(sdata, hdr->addr1);
1059 1058
1060 if (tx->sta && ieee80211_is_data_qos(hdr->frame_control) && 1059 if (tx->sta && ieee80211_is_data_qos(hdr->frame_control) &&
1061 (local->hw.flags & IEEE80211_HW_AMPDU_AGGREGATION)) { 1060 (local->hw.flags & IEEE80211_HW_AMPDU_AGGREGATION)) {
@@ -1474,7 +1473,7 @@ static void ieee80211_xmit(struct ieee80211_sub_if_data *sdata,
1474 continue; 1473 continue;
1475 if (tmp_sdata->vif.type != NL80211_IFTYPE_AP) 1474 if (tmp_sdata->vif.type != NL80211_IFTYPE_AP)
1476 continue; 1475 continue;
1477 if (compare_ether_addr(tmp_sdata->dev->dev_addr, 1476 if (compare_ether_addr(tmp_sdata->vif.addr,
1478 hdr->addr2) == 0) { 1477 hdr->addr2) == 0) {
1479 sdata = tmp_sdata; 1478 sdata = tmp_sdata;
1480 break; 1479 break;
@@ -1638,7 +1637,7 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
1638 fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS); 1637 fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS);
1639 /* RA TA DA SA */ 1638 /* RA TA DA SA */
1640 memcpy(hdr.addr1, sta->sta.addr, ETH_ALEN); 1639 memcpy(hdr.addr1, sta->sta.addr, ETH_ALEN);
1641 memcpy(hdr.addr2, dev->dev_addr, ETH_ALEN); 1640 memcpy(hdr.addr2, sdata->vif.addr, ETH_ALEN);
1642 memcpy(hdr.addr3, skb->data, ETH_ALEN); 1641 memcpy(hdr.addr3, skb->data, ETH_ALEN);
1643 memcpy(hdr.addr4, skb->data + ETH_ALEN, ETH_ALEN); 1642 memcpy(hdr.addr4, skb->data + ETH_ALEN, ETH_ALEN);
1644 hdrlen = 30; 1643 hdrlen = 30;
@@ -1652,7 +1651,7 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
1652 fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS); 1651 fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS);
1653 /* DA BSSID SA */ 1652 /* DA BSSID SA */
1654 memcpy(hdr.addr1, skb->data, ETH_ALEN); 1653 memcpy(hdr.addr1, skb->data, ETH_ALEN);
1655 memcpy(hdr.addr2, dev->dev_addr, ETH_ALEN); 1654 memcpy(hdr.addr2, sdata->vif.addr, ETH_ALEN);
1656 memcpy(hdr.addr3, skb->data + ETH_ALEN, ETH_ALEN); 1655 memcpy(hdr.addr3, skb->data + ETH_ALEN, ETH_ALEN);
1657 hdrlen = 24; 1656 hdrlen = 24;
1658 break; 1657 break;
@@ -1660,7 +1659,7 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
1660 fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS); 1659 fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS);
1661 /* RA TA DA SA */ 1660 /* RA TA DA SA */
1662 memcpy(hdr.addr1, sdata->u.wds.remote_addr, ETH_ALEN); 1661 memcpy(hdr.addr1, sdata->u.wds.remote_addr, ETH_ALEN);
1663 memcpy(hdr.addr2, dev->dev_addr, ETH_ALEN); 1662 memcpy(hdr.addr2, sdata->vif.addr, ETH_ALEN);
1664 memcpy(hdr.addr3, skb->data, ETH_ALEN); 1663 memcpy(hdr.addr3, skb->data, ETH_ALEN);
1665 memcpy(hdr.addr4, skb->data + ETH_ALEN, ETH_ALEN); 1664 memcpy(hdr.addr4, skb->data + ETH_ALEN, ETH_ALEN);
1666 hdrlen = 30; 1665 hdrlen = 30;
@@ -1674,8 +1673,8 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
1674 goto fail; 1673 goto fail;
1675 } 1674 }
1676 1675
1677 if (compare_ether_addr(dev->dev_addr, 1676 if (compare_ether_addr(sdata->vif.addr,
1678 skb->data + ETH_ALEN) == 0) { 1677 skb->data + ETH_ALEN) == 0) {
1679 hdrlen = ieee80211_fill_mesh_addresses(&hdr, &fc, 1678 hdrlen = ieee80211_fill_mesh_addresses(&hdr, &fc,
1680 skb->data, skb->data + ETH_ALEN); 1679 skb->data, skb->data + ETH_ALEN);
1681 meshhdrlen = ieee80211_new_mesh_header(&mesh_hdr, 1680 meshhdrlen = ieee80211_new_mesh_header(&mesh_hdr,
@@ -1705,7 +1704,7 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
1705 } 1704 }
1706 } 1705 }
1707 hdrlen = ieee80211_fill_mesh_addresses(&hdr, &fc, 1706 hdrlen = ieee80211_fill_mesh_addresses(&hdr, &fc,
1708 mesh_da, dev->dev_addr); 1707 mesh_da, sdata->vif.addr);
1709 rcu_read_unlock(); 1708 rcu_read_unlock();
1710 if (is_mesh_mcast) 1709 if (is_mesh_mcast)
1711 meshhdrlen = 1710 meshhdrlen =
@@ -1730,7 +1729,7 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
1730 if (sdata->u.mgd.use_4addr && ethertype != ETH_P_PAE) { 1729 if (sdata->u.mgd.use_4addr && ethertype != ETH_P_PAE) {
1731 fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS); 1730 fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS);
1732 /* RA TA DA SA */ 1731 /* RA TA DA SA */
1733 memcpy(hdr.addr2, dev->dev_addr, ETH_ALEN); 1732 memcpy(hdr.addr2, sdata->vif.addr, ETH_ALEN);
1734 memcpy(hdr.addr3, skb->data, ETH_ALEN); 1733 memcpy(hdr.addr3, skb->data, ETH_ALEN);
1735 memcpy(hdr.addr4, skb->data + ETH_ALEN, ETH_ALEN); 1734 memcpy(hdr.addr4, skb->data + ETH_ALEN, ETH_ALEN);
1736 hdrlen = 30; 1735 hdrlen = 30;
@@ -1761,9 +1760,8 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
1761 */ 1760 */
1762 if (!is_multicast_ether_addr(hdr.addr1)) { 1761 if (!is_multicast_ether_addr(hdr.addr1)) {
1763 rcu_read_lock(); 1762 rcu_read_lock();
1764 sta = sta_info_get(local, hdr.addr1); 1763 sta = sta_info_get(sdata, hdr.addr1);
1765 /* XXX: in the future, use sdata to look up the sta */ 1764 if (sta)
1766 if (sta && sta->sdata == sdata)
1767 sta_flags = get_sta_flags(sta); 1765 sta_flags = get_sta_flags(sta);
1768 rcu_read_unlock(); 1766 rcu_read_unlock();
1769 } 1767 }
@@ -1782,7 +1780,7 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
1782 unlikely(!is_multicast_ether_addr(hdr.addr1) && 1780 unlikely(!is_multicast_ether_addr(hdr.addr1) &&
1783 !(sta_flags & WLAN_STA_AUTHORIZED) && 1781 !(sta_flags & WLAN_STA_AUTHORIZED) &&
1784 !(ethertype == ETH_P_PAE && 1782 !(ethertype == ETH_P_PAE &&
1785 compare_ether_addr(dev->dev_addr, 1783 compare_ether_addr(sdata->vif.addr,
1786 skb->data + ETH_ALEN) == 0))) { 1784 skb->data + ETH_ALEN) == 0))) {
1787#ifdef CONFIG_MAC80211_VERBOSE_DEBUG 1785#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
1788 if (net_ratelimit()) 1786 if (net_ratelimit())
@@ -1922,7 +1920,7 @@ static bool ieee80211_tx_pending_skb(struct ieee80211_local *local,
1922 ieee80211_tx(sdata, skb, true); 1920 ieee80211_tx(sdata, skb, true);
1923 } else { 1921 } else {
1924 hdr = (struct ieee80211_hdr *)skb->data; 1922 hdr = (struct ieee80211_hdr *)skb->data;
1925 sta = sta_info_get(local, hdr->addr1); 1923 sta = sta_info_get(sdata, hdr->addr1);
1926 1924
1927 ret = __ieee80211_tx(local, &skb, sta, true); 1925 ret = __ieee80211_tx(local, &skb, sta, true);
1928 if (ret != IEEE80211_TX_OK) 1926 if (ret != IEEE80211_TX_OK)
@@ -2146,8 +2144,8 @@ struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw,
2146 mgmt->frame_control = 2144 mgmt->frame_control =
2147 cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON); 2145 cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
2148 memset(mgmt->da, 0xff, ETH_ALEN); 2146 memset(mgmt->da, 0xff, ETH_ALEN);
2149 memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN); 2147 memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN);
2150 memcpy(mgmt->bssid, sdata->dev->dev_addr, ETH_ALEN); 2148 memcpy(mgmt->bssid, sdata->vif.addr, ETH_ALEN);
2151 mgmt->u.beacon.beacon_int = 2149 mgmt->u.beacon.beacon_int =
2152 cpu_to_le16(sdata->vif.bss_conf.beacon_int); 2150 cpu_to_le16(sdata->vif.bss_conf.beacon_int);
2153 mgmt->u.beacon.capab_info = 0x0; /* 0x0 for MPs */ 2151 mgmt->u.beacon.capab_info = 0x0; /* 0x0 for MPs */
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 78a6e924c7e1..b01972579c7c 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -469,7 +469,7 @@ void ieee80211_iterate_active_interfaces(
469 break; 469 break;
470 } 470 }
471 if (netif_running(sdata->dev)) 471 if (netif_running(sdata->dev))
472 iterator(data, sdata->dev->dev_addr, 472 iterator(data, sdata->vif.addr,
473 &sdata->vif); 473 &sdata->vif);
474 } 474 }
475 475
@@ -503,7 +503,7 @@ void ieee80211_iterate_active_interfaces_atomic(
503 break; 503 break;
504 } 504 }
505 if (netif_running(sdata->dev)) 505 if (netif_running(sdata->dev))
506 iterator(data, sdata->dev->dev_addr, 506 iterator(data, sdata->vif.addr,
507 &sdata->vif); 507 &sdata->vif);
508 } 508 }
509 509
@@ -848,7 +848,7 @@ void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata,
848 sizeof(*mgmt) + 6 + extra_len); 848 sizeof(*mgmt) + 6 + extra_len);
849 if (!skb) { 849 if (!skb) {
850 printk(KERN_DEBUG "%s: failed to allocate buffer for auth " 850 printk(KERN_DEBUG "%s: failed to allocate buffer for auth "
851 "frame\n", sdata->dev->name); 851 "frame\n", sdata->name);
852 return; 852 return;
853 } 853 }
854 skb_reserve(skb, local->hw.extra_tx_headroom); 854 skb_reserve(skb, local->hw.extra_tx_headroom);
@@ -858,7 +858,7 @@ void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata,
858 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | 858 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
859 IEEE80211_STYPE_AUTH); 859 IEEE80211_STYPE_AUTH);
860 memcpy(mgmt->da, bssid, ETH_ALEN); 860 memcpy(mgmt->da, bssid, ETH_ALEN);
861 memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN); 861 memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN);
862 memcpy(mgmt->bssid, bssid, ETH_ALEN); 862 memcpy(mgmt->bssid, bssid, ETH_ALEN);
863 mgmt->u.auth.auth_alg = cpu_to_le16(auth_alg); 863 mgmt->u.auth.auth_alg = cpu_to_le16(auth_alg);
864 mgmt->u.auth.auth_transaction = cpu_to_le16(transaction); 864 mgmt->u.auth.auth_transaction = cpu_to_le16(transaction);
@@ -908,16 +908,24 @@ int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer,
908 } 908 }
909 909
910 if (sband->ht_cap.ht_supported) { 910 if (sband->ht_cap.ht_supported) {
911 __le16 tmp = cpu_to_le16(sband->ht_cap.cap); 911 u16 cap = sband->ht_cap.cap;
912 __le16 tmp;
913
914 if (ieee80211_disable_40mhz_24ghz &&
915 sband->band == IEEE80211_BAND_2GHZ) {
916 cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
917 cap &= ~IEEE80211_HT_CAP_SGI_40;
918 }
912 919
913 *pos++ = WLAN_EID_HT_CAPABILITY; 920 *pos++ = WLAN_EID_HT_CAPABILITY;
914 *pos++ = sizeof(struct ieee80211_ht_cap); 921 *pos++ = sizeof(struct ieee80211_ht_cap);
915 memset(pos, 0, sizeof(struct ieee80211_ht_cap)); 922 memset(pos, 0, sizeof(struct ieee80211_ht_cap));
923 tmp = cpu_to_le16(cap);
916 memcpy(pos, &tmp, sizeof(u16)); 924 memcpy(pos, &tmp, sizeof(u16));
917 pos += sizeof(u16); 925 pos += sizeof(u16);
918 /* TODO: needs a define here for << 2 */
919 *pos++ = sband->ht_cap.ampdu_factor | 926 *pos++ = sband->ht_cap.ampdu_factor |
920 (sband->ht_cap.ampdu_density << 2); 927 (sband->ht_cap.ampdu_density <<
928 IEEE80211_HT_AMPDU_PARM_DENSITY_SHIFT);
921 memcpy(pos, &sband->ht_cap.mcs, sizeof(sband->ht_cap.mcs)); 929 memcpy(pos, &sband->ht_cap.mcs, sizeof(sband->ht_cap.mcs));
922 pos += sizeof(sband->ht_cap.mcs); 930 pos += sizeof(sband->ht_cap.mcs);
923 pos += 2 + 4 + 1; /* ext info, BF cap, antsel */ 931 pos += 2 + 4 + 1; /* ext info, BF cap, antsel */
@@ -949,7 +957,7 @@ void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst,
949 ie_len); 957 ie_len);
950 if (!skb) { 958 if (!skb) {
951 printk(KERN_DEBUG "%s: failed to allocate buffer for probe " 959 printk(KERN_DEBUG "%s: failed to allocate buffer for probe "
952 "request\n", sdata->dev->name); 960 "request\n", sdata->name);
953 return; 961 return;
954 } 962 }
955 skb_reserve(skb, local->hw.extra_tx_headroom); 963 skb_reserve(skb, local->hw.extra_tx_headroom);
@@ -958,7 +966,7 @@ void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst,
958 memset(mgmt, 0, 24); 966 memset(mgmt, 0, 24);
959 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | 967 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
960 IEEE80211_STYPE_PROBE_REQ); 968 IEEE80211_STYPE_PROBE_REQ);
961 memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN); 969 memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN);
962 if (dst) { 970 if (dst) {
963 memcpy(mgmt->da, dst, ETH_ALEN); 971 memcpy(mgmt->da, dst, ETH_ALEN);
964 memcpy(mgmt->bssid, dst, ETH_ALEN); 972 memcpy(mgmt->bssid, dst, ETH_ALEN);
@@ -1051,7 +1059,7 @@ int ieee80211_reconfig(struct ieee80211_local *local)
1051 netif_running(sdata->dev)) { 1059 netif_running(sdata->dev)) {
1052 conf.vif = &sdata->vif; 1060 conf.vif = &sdata->vif;
1053 conf.type = sdata->vif.type; 1061 conf.type = sdata->vif.type;
1054 conf.mac_addr = sdata->dev->dev_addr; 1062 conf.mac_addr = sdata->vif.addr;
1055 res = drv_add_interface(local, &conf); 1063 res = drv_add_interface(local, &conf);
1056 } 1064 }
1057 } 1065 }
@@ -1066,7 +1074,7 @@ int ieee80211_reconfig(struct ieee80211_local *local)
1066 struct ieee80211_sub_if_data, 1074 struct ieee80211_sub_if_data,
1067 u.ap); 1075 u.ap);
1068 1076
1069 drv_sta_notify(local, &sdata->vif, STA_NOTIFY_ADD, 1077 drv_sta_notify(local, sdata, STA_NOTIFY_ADD,
1070 &sta->sta); 1078 &sta->sta);
1071 } 1079 }
1072 spin_unlock_irqrestore(&local->sta_lock, flags); 1080 spin_unlock_irqrestore(&local->sta_lock, flags);
@@ -1170,3 +1178,77 @@ int ieee80211_reconfig(struct ieee80211_local *local)
1170 return 0; 1178 return 0;
1171} 1179}
1172 1180
1181static int check_mgd_smps(struct ieee80211_if_managed *ifmgd,
1182 enum ieee80211_smps_mode *smps_mode)
1183{
1184 if (ifmgd->associated) {
1185 *smps_mode = ifmgd->ap_smps;
1186
1187 if (*smps_mode == IEEE80211_SMPS_AUTOMATIC) {
1188 if (ifmgd->powersave)
1189 *smps_mode = IEEE80211_SMPS_DYNAMIC;
1190 else
1191 *smps_mode = IEEE80211_SMPS_OFF;
1192 }
1193
1194 return 1;
1195 }
1196
1197 return 0;
1198}
1199
1200/* must hold iflist_mtx */
1201void ieee80211_recalc_smps(struct ieee80211_local *local,
1202 struct ieee80211_sub_if_data *forsdata)
1203{
1204 struct ieee80211_sub_if_data *sdata;
1205 enum ieee80211_smps_mode smps_mode = IEEE80211_SMPS_OFF;
1206 int count = 0;
1207
1208 if (forsdata)
1209 WARN_ON(!mutex_is_locked(&forsdata->u.mgd.mtx));
1210
1211 WARN_ON(!mutex_is_locked(&local->iflist_mtx));
1212
1213 /*
1214 * This function could be improved to handle multiple
1215 * interfaces better, but right now it makes any
1216 * non-station interfaces force SM PS to be turned
1217 * off. If there are multiple station interfaces it
1218 * could also use the best possible mode, e.g. if
1219 * one is in static and the other in dynamic then
1220 * dynamic is ok.
1221 */
1222
1223 list_for_each_entry(sdata, &local->interfaces, list) {
1224 if (!netif_running(sdata->dev))
1225 continue;
1226 if (sdata->vif.type != NL80211_IFTYPE_STATION)
1227 goto set;
1228 if (sdata != forsdata) {
1229 /*
1230 * This nested is ok -- we are holding the iflist_mtx
1231 * so can't get here twice or so. But it's required
1232 * since normally we acquire it first and then the
1233 * iflist_mtx.
1234 */
1235 mutex_lock_nested(&sdata->u.mgd.mtx, SINGLE_DEPTH_NESTING);
1236 count += check_mgd_smps(&sdata->u.mgd, &smps_mode);
1237 mutex_unlock(&sdata->u.mgd.mtx);
1238 } else
1239 count += check_mgd_smps(&sdata->u.mgd, &smps_mode);
1240
1241 if (count > 1) {
1242 smps_mode = IEEE80211_SMPS_OFF;
1243 break;
1244 }
1245 }
1246
1247 if (smps_mode == local->smps_mode)
1248 return;
1249
1250 set:
1251 local->smps_mode = smps_mode;
1252 /* changed flag is auto-detected for this */
1253 ieee80211_hw_config(local, 0);
1254}
diff --git a/net/wireless/.gitignore b/net/wireless/.gitignore
new file mode 100644
index 000000000000..c33451b896d9
--- /dev/null
+++ b/net/wireless/.gitignore
@@ -0,0 +1 @@
regdb.c
diff --git a/net/wireless/Kconfig b/net/wireless/Kconfig
index 90e93a5701aa..8419971f07c5 100644
--- a/net/wireless/Kconfig
+++ b/net/wireless/Kconfig
@@ -109,6 +109,22 @@ config WIRELESS_OLD_REGULATORY
109 109
110 Say N and if you say Y, please tell us why. The default is N. 110 Say N and if you say Y, please tell us why. The default is N.
111 111
112config CFG80211_INTERNAL_REGDB
113 bool "use statically compiled regulatory rules database" if EMBEDDED
114 default n
115 depends on CFG80211
116 ---help---
117 This option generates an internal data structure representing
118 the wireless regulatory rules described in net/wireless/db.txt
119 and includes code to query that database. This is an alternative
120 to using CRDA for defining regulatory rules for the kernel.
121
122 For details see:
123
124 http://wireless.kernel.org/en/developers/Regulatory
125
126 Most distributions have a CRDA package. So if unsure, say N.
127
112config CFG80211_WEXT 128config CFG80211_WEXT
113 bool "cfg80211 wireless extensions compatibility" 129 bool "cfg80211 wireless extensions compatibility"
114 depends on CFG80211 130 depends on CFG80211
diff --git a/net/wireless/Makefile b/net/wireless/Makefile
index f07c8dc7aab2..e77e508126fa 100644
--- a/net/wireless/Makefile
+++ b/net/wireless/Makefile
@@ -13,5 +13,11 @@ cfg80211-y += core.o sysfs.o radiotap.o util.o reg.o scan.o nl80211.o
13cfg80211-y += mlme.o ibss.o sme.o chan.o ethtool.o 13cfg80211-y += mlme.o ibss.o sme.o chan.o ethtool.o
14cfg80211-$(CONFIG_CFG80211_DEBUGFS) += debugfs.o 14cfg80211-$(CONFIG_CFG80211_DEBUGFS) += debugfs.o
15cfg80211-$(CONFIG_CFG80211_WEXT) += wext-compat.o wext-sme.o 15cfg80211-$(CONFIG_CFG80211_WEXT) += wext-compat.o wext-sme.o
16cfg80211-$(CONFIG_CFG80211_INTERNAL_REGDB) += regdb.o
16 17
17ccflags-y += -D__CHECK_ENDIAN__ 18ccflags-y += -D__CHECK_ENDIAN__
19
20$(obj)/regdb.c: $(src)/db.txt $(src)/genregdb.awk
21 @$(AWK) -f $(srctree)/$(src)/genregdb.awk < $< > $@
22
23clean-files := regdb.c
diff --git a/net/wireless/core.h b/net/wireless/core.h
index 4ef3efc94106..35b712127143 100644
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
@@ -378,6 +378,8 @@ int rdev_set_freq(struct cfg80211_registered_device *rdev,
378 struct wireless_dev *for_wdev, 378 struct wireless_dev *for_wdev,
379 int freq, enum nl80211_channel_type channel_type); 379 int freq, enum nl80211_channel_type channel_type);
380 380
381u16 cfg80211_calculate_bitrate(struct rate_info *rate);
382
381#ifdef CONFIG_CFG80211_DEVELOPER_WARNINGS 383#ifdef CONFIG_CFG80211_DEVELOPER_WARNINGS
382#define CFG80211_DEV_WARN_ON(cond) WARN_ON(cond) 384#define CFG80211_DEV_WARN_ON(cond) WARN_ON(cond)
383#else 385#else
diff --git a/net/wireless/db.txt b/net/wireless/db.txt
new file mode 100644
index 000000000000..a2fc3a09ccdc
--- /dev/null
+++ b/net/wireless/db.txt
@@ -0,0 +1,17 @@
1#
2# This file is a placeholder to prevent accidental build breakage if someone
3# enables CONFIG_CFG80211_INTERNAL_REGDB. Almost no one actually needs to
4# enable that build option.
5#
6# You should be using CRDA instead. It is even better if you use the CRDA
7# package provided by your distribution, since they will probably keep it
8# up-to-date on your behalf.
9#
10# If you _really_ intend to use CONFIG_CFG80211_INTERNAL_REGDB then you will
11# need to replace this file with one containing appropriately formatted
12# regulatory rules that cover the regulatory domains you will be using. Your
13# best option is to extract the db.txt file from the wireless-regdb git
14# repository:
15#
16# git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-regdb.git
17#
diff --git a/net/wireless/genregdb.awk b/net/wireless/genregdb.awk
new file mode 100644
index 000000000000..8316cf075ce9
--- /dev/null
+++ b/net/wireless/genregdb.awk
@@ -0,0 +1,118 @@
1#!/usr/bin/awk -f
2#
3# genregdb.awk -- generate regdb.c from db.txt
4#
5# Actually, it reads from stdin (presumed to be db.txt) and writes
6# to stdout (presumed to be regdb.c), but close enough...
7#
8# Copyright 2009 John W. Linville <linville@tuxdriver.com>
9#
10# This program is free software; you can redistribute it and/or modify
11# it under the terms of the GNU General Public License version 2 as
12# published by the Free Software Foundation.
13#
14
15BEGIN {
16 active = 0
17 rules = 0;
18 print "/*"
19 print " * DO NOT EDIT -- file generated from data in db.txt"
20 print " */"
21 print ""
22 print "#include <linux/nl80211.h>"
23 print "#include <net/cfg80211.h>"
24 print ""
25 regdb = "const struct ieee80211_regdomain *reg_regdb[] = {\n"
26}
27
28/^[ \t]*#/ {
29 /* Ignore */
30}
31
32!active && /^[ \t]*$/ {
33 /* Ignore */
34}
35
36!active && /country/ {
37 country=$2
38 sub(/:/, "", country)
39 printf "static const struct ieee80211_regdomain regdom_%s = {\n", country
40 printf "\t.alpha2 = \"%s\",\n", country
41 printf "\t.reg_rules = {\n"
42 active = 1
43 regdb = regdb "\t&regdom_" country ",\n"
44}
45
46active && /^[ \t]*\(/ {
47 start = $1
48 sub(/\(/, "", start)
49 end = $3
50 bw = $5
51 sub(/\),/, "", bw)
52 gain = $6
53 sub(/\(/, "", gain)
54 sub(/,/, "", gain)
55 power = $7
56 sub(/\)/, "", power)
57 sub(/,/, "", power)
58 # power might be in mW...
59 units = $8
60 sub(/\)/, "", units)
61 sub(/,/, "", units)
62 if (units == "mW") {
63 if (power == 100) {
64 power = 20
65 } else if (power == 200) {
66 power = 23
67 } else if (power == 500) {
68 power = 27
69 } else if (power == 1000) {
70 power = 30
71 } else {
72 print "Unknown power value in database!"
73 }
74 }
75 flagstr = ""
76 for (i=8; i<=NF; i++)
77 flagstr = flagstr $i
78 split(flagstr, flagarray, ",")
79 flags = ""
80 for (arg in flagarray) {
81 if (flagarray[arg] == "NO-OFDM") {
82 flags = flags "\n\t\t\tNL80211_RRF_NO_OFDM | "
83 } else if (flagarray[arg] == "NO-CCK") {
84 flags = flags "\n\t\t\tNL80211_RRF_NO_CCK | "
85 } else if (flagarray[arg] == "NO-INDOOR") {
86 flags = flags "\n\t\t\tNL80211_RRF_NO_INDOOR | "
87 } else if (flagarray[arg] == "NO-OUTDOOR") {
88 flags = flags "\n\t\t\tNL80211_RRF_NO_OUTDOOR | "
89 } else if (flagarray[arg] == "DFS") {
90 flags = flags "\n\t\t\tNL80211_RRF_DFS | "
91 } else if (flagarray[arg] == "PTP-ONLY") {
92 flags = flags "\n\t\t\tNL80211_RRF_PTP_ONLY | "
93 } else if (flagarray[arg] == "PTMP-ONLY") {
94 flags = flags "\n\t\t\tNL80211_RRF_PTMP_ONLY | "
95 } else if (flagarray[arg] == "PASSIVE-SCAN") {
96 flags = flags "\n\t\t\tNL80211_RRF_PASSIVE_SCAN | "
97 } else if (flagarray[arg] == "NO-IBSS") {
98 flags = flags "\n\t\t\tNL80211_RRF_NO_IBSS | "
99 }
100 }
101 flags = flags "0"
102 printf "\t\tREG_RULE(%d, %d, %d, %d, %d, %s),\n", start, end, bw, gain, power, flags
103 rules++
104}
105
106active && /^[ \t]*$/ {
107 active = 0
108 printf "\t},\n"
109 printf "\t.n_reg_rules = %d\n", rules
110 printf "};\n\n"
111 rules = 0;
112}
113
114END {
115 print regdb "};"
116 print ""
117 print "int reg_regdb_size = ARRAY_SIZE(reg_regdb);"
118}
diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c
index 1001db4912f7..acaeaa784d68 100644
--- a/net/wireless/mlme.c
+++ b/net/wireless/mlme.c
@@ -137,22 +137,23 @@ void __cfg80211_send_deauth(struct net_device *dev,
137 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)buf; 137 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)buf;
138 const u8 *bssid = mgmt->bssid; 138 const u8 *bssid = mgmt->bssid;
139 int i; 139 int i;
140 bool found = false;
140 141
141 ASSERT_WDEV_LOCK(wdev); 142 ASSERT_WDEV_LOCK(wdev);
142 143
143 nl80211_send_deauth(rdev, dev, buf, len, GFP_KERNEL);
144
145 if (wdev->current_bss && 144 if (wdev->current_bss &&
146 memcmp(wdev->current_bss->pub.bssid, bssid, ETH_ALEN) == 0) { 145 memcmp(wdev->current_bss->pub.bssid, bssid, ETH_ALEN) == 0) {
147 cfg80211_unhold_bss(wdev->current_bss); 146 cfg80211_unhold_bss(wdev->current_bss);
148 cfg80211_put_bss(&wdev->current_bss->pub); 147 cfg80211_put_bss(&wdev->current_bss->pub);
149 wdev->current_bss = NULL; 148 wdev->current_bss = NULL;
149 found = true;
150 } else for (i = 0; i < MAX_AUTH_BSSES; i++) { 150 } else for (i = 0; i < MAX_AUTH_BSSES; i++) {
151 if (wdev->auth_bsses[i] && 151 if (wdev->auth_bsses[i] &&
152 memcmp(wdev->auth_bsses[i]->pub.bssid, bssid, ETH_ALEN) == 0) { 152 memcmp(wdev->auth_bsses[i]->pub.bssid, bssid, ETH_ALEN) == 0) {
153 cfg80211_unhold_bss(wdev->auth_bsses[i]); 153 cfg80211_unhold_bss(wdev->auth_bsses[i]);
154 cfg80211_put_bss(&wdev->auth_bsses[i]->pub); 154 cfg80211_put_bss(&wdev->auth_bsses[i]->pub);
155 wdev->auth_bsses[i] = NULL; 155 wdev->auth_bsses[i] = NULL;
156 found = true;
156 break; 157 break;
157 } 158 }
158 if (wdev->authtry_bsses[i] && 159 if (wdev->authtry_bsses[i] &&
@@ -160,10 +161,16 @@ void __cfg80211_send_deauth(struct net_device *dev,
160 cfg80211_unhold_bss(wdev->authtry_bsses[i]); 161 cfg80211_unhold_bss(wdev->authtry_bsses[i]);
161 cfg80211_put_bss(&wdev->authtry_bsses[i]->pub); 162 cfg80211_put_bss(&wdev->authtry_bsses[i]->pub);
162 wdev->authtry_bsses[i] = NULL; 163 wdev->authtry_bsses[i] = NULL;
164 found = true;
163 break; 165 break;
164 } 166 }
165 } 167 }
166 168
169 if (!found)
170 return;
171
172 nl80211_send_deauth(rdev, dev, buf, len, GFP_KERNEL);
173
167 if (wdev->sme_state == CFG80211_SME_CONNECTED) { 174 if (wdev->sme_state == CFG80211_SME_CONNECTED) {
168 u16 reason_code; 175 u16 reason_code;
169 bool from_ap; 176 bool from_ap;
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index a6028433e3a0..7cb0d647fc34 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -1637,39 +1637,6 @@ static int parse_station_flags(struct genl_info *info,
1637 return 0; 1637 return 0;
1638} 1638}
1639 1639
1640static u16 nl80211_calculate_bitrate(struct rate_info *rate)
1641{
1642 int modulation, streams, bitrate;
1643
1644 if (!(rate->flags & RATE_INFO_FLAGS_MCS))
1645 return rate->legacy;
1646
1647 /* the formula below does only work for MCS values smaller than 32 */
1648 if (rate->mcs >= 32)
1649 return 0;
1650
1651 modulation = rate->mcs & 7;
1652 streams = (rate->mcs >> 3) + 1;
1653
1654 bitrate = (rate->flags & RATE_INFO_FLAGS_40_MHZ_WIDTH) ?
1655 13500000 : 6500000;
1656
1657 if (modulation < 4)
1658 bitrate *= (modulation + 1);
1659 else if (modulation == 4)
1660 bitrate *= (modulation + 2);
1661 else
1662 bitrate *= (modulation + 3);
1663
1664 bitrate *= streams;
1665
1666 if (rate->flags & RATE_INFO_FLAGS_SHORT_GI)
1667 bitrate = (bitrate / 9) * 10;
1668
1669 /* do NOT round down here */
1670 return (bitrate + 50000) / 100000;
1671}
1672
1673static int nl80211_send_station(struct sk_buff *msg, u32 pid, u32 seq, 1640static int nl80211_send_station(struct sk_buff *msg, u32 pid, u32 seq,
1674 int flags, struct net_device *dev, 1641 int flags, struct net_device *dev,
1675 u8 *mac_addr, struct station_info *sinfo) 1642 u8 *mac_addr, struct station_info *sinfo)
@@ -1716,8 +1683,8 @@ static int nl80211_send_station(struct sk_buff *msg, u32 pid, u32 seq,
1716 if (!txrate) 1683 if (!txrate)
1717 goto nla_put_failure; 1684 goto nla_put_failure;
1718 1685
1719 /* nl80211_calculate_bitrate will return 0 for mcs >= 32 */ 1686 /* cfg80211_calculate_bitrate will return 0 for mcs >= 32 */
1720 bitrate = nl80211_calculate_bitrate(&sinfo->txrate); 1687 bitrate = cfg80211_calculate_bitrate(&sinfo->txrate);
1721 if (bitrate > 0) 1688 if (bitrate > 0)
1722 NLA_PUT_U16(msg, NL80211_RATE_INFO_BITRATE, bitrate); 1689 NLA_PUT_U16(msg, NL80211_RATE_INFO_BITRATE, bitrate);
1723 1690
diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index baa898add287..dc13c3ffeca6 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -40,6 +40,7 @@
40#include <net/cfg80211.h> 40#include <net/cfg80211.h>
41#include "core.h" 41#include "core.h"
42#include "reg.h" 42#include "reg.h"
43#include "regdb.h"
43#include "nl80211.h" 44#include "nl80211.h"
44 45
45/* Receipt of information from last regulatory request */ 46/* Receipt of information from last regulatory request */
@@ -335,6 +336,98 @@ static bool country_ie_integrity_changes(u32 checksum)
335 return false; 336 return false;
336} 337}
337 338
339static int reg_copy_regd(const struct ieee80211_regdomain **dst_regd,
340 const struct ieee80211_regdomain *src_regd)
341{
342 struct ieee80211_regdomain *regd;
343 int size_of_regd = 0;
344 unsigned int i;
345
346 size_of_regd = sizeof(struct ieee80211_regdomain) +
347 ((src_regd->n_reg_rules + 1) * sizeof(struct ieee80211_reg_rule));
348
349 regd = kzalloc(size_of_regd, GFP_KERNEL);
350 if (!regd)
351 return -ENOMEM;
352
353 memcpy(regd, src_regd, sizeof(struct ieee80211_regdomain));
354
355 for (i = 0; i < src_regd->n_reg_rules; i++)
356 memcpy(&regd->reg_rules[i], &src_regd->reg_rules[i],
357 sizeof(struct ieee80211_reg_rule));
358
359 *dst_regd = regd;
360 return 0;
361}
362
363#ifdef CONFIG_CFG80211_INTERNAL_REGDB
364struct reg_regdb_search_request {
365 char alpha2[2];
366 struct list_head list;
367};
368
369static LIST_HEAD(reg_regdb_search_list);
370static DEFINE_SPINLOCK(reg_regdb_search_lock);
371
372static void reg_regdb_search(struct work_struct *work)
373{
374 struct reg_regdb_search_request *request;
375 const struct ieee80211_regdomain *curdom, *regdom;
376 int i, r;
377
378 spin_lock(&reg_regdb_search_lock);
379 while (!list_empty(&reg_regdb_search_list)) {
380 request = list_first_entry(&reg_regdb_search_list,
381 struct reg_regdb_search_request,
382 list);
383 list_del(&request->list);
384
385 for (i=0; i<reg_regdb_size; i++) {
386 curdom = reg_regdb[i];
387
388 if (!memcmp(request->alpha2, curdom->alpha2, 2)) {
389 r = reg_copy_regd(&regdom, curdom);
390 if (r)
391 break;
392 spin_unlock(&reg_regdb_search_lock);
393 mutex_lock(&cfg80211_mutex);
394 set_regdom(regdom);
395 mutex_unlock(&cfg80211_mutex);
396 spin_lock(&reg_regdb_search_lock);
397 break;
398 }
399 }
400
401 kfree(request);
402 }
403 spin_unlock(&reg_regdb_search_lock);
404}
405
406static DECLARE_WORK(reg_regdb_work, reg_regdb_search);
407
408static void reg_regdb_query(const char *alpha2)
409{
410 struct reg_regdb_search_request *request;
411
412 if (!alpha2)
413 return;
414
415 request = kzalloc(sizeof(struct reg_regdb_search_request), GFP_KERNEL);
416 if (!request)
417 return;
418
419 memcpy(request->alpha2, alpha2, 2);
420
421 spin_lock(&reg_regdb_search_lock);
422 list_add_tail(&request->list, &reg_regdb_search_list);
423 spin_unlock(&reg_regdb_search_lock);
424
425 schedule_work(&reg_regdb_work);
426}
427#else
428static inline void reg_regdb_query(const char *alpha2) {}
429#endif /* CONFIG_CFG80211_INTERNAL_REGDB */
430
338/* 431/*
339 * This lets us keep regulatory code which is updated on a regulatory 432 * This lets us keep regulatory code which is updated on a regulatory
340 * basis in userspace. 433 * basis in userspace.
@@ -354,6 +447,9 @@ static int call_crda(const char *alpha2)
354 printk(KERN_INFO "cfg80211: Calling CRDA to update world " 447 printk(KERN_INFO "cfg80211: Calling CRDA to update world "
355 "regulatory domain\n"); 448 "regulatory domain\n");
356 449
450 /* query internal regulatory database (if it exists) */
451 reg_regdb_query(alpha2);
452
357 country_env[8] = alpha2[0]; 453 country_env[8] = alpha2[0];
358 country_env[9] = alpha2[1]; 454 country_env[9] = alpha2[1];
359 455
@@ -1342,30 +1438,6 @@ void wiphy_apply_custom_regulatory(struct wiphy *wiphy,
1342} 1438}
1343EXPORT_SYMBOL(wiphy_apply_custom_regulatory); 1439EXPORT_SYMBOL(wiphy_apply_custom_regulatory);
1344 1440
1345static int reg_copy_regd(const struct ieee80211_regdomain **dst_regd,
1346 const struct ieee80211_regdomain *src_regd)
1347{
1348 struct ieee80211_regdomain *regd;
1349 int size_of_regd = 0;
1350 unsigned int i;
1351
1352 size_of_regd = sizeof(struct ieee80211_regdomain) +
1353 ((src_regd->n_reg_rules + 1) * sizeof(struct ieee80211_reg_rule));
1354
1355 regd = kzalloc(size_of_regd, GFP_KERNEL);
1356 if (!regd)
1357 return -ENOMEM;
1358
1359 memcpy(regd, src_regd, sizeof(struct ieee80211_regdomain));
1360
1361 for (i = 0; i < src_regd->n_reg_rules; i++)
1362 memcpy(&regd->reg_rules[i], &src_regd->reg_rules[i],
1363 sizeof(struct ieee80211_reg_rule));
1364
1365 *dst_regd = regd;
1366 return 0;
1367}
1368
1369/* 1441/*
1370 * Return value which can be used by ignore_request() to indicate 1442 * Return value which can be used by ignore_request() to indicate
1371 * it has been determined we should intersect two regulatory domains 1443 * it has been determined we should intersect two regulatory domains
diff --git a/net/wireless/regdb.h b/net/wireless/regdb.h
new file mode 100644
index 000000000000..818222c92513
--- /dev/null
+++ b/net/wireless/regdb.h
@@ -0,0 +1,7 @@
1#ifndef __REGDB_H__
2#define __REGDB_H__
3
4extern const struct ieee80211_regdomain *reg_regdb[];
5extern int reg_regdb_size;
6
7#endif /* __REGDB_H__ */
diff --git a/net/wireless/util.c b/net/wireless/util.c
index 59361fdcb5d0..23557c1d0a9c 100644
--- a/net/wireless/util.c
+++ b/net/wireless/util.c
@@ -285,7 +285,7 @@ static int ieee80211_get_mesh_hdrlen(struct ieee80211s_hdr *meshhdr)
285 } 285 }
286} 286}
287 287
288int ieee80211_data_to_8023(struct sk_buff *skb, u8 *addr, 288int ieee80211_data_to_8023(struct sk_buff *skb, const u8 *addr,
289 enum nl80211_iftype iftype) 289 enum nl80211_iftype iftype)
290{ 290{
291 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; 291 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
@@ -383,7 +383,7 @@ int ieee80211_data_to_8023(struct sk_buff *skb, u8 *addr,
383} 383}
384EXPORT_SYMBOL(ieee80211_data_to_8023); 384EXPORT_SYMBOL(ieee80211_data_to_8023);
385 385
386int ieee80211_data_from_8023(struct sk_buff *skb, u8 *addr, 386int ieee80211_data_from_8023(struct sk_buff *skb, const u8 *addr,
387 enum nl80211_iftype iftype, u8 *bssid, bool qos) 387 enum nl80211_iftype iftype, u8 *bssid, bool qos)
388{ 388{
389 struct ieee80211_hdr hdr; 389 struct ieee80211_hdr hdr;
@@ -497,6 +497,101 @@ int ieee80211_data_from_8023(struct sk_buff *skb, u8 *addr,
497} 497}
498EXPORT_SYMBOL(ieee80211_data_from_8023); 498EXPORT_SYMBOL(ieee80211_data_from_8023);
499 499
500
501void ieee80211_amsdu_to_8023s(struct sk_buff *skb, struct sk_buff_head *list,
502 const u8 *addr, enum nl80211_iftype iftype,
503 const unsigned int extra_headroom)
504{
505 struct sk_buff *frame = NULL;
506 u16 ethertype;
507 u8 *payload;
508 const struct ethhdr *eth;
509 int remaining, err;
510 u8 dst[ETH_ALEN], src[ETH_ALEN];
511
512 err = ieee80211_data_to_8023(skb, addr, iftype);
513 if (err)
514 goto out;
515
516 /* skip the wrapping header */
517 eth = (struct ethhdr *) skb_pull(skb, sizeof(struct ethhdr));
518 if (!eth)
519 goto out;
520
521 while (skb != frame) {
522 u8 padding;
523 __be16 len = eth->h_proto;
524 unsigned int subframe_len = sizeof(struct ethhdr) + ntohs(len);
525
526 remaining = skb->len;
527 memcpy(dst, eth->h_dest, ETH_ALEN);
528 memcpy(src, eth->h_source, ETH_ALEN);
529
530 padding = (4 - subframe_len) & 0x3;
531 /* the last MSDU has no padding */
532 if (subframe_len > remaining)
533 goto purge;
534
535 skb_pull(skb, sizeof(struct ethhdr));
536 /* reuse skb for the last subframe */
537 if (remaining <= subframe_len + padding)
538 frame = skb;
539 else {
540 unsigned int hlen = ALIGN(extra_headroom, 4);
541 /*
542 * Allocate and reserve two bytes more for payload
543 * alignment since sizeof(struct ethhdr) is 14.
544 */
545 frame = dev_alloc_skb(hlen + subframe_len + 2);
546 if (!frame)
547 goto purge;
548
549 skb_reserve(frame, hlen + sizeof(struct ethhdr) + 2);
550 memcpy(skb_put(frame, ntohs(len)), skb->data,
551 ntohs(len));
552
553 eth = (struct ethhdr *)skb_pull(skb, ntohs(len) +
554 padding);
555 if (!eth) {
556 dev_kfree_skb(frame);
557 goto purge;
558 }
559 }
560
561 skb_reset_network_header(frame);
562 frame->dev = skb->dev;
563 frame->priority = skb->priority;
564
565 payload = frame->data;
566 ethertype = (payload[6] << 8) | payload[7];
567
568 if (likely((compare_ether_addr(payload, rfc1042_header) == 0 &&
569 ethertype != ETH_P_AARP && ethertype != ETH_P_IPX) ||
570 compare_ether_addr(payload,
571 bridge_tunnel_header) == 0)) {
572 /* remove RFC1042 or Bridge-Tunnel
573 * encapsulation and replace EtherType */
574 skb_pull(frame, 6);
575 memcpy(skb_push(frame, ETH_ALEN), src, ETH_ALEN);
576 memcpy(skb_push(frame, ETH_ALEN), dst, ETH_ALEN);
577 } else {
578 memcpy(skb_push(frame, sizeof(__be16)), &len,
579 sizeof(__be16));
580 memcpy(skb_push(frame, ETH_ALEN), src, ETH_ALEN);
581 memcpy(skb_push(frame, ETH_ALEN), dst, ETH_ALEN);
582 }
583 __skb_queue_tail(list, frame);
584 }
585
586 return;
587
588 purge:
589 __skb_queue_purge(list);
590 out:
591 dev_kfree_skb(skb);
592}
593EXPORT_SYMBOL(ieee80211_amsdu_to_8023s);
594
500/* Given a data frame determine the 802.1p/1d tag to use. */ 595/* Given a data frame determine the 802.1p/1d tag to use. */
501unsigned int cfg80211_classify8021d(struct sk_buff *skb) 596unsigned int cfg80211_classify8021d(struct sk_buff *skb)
502{ 597{
@@ -720,3 +815,36 @@ int cfg80211_change_iface(struct cfg80211_registered_device *rdev,
720 815
721 return err; 816 return err;
722} 817}
818
819u16 cfg80211_calculate_bitrate(struct rate_info *rate)
820{
821 int modulation, streams, bitrate;
822
823 if (!(rate->flags & RATE_INFO_FLAGS_MCS))
824 return rate->legacy;
825
826 /* the formula below does only work for MCS values smaller than 32 */
827 if (rate->mcs >= 32)
828 return 0;
829
830 modulation = rate->mcs & 7;
831 streams = (rate->mcs >> 3) + 1;
832
833 bitrate = (rate->flags & RATE_INFO_FLAGS_40_MHZ_WIDTH) ?
834 13500000 : 6500000;
835
836 if (modulation < 4)
837 bitrate *= (modulation + 1);
838 else if (modulation == 4)
839 bitrate *= (modulation + 2);
840 else
841 bitrate *= (modulation + 3);
842
843 bitrate *= streams;
844
845 if (rate->flags & RATE_INFO_FLAGS_SHORT_GI)
846 bitrate = (bitrate / 9) * 10;
847
848 /* do NOT round down here */
849 return (bitrate + 50000) / 100000;
850}
diff --git a/net/wireless/wext-compat.c b/net/wireless/wext-compat.c
index 54face3d4424..4198243a3dff 100644
--- a/net/wireless/wext-compat.c
+++ b/net/wireless/wext-compat.c
@@ -1257,10 +1257,7 @@ int cfg80211_wext_giwrate(struct net_device *dev,
1257 if (!(sinfo.filled & STATION_INFO_TX_BITRATE)) 1257 if (!(sinfo.filled & STATION_INFO_TX_BITRATE))
1258 return -EOPNOTSUPP; 1258 return -EOPNOTSUPP;
1259 1259
1260 rate->value = 0; 1260 rate->value = 100000 * cfg80211_calculate_bitrate(&sinfo.txrate);
1261
1262 if (!(sinfo.txrate.flags & RATE_INFO_FLAGS_MCS))
1263 rate->value = 100000 * sinfo.txrate.legacy;
1264 1261
1265 return 0; 1262 return 0;
1266} 1263}