aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless')
-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
69 files changed, 1437 insertions, 507 deletions
diff --git a/drivers/net/wireless/ath/ar9170/ar9170.h b/drivers/net/wireless/ath/ar9170/ar9170.h
index 9f9459860d8..b99a8c2053d 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 701ddb7d840..0a1d4c28e68 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 ddc8c09dc79..857e8610429 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 f9d6db8d013..20f04ab2b13 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 e0799d92405..0f361186b78 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 e2cef2ff5d8..9f1f523e02e 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 b66f72dbf7b..592f1b70f55 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 2ec61f08cfd..9474f9f6d40 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 e2b0c73a616..8849450dc59 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 9e68c1a8aef..3f5b887d0fc 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 9eb96f50699..4f6d6fd442f 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 ff9b5c88218..d7073281942 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 8414178bcff..0db1fda94a6 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 e413bd35bc4..d1bab141508 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 ecc23ec1f6a..28f6eb5f2cb 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 484c5fdf7c2..78706ce8b7a 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 33a5866538e..ec6b27689fa 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 74e57104927..a5a0ed4817a 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 1c9866daf81..771b03c1c7c 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 95a57b36a7e..dc61906290e 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 e9150753192..28f3800c560 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 574d3665870..e3b96b48b7f 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 27ca859e745..308f679ef81 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 d61293ab67c..58e0462cafa 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 21e0f6699da..ee5aed12a4b 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 165d1f6e2dd..42f9b17327c 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 e7d88d1da15..bf46308b17f 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 21361968ab7..0819f990be6 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 e5d8fa38432..6533122ed87 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 6d6ed748517..d32adeab68a 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 30aa9d48d67..0485c995757 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 b188cd97a05..45e870e3311 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 751067369ba..5e650f35841 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 42611bea76a..82371ef3952 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 2862748aef7..cb4138a55fd 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 21d57690c20..0334a58820e 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 6b6ea9f7bf5..ea3f10ef4e0 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 05bb298dfae..c348aff8f30 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 63d020374c2..3804a58d7f4 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 c2975c8e2f2..60bde1233a3 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 2f91c9b808a..954cd00f745 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 fea9b5d005f..e2573303a32 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 c6a6c042b82..4a0c3e3cd3b 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 315d1ce286c..52d244ea3d9 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 4b1aab593a8..71f88a08e09 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 88e41176e7f..718a5f198c3 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 2ecbedb26e1..305c106fdc1 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 dfc886fcb44..458378c4e50 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 af85d18cdbe..40295b454ff 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 1e4340a182e..d1d8ae94b4d 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 4d841c07c97..194dae01d0c 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 06c43ca39bf..d7711e4d475 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 0feb4d0e466..801be436cf1 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 239afc7a9c0..3d8fb684b4e 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 70775e5ba1a..c1e482bb37b 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 ced3b6ab5e1..6ce88d3c3b6 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 a1a3dd15c66..8a40a143998 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 054533f7a12..6301578d156 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 acfa086dbfc..beff084040b 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 652371432cd..26160c45784 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 a00723059f8..0ccba57fb9f 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 5cb573383ee..5aad56ea715 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 b3b25ec885e..269cefb3e7d 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 2f50a256efa..6aeffbe9e40 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 9931b197ff7..851dfb65e47 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 f84cc89cbff..b56732226cc 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 f8597061584..c8223185efd 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 7c1c1665c81..55856c6bb97 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 ac19ecd19cf..4daf1c94ec0 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;