aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/wireless/Kconfig14
-rw-r--r--drivers/net/wireless/ath/ath9k/btcoex.c10
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.c7
-rw-r--r--drivers/net/wireless/ath/ath9k/main.c12
-rw-r--r--drivers/net/wireless/b43/main.c3
-rw-r--r--drivers/net/wireless/b43/phy_a.c48
-rw-r--r--drivers/net/wireless/b43/phy_g.c53
-rw-r--r--drivers/net/wireless/b43/phy_lp.c3
-rw-r--r--drivers/net/wireless/b43/tables_lpphy.c309
-rw-r--r--drivers/net/wireless/ipw2x00/Kconfig6
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-rs.c56
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-rs.h1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.c39
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.h1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-power.c24
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-rx.c9
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-tx.c111
-rw-r--r--drivers/net/wireless/iwlwifi/iwl3945-base.c8
-rw-r--r--drivers/net/wireless/iwmc3200wifi/cfg80211.c66
-rw-r--r--drivers/net/wireless/iwmc3200wifi/commands.c1
-rw-r--r--drivers/net/wireless/iwmc3200wifi/debug.h2
-rw-r--r--drivers/net/wireless/iwmc3200wifi/debugfs.c105
-rw-r--r--drivers/net/wireless/iwmc3200wifi/fw.c56
-rw-r--r--drivers/net/wireless/iwmc3200wifi/iwm.h8
-rw-r--r--drivers/net/wireless/iwmc3200wifi/lmac.h15
-rw-r--r--drivers/net/wireless/iwmc3200wifi/main.c60
-rw-r--r--drivers/net/wireless/iwmc3200wifi/rx.c87
-rw-r--r--drivers/net/wireless/rndis_wlan.c98
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00crypto.c6
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00dev.c38
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00lib.h45
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00queue.c99
32 files changed, 877 insertions, 523 deletions
diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig
index dda7cc2e1f57..a8871a84d87e 100644
--- a/drivers/net/wireless/Kconfig
+++ b/drivers/net/wireless/Kconfig
@@ -2,8 +2,17 @@
2# Wireless LAN device configuration 2# Wireless LAN device configuration
3# 3#
4 4
5menu "Wireless LAN" 5menuconfig WLAN
6 bool "Wireless LAN"
6 depends on !S390 7 depends on !S390
8 ---help---
9 This section contains all the pre 802.11 and 802.11 wireless
10 device drivers. For a complete list of drivers and documentation
11 on them refer to the wireless wiki:
12
13 http://wireless.kernel.org/en/users/Drivers
14
15if WLAN
7 16
8menuconfig WLAN_PRE80211 17menuconfig WLAN_PRE80211
9 bool "Wireless LAN (pre-802.11)" 18 bool "Wireless LAN (pre-802.11)"
@@ -337,7 +346,6 @@ config USB_NET_RNDIS_WLAN
337 select USB_USBNET 346 select USB_USBNET
338 select USB_NET_CDCETHER 347 select USB_NET_CDCETHER
339 select USB_NET_RNDIS_HOST 348 select USB_NET_RNDIS_HOST
340 select WIRELESS_EXT
341 ---help--- 349 ---help---
342 This is a driver for wireless RNDIS devices. 350 This is a driver for wireless RNDIS devices.
343 These are USB based adapters found in devices such as: 351 These are USB based adapters found in devices such as:
@@ -506,4 +514,4 @@ source "drivers/net/wireless/orinoco/Kconfig"
506source "drivers/net/wireless/wl12xx/Kconfig" 514source "drivers/net/wireless/wl12xx/Kconfig"
507source "drivers/net/wireless/iwmc3200wifi/Kconfig" 515source "drivers/net/wireless/iwmc3200wifi/Kconfig"
508 516
509endmenu 517endif # WLAN
diff --git a/drivers/net/wireless/ath/ath9k/btcoex.c b/drivers/net/wireless/ath/ath9k/btcoex.c
index 8fb356748823..e8bfb01ee78a 100644
--- a/drivers/net/wireless/ath/ath9k/btcoex.c
+++ b/drivers/net/wireless/ath/ath9k/btcoex.c
@@ -84,15 +84,14 @@ static void ath_btcoex_period_timer(unsigned long data)
84{ 84{
85 struct ath_softc *sc = (struct ath_softc *) data; 85 struct ath_softc *sc = (struct ath_softc *) data;
86 struct ath_btcoex_info *btinfo = &sc->btcoex_info; 86 struct ath_btcoex_info *btinfo = &sc->btcoex_info;
87 unsigned long flags;
88 87
89 ath_detect_bt_priority(sc); 88 ath_detect_bt_priority(sc);
90 89
91 spin_lock_irqsave(&btinfo->btcoex_lock, flags); 90 spin_lock_bh(&btinfo->btcoex_lock);
92 91
93 ath_btcoex_bt_stomp(sc, btinfo, btinfo->bt_stomp_type); 92 ath_btcoex_bt_stomp(sc, btinfo, btinfo->bt_stomp_type);
94 93
95 spin_unlock_irqrestore(&btinfo->btcoex_lock, flags); 94 spin_unlock_bh(&btinfo->btcoex_lock);
96 95
97 if (btinfo->btcoex_period != btinfo->btcoex_no_stomp) { 96 if (btinfo->btcoex_period != btinfo->btcoex_no_stomp) {
98 if (btinfo->hw_timer_enabled) 97 if (btinfo->hw_timer_enabled)
@@ -119,18 +118,17 @@ static void ath_btcoex_no_stomp_timer(void *arg)
119{ 118{
120 struct ath_softc *sc = (struct ath_softc *)arg; 119 struct ath_softc *sc = (struct ath_softc *)arg;
121 struct ath_btcoex_info *btinfo = &sc->btcoex_info; 120 struct ath_btcoex_info *btinfo = &sc->btcoex_info;
122 unsigned long flags;
123 121
124 DPRINTF(sc, ATH_DBG_BTCOEX, "no stomp timer running \n"); 122 DPRINTF(sc, ATH_DBG_BTCOEX, "no stomp timer running \n");
125 123
126 spin_lock_irqsave(&btinfo->btcoex_lock, flags); 124 spin_lock_bh(&btinfo->btcoex_lock);
127 125
128 if (btinfo->bt_stomp_type == ATH_BTCOEX_STOMP_LOW) 126 if (btinfo->bt_stomp_type == ATH_BTCOEX_STOMP_LOW)
129 ath_btcoex_bt_stomp(sc, btinfo, ATH_BTCOEX_STOMP_NONE); 127 ath_btcoex_bt_stomp(sc, btinfo, ATH_BTCOEX_STOMP_NONE);
130 else if (btinfo->bt_stomp_type == ATH_BTCOEX_STOMP_ALL) 128 else if (btinfo->bt_stomp_type == ATH_BTCOEX_STOMP_ALL)
131 ath_btcoex_bt_stomp(sc, btinfo, ATH_BTCOEX_STOMP_LOW); 129 ath_btcoex_bt_stomp(sc, btinfo, ATH_BTCOEX_STOMP_LOW);
132 130
133 spin_unlock_irqrestore(&btinfo->btcoex_lock, flags); 131 spin_unlock_bh(&btinfo->btcoex_lock);
134} 132}
135 133
136static int ath_init_btcoex_info(struct ath_hw *hw, 134static int ath_init_btcoex_info(struct ath_hw *hw,
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index e340dacc6ebe..71f27f324cea 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -1712,8 +1712,15 @@ static bool ath9k_hw_set_reset_power_on(struct ath_hw *ah)
1712 REG_WRITE(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_EN | 1712 REG_WRITE(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_EN |
1713 AR_RTC_FORCE_WAKE_ON_INT); 1713 AR_RTC_FORCE_WAKE_ON_INT);
1714 1714
1715 if (!AR_SREV_9100(ah))
1716 REG_WRITE(ah, AR_RC, AR_RC_AHB);
1717
1715 REG_WRITE(ah, AR_RTC_RESET, 0); 1718 REG_WRITE(ah, AR_RTC_RESET, 0);
1716 udelay(2); 1719 udelay(2);
1720
1721 if (!AR_SREV_9100(ah))
1722 REG_WRITE(ah, AR_RC, 0);
1723
1717 REG_WRITE(ah, AR_RTC_RESET, 1); 1724 REG_WRITE(ah, AR_RTC_RESET, 1);
1718 1725
1719 if (!ath9k_hw_wait(ah, 1726 if (!ath9k_hw_wait(ah,
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 4fae699a53c2..c2efdf2d72d3 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -506,6 +506,10 @@ static void ath9k_tasklet(unsigned long data)
506 sc->sc_flags |= SC_OP_WAIT_FOR_BEACON | SC_OP_BEACON_SYNC; 506 sc->sc_flags |= SC_OP_WAIT_FOR_BEACON | SC_OP_BEACON_SYNC;
507 } 507 }
508 508
509 if (sc->btcoex_info.btcoex_scheme == ATH_BTCOEX_CFG_3WIRE)
510 if (status & ATH9K_INT_GENTIMER)
511 ath_gen_timer_isr(sc->sc_ah);
512
509 /* re-enable hardware interrupt */ 513 /* re-enable hardware interrupt */
510 ath9k_hw_set_interrupts(sc->sc_ah, sc->imask); 514 ath9k_hw_set_interrupts(sc->sc_ah, sc->imask);
511 ath9k_ps_restore(sc); 515 ath9k_ps_restore(sc);
@@ -521,7 +525,8 @@ irqreturn_t ath_isr(int irq, void *dev)
521 ATH9K_INT_TX | \ 525 ATH9K_INT_TX | \
522 ATH9K_INT_BMISS | \ 526 ATH9K_INT_BMISS | \
523 ATH9K_INT_CST | \ 527 ATH9K_INT_CST | \
524 ATH9K_INT_TSFOOR) 528 ATH9K_INT_TSFOOR | \
529 ATH9K_INT_GENTIMER)
525 530
526 struct ath_softc *sc = dev; 531 struct ath_softc *sc = dev;
527 struct ath_hw *ah = sc->sc_ah; 532 struct ath_hw *ah = sc->sc_ah;
@@ -602,10 +607,6 @@ irqreturn_t ath_isr(int irq, void *dev)
602 sc->sc_flags |= SC_OP_WAIT_FOR_BEACON; 607 sc->sc_flags |= SC_OP_WAIT_FOR_BEACON;
603 } 608 }
604 609
605 if (sc->btcoex_info.btcoex_scheme == ATH_BTCOEX_CFG_3WIRE)
606 if (status & ATH9K_INT_GENTIMER)
607 ath_gen_timer_isr(ah);
608
609chip_reset: 610chip_reset:
610 611
611 ath_debug_stat_interrupt(sc, status); 612 ath_debug_stat_interrupt(sc, status);
@@ -2772,6 +2773,7 @@ static void ath9k_sw_scan_complete(struct ieee80211_hw *hw)
2772 sc->sc_flags &= ~SC_OP_SCANNING; 2773 sc->sc_flags &= ~SC_OP_SCANNING;
2773 sc->sc_flags |= SC_OP_FULL_RESET; 2774 sc->sc_flags |= SC_OP_FULL_RESET;
2774 spin_unlock_bh(&sc->ani_lock); 2775 spin_unlock_bh(&sc->ani_lock);
2776 ath_beacon_config(sc, NULL);
2775 mutex_unlock(&sc->mutex); 2777 mutex_unlock(&sc->mutex);
2776} 2778}
2777 2779
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index 0f168443ad49..ae05f6671149 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -58,6 +58,7 @@ MODULE_DESCRIPTION("Broadcom B43 wireless driver");
58MODULE_AUTHOR("Martin Langer"); 58MODULE_AUTHOR("Martin Langer");
59MODULE_AUTHOR("Stefano Brivio"); 59MODULE_AUTHOR("Stefano Brivio");
60MODULE_AUTHOR("Michael Buesch"); 60MODULE_AUTHOR("Michael Buesch");
61MODULE_AUTHOR("Gábor Stefanik");
61MODULE_LICENSE("GPL"); 62MODULE_LICENSE("GPL");
62 63
63MODULE_FIRMWARE(B43_SUPPORTED_FIRMWARE_ID); 64MODULE_FIRMWARE(B43_SUPPORTED_FIRMWARE_ID);
@@ -90,7 +91,7 @@ MODULE_PARM_DESC(qos, "Enable QOS support (default on)");
90 91
91static int modparam_btcoex = 1; 92static int modparam_btcoex = 1;
92module_param_named(btcoex, modparam_btcoex, int, 0444); 93module_param_named(btcoex, modparam_btcoex, int, 0444);
93MODULE_PARM_DESC(btcoex, "Enable Bluetooth coexistance (default on)"); 94MODULE_PARM_DESC(btcoex, "Enable Bluetooth coexistence (default on)");
94 95
95int b43_modparam_verbose = B43_VERBOSITY_DEFAULT; 96int b43_modparam_verbose = B43_VERBOSITY_DEFAULT;
96module_param_named(verbose, b43_modparam_verbose, int, 0644); 97module_param_named(verbose, b43_modparam_verbose, int, 0644);
diff --git a/drivers/net/wireless/b43/phy_a.c b/drivers/net/wireless/b43/phy_a.c
index 809ec97031cb..d90217c3a706 100644
--- a/drivers/net/wireless/b43/phy_a.c
+++ b/drivers/net/wireless/b43/phy_a.c
@@ -518,58 +518,40 @@ static unsigned int b43_aphy_op_get_default_chan(struct b43_wldev *dev)
518static void b43_aphy_op_set_rx_antenna(struct b43_wldev *dev, int antenna) 518static void b43_aphy_op_set_rx_antenna(struct b43_wldev *dev, int antenna)
519{//TODO 519{//TODO
520 struct b43_phy *phy = &dev->phy; 520 struct b43_phy *phy = &dev->phy;
521 u64 hf;
522 u16 tmp; 521 u16 tmp;
523 int autodiv = 0; 522 int autodiv = 0;
524 523
525 if (antenna == B43_ANTENNA_AUTO0 || antenna == B43_ANTENNA_AUTO1) 524 if (antenna == B43_ANTENNA_AUTO0 || antenna == B43_ANTENNA_AUTO1)
526 autodiv = 1; 525 autodiv = 1;
527 526
528 hf = b43_hf_read(dev); 527 b43_hf_write(dev, b43_hf_read(dev) & ~B43_HF_ANTDIVHELP);
529 hf &= ~B43_HF_ANTDIVHELP;
530 b43_hf_write(dev, hf);
531 528
532 tmp = b43_phy_read(dev, B43_PHY_BBANDCFG); 529 b43_phy_maskset(dev, B43_PHY_BBANDCFG, ~B43_PHY_BBANDCFG_RXANT,
533 tmp &= ~B43_PHY_BBANDCFG_RXANT; 530 (autodiv ? B43_ANTENNA_AUTO1 : antenna) <<
534 tmp |= (autodiv ? B43_ANTENNA_AUTO1 : antenna) 531 B43_PHY_BBANDCFG_RXANT_SHIFT);
535 << B43_PHY_BBANDCFG_RXANT_SHIFT;
536 b43_phy_write(dev, B43_PHY_BBANDCFG, tmp);
537 532
538 if (autodiv) { 533 if (autodiv) {
539 tmp = b43_phy_read(dev, B43_PHY_ANTDWELL); 534 tmp = b43_phy_read(dev, B43_PHY_ANTDWELL);
540 if (antenna == B43_ANTENNA_AUTO0) 535 if (antenna == B43_ANTENNA_AUTO1)
541 tmp &= ~B43_PHY_ANTDWELL_AUTODIV1; 536 tmp &= ~B43_PHY_ANTDWELL_AUTODIV1;
542 else 537 else
543 tmp |= B43_PHY_ANTDWELL_AUTODIV1; 538 tmp |= B43_PHY_ANTDWELL_AUTODIV1;
544 b43_phy_write(dev, B43_PHY_ANTDWELL, tmp); 539 b43_phy_write(dev, B43_PHY_ANTDWELL, tmp);
545 } 540 }
546 if (phy->rev < 3) { 541 if (phy->rev < 3)
547 tmp = b43_phy_read(dev, B43_PHY_ANTDWELL); 542 b43_phy_maskset(dev, B43_PHY_ANTDWELL, 0xFF00, 0x24);
548 tmp = (tmp & 0xFF00) | 0x24; 543 else {
549 b43_phy_write(dev, B43_PHY_ANTDWELL, tmp); 544 b43_phy_set(dev, B43_PHY_OFDM61, 0x10);
550 } else { 545 if (phy->rev == 3) {
551 tmp = b43_phy_read(dev, B43_PHY_OFDM61); 546 b43_phy_write(dev, B43_PHY_CLIPPWRDOWNT, 0x1D);
552 tmp |= 0x10; 547 b43_phy_write(dev, B43_PHY_ADIVRELATED, 8);
553 b43_phy_write(dev, B43_PHY_OFDM61, tmp);
554 if (phy->analog == 3) {
555 b43_phy_write(dev, B43_PHY_CLIPPWRDOWNT,
556 0x1D);
557 b43_phy_write(dev, B43_PHY_ADIVRELATED,
558 8);
559 } else { 548 } else {
560 b43_phy_write(dev, B43_PHY_CLIPPWRDOWNT, 549 b43_phy_write(dev, B43_PHY_CLIPPWRDOWNT, 0x3A);
561 0x3A); 550 b43_phy_maskset(dev, B43_PHY_ADIVRELATED, 0xFF00, 8);
562 tmp =
563 b43_phy_read(dev,
564 B43_PHY_ADIVRELATED);
565 tmp = (tmp & 0xFF00) | 8;
566 b43_phy_write(dev, B43_PHY_ADIVRELATED,
567 tmp);
568 } 551 }
569 } 552 }
570 553
571 hf |= B43_HF_ANTDIVHELP; 554 b43_hf_write(dev, b43_hf_read(dev) | B43_HF_ANTDIVHELP);
572 b43_hf_write(dev, hf);
573} 555}
574 556
575static void b43_aphy_op_adjust_txpower(struct b43_wldev *dev) 557static void b43_aphy_op_adjust_txpower(struct b43_wldev *dev)
diff --git a/drivers/net/wireless/b43/phy_g.c b/drivers/net/wireless/b43/phy_g.c
index bdff9afe3f81..5afa4df0b02f 100644
--- a/drivers/net/wireless/b43/phy_g.c
+++ b/drivers/net/wireless/b43/phy_g.c
@@ -2651,65 +2651,54 @@ static unsigned int b43_gphy_op_get_default_chan(struct b43_wldev *dev)
2651static void b43_gphy_op_set_rx_antenna(struct b43_wldev *dev, int antenna) 2651static void b43_gphy_op_set_rx_antenna(struct b43_wldev *dev, int antenna)
2652{ 2652{
2653 struct b43_phy *phy = &dev->phy; 2653 struct b43_phy *phy = &dev->phy;
2654 u64 hf;
2655 u16 tmp; 2654 u16 tmp;
2656 int autodiv = 0; 2655 int autodiv = 0;
2657 2656
2658 if (antenna == B43_ANTENNA_AUTO0 || antenna == B43_ANTENNA_AUTO1) 2657 if (antenna == B43_ANTENNA_AUTO0 || antenna == B43_ANTENNA_AUTO1)
2659 autodiv = 1; 2658 autodiv = 1;
2660 2659
2661 hf = b43_hf_read(dev); 2660 b43_hf_write(dev, b43_hf_read(dev) & ~B43_HF_ANTDIVHELP);
2662 hf &= ~B43_HF_ANTDIVHELP;
2663 b43_hf_write(dev, hf);
2664 2661
2665 tmp = b43_phy_read(dev, B43_PHY_BBANDCFG); 2662 b43_phy_maskset(dev, B43_PHY_BBANDCFG, ~B43_PHY_BBANDCFG_RXANT,
2666 tmp &= ~B43_PHY_BBANDCFG_RXANT; 2663 (autodiv ? B43_ANTENNA_AUTO1 : antenna) <<
2667 tmp |= (autodiv ? B43_ANTENNA_AUTO1 : antenna) 2664 B43_PHY_BBANDCFG_RXANT_SHIFT);
2668 << B43_PHY_BBANDCFG_RXANT_SHIFT;
2669 b43_phy_write(dev, B43_PHY_BBANDCFG, tmp);
2670 2665
2671 if (autodiv) { 2666 if (autodiv) {
2672 tmp = b43_phy_read(dev, B43_PHY_ANTDWELL); 2667 tmp = b43_phy_read(dev, B43_PHY_ANTDWELL);
2673 if (antenna == B43_ANTENNA_AUTO0) 2668 if (antenna == B43_ANTENNA_AUTO1)
2674 tmp &= ~B43_PHY_ANTDWELL_AUTODIV1; 2669 tmp &= ~B43_PHY_ANTDWELL_AUTODIV1;
2675 else 2670 else
2676 tmp |= B43_PHY_ANTDWELL_AUTODIV1; 2671 tmp |= B43_PHY_ANTDWELL_AUTODIV1;
2677 b43_phy_write(dev, B43_PHY_ANTDWELL, tmp); 2672 b43_phy_write(dev, B43_PHY_ANTDWELL, tmp);
2678 } 2673 }
2674
2679 tmp = b43_phy_read(dev, B43_PHY_ANTWRSETT); 2675 tmp = b43_phy_read(dev, B43_PHY_ANTWRSETT);
2680 if (autodiv) 2676 if (autodiv)
2681 tmp |= B43_PHY_ANTWRSETT_ARXDIV; 2677 tmp |= B43_PHY_ANTWRSETT_ARXDIV;
2682 else 2678 else
2683 tmp &= ~B43_PHY_ANTWRSETT_ARXDIV; 2679 tmp &= ~B43_PHY_ANTWRSETT_ARXDIV;
2684 b43_phy_write(dev, B43_PHY_ANTWRSETT, tmp); 2680 b43_phy_write(dev, B43_PHY_ANTWRSETT, tmp);
2685 if (phy->rev >= 2) {
2686 tmp = b43_phy_read(dev, B43_PHY_OFDM61);
2687 tmp |= B43_PHY_OFDM61_10;
2688 b43_phy_write(dev, B43_PHY_OFDM61, tmp);
2689 2681
2690 tmp = 2682 if (autodiv)
2691 b43_phy_read(dev, B43_PHY_DIVSRCHGAINBACK); 2683 b43_phy_set(dev, B43_PHY_ANTWRSETT, B43_PHY_ANTWRSETT_ARXDIV);
2692 tmp = (tmp & 0xFF00) | 0x15; 2684 else {
2693 b43_phy_write(dev, B43_PHY_DIVSRCHGAINBACK, 2685 b43_phy_mask(dev, B43_PHY_ANTWRSETT,
2694 tmp); 2686 B43_PHY_ANTWRSETT_ARXDIV);
2687 }
2695 2688
2696 if (phy->rev == 2) { 2689 if (phy->rev >= 2) {
2697 b43_phy_write(dev, B43_PHY_ADIVRELATED, 2690 b43_phy_set(dev, B43_PHY_OFDM61, B43_PHY_OFDM61_10);
2698 8); 2691 b43_phy_maskset(dev, B43_PHY_DIVSRCHGAINBACK, 0xFF00, 0x15);
2699 } else { 2692
2700 tmp = 2693 if (phy->rev == 2)
2701 b43_phy_read(dev, 2694 b43_phy_write(dev, B43_PHY_ADIVRELATED, 8);
2702 B43_PHY_ADIVRELATED); 2695 else
2703 tmp = (tmp & 0xFF00) | 8; 2696 b43_phy_maskset(dev, B43_PHY_ADIVRELATED, 0xFF00, 8);
2704 b43_phy_write(dev, B43_PHY_ADIVRELATED,
2705 tmp);
2706 }
2707 } 2697 }
2708 if (phy->rev >= 6) 2698 if (phy->rev >= 6)
2709 b43_phy_write(dev, B43_PHY_OFDM9B, 0xDC); 2699 b43_phy_write(dev, B43_PHY_OFDM9B, 0xDC);
2710 2700
2711 hf |= B43_HF_ANTDIVHELP; 2701 b43_hf_write(dev, b43_hf_read(dev) | B43_HF_ANTDIVHELP);
2712 b43_hf_write(dev, hf);
2713} 2702}
2714 2703
2715static int b43_gphy_op_interf_mitigation(struct b43_wldev *dev, 2704static int b43_gphy_op_interf_mitigation(struct b43_wldev *dev,
diff --git a/drivers/net/wireless/b43/phy_lp.c b/drivers/net/wireless/b43/phy_lp.c
index 1ab00b034cbd..3e02d969f683 100644
--- a/drivers/net/wireless/b43/phy_lp.c
+++ b/drivers/net/wireless/b43/phy_lp.c
@@ -1,9 +1,10 @@
1/* 1/*
2 2
3 Broadcom B43 wireless driver 3 Broadcom B43 wireless driver
4 IEEE 802.11g LP-PHY driver 4 IEEE 802.11a/g LP-PHY driver
5 5
6 Copyright (c) 2008-2009 Michael Buesch <mb@bu3sch.de> 6 Copyright (c) 2008-2009 Michael Buesch <mb@bu3sch.de>
7 Copyright (c) 2009 Gábor Stefanik <netrolller.3d@gmail.com>
7 8
8 This program is free software; you can redistribute it and/or modify 9 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by 10 it under the terms of the GNU General Public License as published by
diff --git a/drivers/net/wireless/b43/tables_lpphy.c b/drivers/net/wireless/b43/tables_lpphy.c
index c784def19b19..61027ee84fb5 100644
--- a/drivers/net/wireless/b43/tables_lpphy.c
+++ b/drivers/net/wireless/b43/tables_lpphy.c
@@ -1,9 +1,10 @@
1/* 1/*
2 2
3 Broadcom B43 wireless driver 3 Broadcom B43 wireless driver
4 IEEE 802.11g LP-PHY and radio device data tables 4 IEEE 802.11a/g LP-PHY and radio device data tables
5 5
6 Copyright (c) 2009 Michael Buesch <mb@bu3sch.de> 6 Copyright (c) 2009 Michael Buesch <mb@bu3sch.de>
7 Copyright (c) 2009 Gábor Stefanik <netrolller.3d@gmail.com>
7 8
8 This program is free software; you can redistribute it and/or modify 9 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by 10 it under the terms of the GNU General Public License as published by
@@ -1612,11 +1613,62 @@ static struct lpphy_tx_gain_table_entry lpphy_rev1_nopa_tx_gain_table[] = {
1612}; 1613};
1613 1614
1614static struct lpphy_tx_gain_table_entry lpphy_rev1_2ghz_tx_gain_table[] = { 1615static struct lpphy_tx_gain_table_entry lpphy_rev1_2ghz_tx_gain_table[] = {
1615 { .gm = 4, .pga = 15, .pad = 9, .dac = 0, .bb_mult = 85, }, 1616 { .gm = 4, .pga = 15, .pad = 15, .dac = 0, .bb_mult = 90, },
1616 { .gm = 4, .pga = 15, .pad = 9, .dac = 0, .bb_mult = 81, }, 1617 { .gm = 4, .pga = 15, .pad = 15, .dac = 0, .bb_mult = 88, },
1617 { .gm = 4, .pga = 15, .pad = 9, .dac = 0, .bb_mult = 78, }, 1618 { .gm = 4, .pga = 15, .pad = 15, .dac = 0, .bb_mult = 85, },
1618 { .gm = 4, .pga = 15, .pad = 9, .dac = 0, .bb_mult = 76, }, 1619 { .gm = 4, .pga = 15, .pad = 15, .dac = 0, .bb_mult = 83, },
1619 { .gm = 4, .pga = 15, .pad = 9, .dac = 0, .bb_mult = 74, }, 1620 { .gm = 4, .pga = 15, .pad = 15, .dac = 0, .bb_mult = 81, },
1621 { .gm = 4, .pga = 15, .pad = 15, .dac = 0, .bb_mult = 78, },
1622 { .gm = 4, .pga = 15, .pad = 15, .dac = 0, .bb_mult = 76, },
1623 { .gm = 4, .pga = 15, .pad = 15, .dac = 0, .bb_mult = 74, },
1624 { .gm = 4, .pga = 15, .pad = 15, .dac = 0, .bb_mult = 72, },
1625 { .gm = 4, .pga = 15, .pad = 15, .dac = 0, .bb_mult = 70, },
1626 { .gm = 4, .pga = 15, .pad = 15, .dac = 0, .bb_mult = 68, },
1627 { .gm = 4, .pga = 15, .pad = 15, .dac = 0, .bb_mult = 66, },
1628 { .gm = 4, .pga = 15, .pad = 15, .dac = 0, .bb_mult = 64, },
1629 { .gm = 4, .pga = 15, .pad = 15, .dac = 0, .bb_mult = 62, },
1630 { .gm = 4, .pga = 15, .pad = 15, .dac = 0, .bb_mult = 60, },
1631 { .gm = 4, .pga = 15, .pad = 15, .dac = 0, .bb_mult = 59, },
1632 { .gm = 4, .pga = 15, .pad = 14, .dac = 0, .bb_mult = 72, },
1633 { .gm = 4, .pga = 15, .pad = 14, .dac = 0, .bb_mult = 70, },
1634 { .gm = 4, .pga = 15, .pad = 14, .dac = 0, .bb_mult = 68, },
1635 { .gm = 4, .pga = 15, .pad = 14, .dac = 0, .bb_mult = 66, },
1636 { .gm = 4, .pga = 15, .pad = 14, .dac = 0, .bb_mult = 64, },
1637 { .gm = 4, .pga = 15, .pad = 14, .dac = 0, .bb_mult = 62, },
1638 { .gm = 4, .pga = 15, .pad = 14, .dac = 0, .bb_mult = 60, },
1639 { .gm = 4, .pga = 15, .pad = 14, .dac = 0, .bb_mult = 59, },
1640 { .gm = 4, .pga = 15, .pad = 13, .dac = 0, .bb_mult = 72, },
1641 { .gm = 4, .pga = 15, .pad = 13, .dac = 0, .bb_mult = 70, },
1642 { .gm = 4, .pga = 15, .pad = 13, .dac = 0, .bb_mult = 68, },
1643 { .gm = 4, .pga = 15, .pad = 13, .dac = 0, .bb_mult = 66, },
1644 { .gm = 4, .pga = 15, .pad = 13, .dac = 0, .bb_mult = 64, },
1645 { .gm = 4, .pga = 15, .pad = 13, .dac = 0, .bb_mult = 62, },
1646 { .gm = 4, .pga = 15, .pad = 13, .dac = 0, .bb_mult = 60, },
1647 { .gm = 4, .pga = 15, .pad = 13, .dac = 0, .bb_mult = 59, },
1648 { .gm = 4, .pga = 15, .pad = 12, .dac = 0, .bb_mult = 72, },
1649 { .gm = 4, .pga = 15, .pad = 12, .dac = 0, .bb_mult = 70, },
1650 { .gm = 4, .pga = 15, .pad = 12, .dac = 0, .bb_mult = 68, },
1651 { .gm = 4, .pga = 15, .pad = 12, .dac = 0, .bb_mult = 66, },
1652 { .gm = 4, .pga = 15, .pad = 12, .dac = 0, .bb_mult = 64, },
1653 { .gm = 4, .pga = 15, .pad = 12, .dac = 0, .bb_mult = 62, },
1654 { .gm = 4, .pga = 15, .pad = 12, .dac = 0, .bb_mult = 60, },
1655 { .gm = 4, .pga = 15, .pad = 12, .dac = 0, .bb_mult = 59, },
1656 { .gm = 4, .pga = 15, .pad = 11, .dac = 0, .bb_mult = 72, },
1657 { .gm = 4, .pga = 15, .pad = 11, .dac = 0, .bb_mult = 70, },
1658 { .gm = 4, .pga = 15, .pad = 11, .dac = 0, .bb_mult = 68, },
1659 { .gm = 4, .pga = 15, .pad = 11, .dac = 0, .bb_mult = 66, },
1660 { .gm = 4, .pga = 15, .pad = 11, .dac = 0, .bb_mult = 64, },
1661 { .gm = 4, .pga = 15, .pad = 11, .dac = 0, .bb_mult = 62, },
1662 { .gm = 4, .pga = 15, .pad = 11, .dac = 0, .bb_mult = 60, },
1663 { .gm = 4, .pga = 15, .pad = 11, .dac = 0, .bb_mult = 59, },
1664 { .gm = 4, .pga = 15, .pad = 10, .dac = 0, .bb_mult = 72, },
1665 { .gm = 4, .pga = 15, .pad = 10, .dac = 0, .bb_mult = 70, },
1666 { .gm = 4, .pga = 15, .pad = 10, .dac = 0, .bb_mult = 68, },
1667 { .gm = 4, .pga = 15, .pad = 10, .dac = 0, .bb_mult = 66, },
1668 { .gm = 4, .pga = 15, .pad = 10, .dac = 0, .bb_mult = 64, },
1669 { .gm = 4, .pga = 15, .pad = 10, .dac = 0, .bb_mult = 62, },
1670 { .gm = 4, .pga = 15, .pad = 10, .dac = 0, .bb_mult = 60, },
1671 { .gm = 4, .pga = 15, .pad = 10, .dac = 0, .bb_mult = 59, },
1620 { .gm = 4, .pga = 15, .pad = 9, .dac = 0, .bb_mult = 72, }, 1672 { .gm = 4, .pga = 15, .pad = 9, .dac = 0, .bb_mult = 72, },
1621 { .gm = 4, .pga = 15, .pad = 9, .dac = 0, .bb_mult = 70, }, 1673 { .gm = 4, .pga = 15, .pad = 9, .dac = 0, .bb_mult = 70, },
1622 { .gm = 4, .pga = 15, .pad = 9, .dac = 0, .bb_mult = 68, }, 1674 { .gm = 4, .pga = 15, .pad = 9, .dac = 0, .bb_mult = 68, },
@@ -1689,57 +1741,6 @@ static struct lpphy_tx_gain_table_entry lpphy_rev1_2ghz_tx_gain_table[] = {
1689 { .gm = 4, .pga = 10, .pad = 6, .dac = 0, .bb_mult = 64, }, 1741 { .gm = 4, .pga = 10, .pad = 6, .dac = 0, .bb_mult = 64, },
1690 { .gm = 4, .pga = 10, .pad = 6, .dac = 0, .bb_mult = 62, }, 1742 { .gm = 4, .pga = 10, .pad = 6, .dac = 0, .bb_mult = 62, },
1691 { .gm = 4, .pga = 10, .pad = 6, .dac = 0, .bb_mult = 60, }, 1743 { .gm = 4, .pga = 10, .pad = 6, .dac = 0, .bb_mult = 60, },
1692 { .gm = 4, .pga = 10, .pad = 6, .dac = 0, .bb_mult = 59, },
1693 { .gm = 4, .pga = 10, .pad = 5, .dac = 0, .bb_mult = 72, },
1694 { .gm = 4, .pga = 10, .pad = 5, .dac = 0, .bb_mult = 70, },
1695 { .gm = 4, .pga = 10, .pad = 5, .dac = 0, .bb_mult = 68, },
1696 { .gm = 4, .pga = 10, .pad = 5, .dac = 0, .bb_mult = 66, },
1697 { .gm = 4, .pga = 10, .pad = 5, .dac = 0, .bb_mult = 64, },
1698 { .gm = 4, .pga = 10, .pad = 5, .dac = 0, .bb_mult = 62, },
1699 { .gm = 4, .pga = 10, .pad = 5, .dac = 0, .bb_mult = 60, },
1700 { .gm = 4, .pga = 10, .pad = 5, .dac = 0, .bb_mult = 59, },
1701 { .gm = 4, .pga = 9, .pad = 5, .dac = 0, .bb_mult = 70, },
1702 { .gm = 4, .pga = 9, .pad = 5, .dac = 0, .bb_mult = 68, },
1703 { .gm = 4, .pga = 9, .pad = 5, .dac = 0, .bb_mult = 66, },
1704 { .gm = 4, .pga = 9, .pad = 5, .dac = 0, .bb_mult = 64, },
1705 { .gm = 4, .pga = 9, .pad = 5, .dac = 0, .bb_mult = 63, },
1706 { .gm = 4, .pga = 9, .pad = 5, .dac = 0, .bb_mult = 61, },
1707 { .gm = 4, .pga = 9, .pad = 5, .dac = 0, .bb_mult = 59, },
1708 { .gm = 4, .pga = 9, .pad = 4, .dac = 0, .bb_mult = 71, },
1709 { .gm = 4, .pga = 9, .pad = 4, .dac = 0, .bb_mult = 69, },
1710 { .gm = 4, .pga = 9, .pad = 4, .dac = 0, .bb_mult = 67, },
1711 { .gm = 4, .pga = 9, .pad = 4, .dac = 0, .bb_mult = 65, },
1712 { .gm = 4, .pga = 9, .pad = 4, .dac = 0, .bb_mult = 63, },
1713 { .gm = 4, .pga = 9, .pad = 4, .dac = 0, .bb_mult = 62, },
1714 { .gm = 4, .pga = 9, .pad = 4, .dac = 0, .bb_mult = 60, },
1715 { .gm = 4, .pga = 9, .pad = 4, .dac = 0, .bb_mult = 58, },
1716 { .gm = 4, .pga = 8, .pad = 4, .dac = 0, .bb_mult = 70, },
1717 { .gm = 4, .pga = 8, .pad = 4, .dac = 0, .bb_mult = 68, },
1718 { .gm = 4, .pga = 8, .pad = 4, .dac = 0, .bb_mult = 66, },
1719 { .gm = 4, .pga = 8, .pad = 4, .dac = 0, .bb_mult = 65, },
1720 { .gm = 4, .pga = 8, .pad = 4, .dac = 0, .bb_mult = 63, },
1721 { .gm = 4, .pga = 8, .pad = 4, .dac = 0, .bb_mult = 61, },
1722 { .gm = 4, .pga = 8, .pad = 4, .dac = 0, .bb_mult = 59, },
1723 { .gm = 4, .pga = 7, .pad = 4, .dac = 0, .bb_mult = 68, },
1724 { .gm = 4, .pga = 7, .pad = 4, .dac = 0, .bb_mult = 66, },
1725 { .gm = 4, .pga = 7, .pad = 4, .dac = 0, .bb_mult = 64, },
1726 { .gm = 4, .pga = 7, .pad = 4, .dac = 0, .bb_mult = 62, },
1727 { .gm = 4, .pga = 7, .pad = 4, .dac = 0, .bb_mult = 61, },
1728 { .gm = 4, .pga = 7, .pad = 4, .dac = 0, .bb_mult = 59, },
1729 { .gm = 4, .pga = 7, .pad = 3, .dac = 0, .bb_mult = 67, },
1730 { .gm = 4, .pga = 7, .pad = 3, .dac = 0, .bb_mult = 65, },
1731 { .gm = 4, .pga = 7, .pad = 3, .dac = 0, .bb_mult = 63, },
1732 { .gm = 4, .pga = 7, .pad = 3, .dac = 0, .bb_mult = 62, },
1733 { .gm = 4, .pga = 7, .pad = 3, .dac = 0, .bb_mult = 60, },
1734 { .gm = 4, .pga = 6, .pad = 3, .dac = 0, .bb_mult = 65, },
1735 { .gm = 4, .pga = 6, .pad = 3, .dac = 0, .bb_mult = 63, },
1736 { .gm = 4, .pga = 6, .pad = 3, .dac = 0, .bb_mult = 61, },
1737 { .gm = 4, .pga = 6, .pad = 3, .dac = 0, .bb_mult = 60, },
1738 { .gm = 4, .pga = 6, .pad = 3, .dac = 0, .bb_mult = 58, },
1739 { .gm = 4, .pga = 5, .pad = 3, .dac = 0, .bb_mult = 68, },
1740 { .gm = 4, .pga = 5, .pad = 3, .dac = 0, .bb_mult = 66, },
1741 { .gm = 4, .pga = 5, .pad = 3, .dac = 0, .bb_mult = 64, },
1742 { .gm = 4, .pga = 5, .pad = 3, .dac = 0, .bb_mult = 62, },
1743}; 1744};
1744 1745
1745static struct lpphy_tx_gain_table_entry lpphy_rev1_5ghz_tx_gain_table[] = { 1746static struct lpphy_tx_gain_table_entry lpphy_rev1_5ghz_tx_gain_table[] = {
@@ -2167,103 +2168,103 @@ static struct lpphy_tx_gain_table_entry lpphy_rev2_5ghz_tx_gain_table[] = {
2167 { .gm = 255, .pga = 255, .pad = 255, .dac = 0, .bb_mult = 68, }, 2168 { .gm = 255, .pga = 255, .pad = 255, .dac = 0, .bb_mult = 68, },
2168 { .gm = 255, .pga = 255, .pad = 255, .dac = 0, .bb_mult = 66, }, 2169 { .gm = 255, .pga = 255, .pad = 255, .dac = 0, .bb_mult = 66, },
2169 { .gm = 255, .pga = 255, .pad = 255, .dac = 0, .bb_mult = 64, }, 2170 { .gm = 255, .pga = 255, .pad = 255, .dac = 0, .bb_mult = 64, },
2170 { .gm = 255, .pga = 248, .pad = 255, .dac = 0, .bb_mult = 64, }, 2171 { .gm = 255, .pga = 255, .pad = 248, .dac = 0, .bb_mult = 64, },
2171 { .gm = 255, .pga = 241, .pad = 255, .dac = 0, .bb_mult = 64, }, 2172 { .gm = 255, .pga = 255, .pad = 241, .dac = 0, .bb_mult = 64, },
2172 { .gm = 255, .pga = 234, .pad = 255, .dac = 0, .bb_mult = 64, }, 2173 { .gm = 255, .pga = 255, .pad = 234, .dac = 0, .bb_mult = 64, },
2173 { .gm = 255, .pga = 227, .pad = 255, .dac = 0, .bb_mult = 64, }, 2174 { .gm = 255, .pga = 255, .pad = 227, .dac = 0, .bb_mult = 64, },
2174 { .gm = 255, .pga = 221, .pad = 255, .dac = 0, .bb_mult = 64, }, 2175 { .gm = 255, .pga = 255, .pad = 221, .dac = 0, .bb_mult = 64, },
2175 { .gm = 255, .pga = 215, .pad = 255, .dac = 0, .bb_mult = 64, }, 2176 { .gm = 255, .pga = 255, .pad = 215, .dac = 0, .bb_mult = 64, },
2176 { .gm = 255, .pga = 208, .pad = 255, .dac = 0, .bb_mult = 64, }, 2177 { .gm = 255, .pga = 255, .pad = 208, .dac = 0, .bb_mult = 64, },
2177 { .gm = 255, .pga = 203, .pad = 255, .dac = 0, .bb_mult = 64, }, 2178 { .gm = 255, .pga = 255, .pad = 203, .dac = 0, .bb_mult = 64, },
2178 { .gm = 255, .pga = 197, .pad = 255, .dac = 0, .bb_mult = 64, }, 2179 { .gm = 255, .pga = 255, .pad = 197, .dac = 0, .bb_mult = 64, },
2179 { .gm = 255, .pga = 191, .pad = 255, .dac = 0, .bb_mult = 64, }, 2180 { .gm = 255, .pga = 255, .pad = 191, .dac = 0, .bb_mult = 64, },
2180 { .gm = 255, .pga = 186, .pad = 255, .dac = 0, .bb_mult = 64, }, 2181 { .gm = 255, .pga = 255, .pad = 186, .dac = 0, .bb_mult = 64, },
2181 { .gm = 255, .pga = 181, .pad = 255, .dac = 0, .bb_mult = 64, }, 2182 { .gm = 255, .pga = 255, .pad = 181, .dac = 0, .bb_mult = 64, },
2182 { .gm = 255, .pga = 175, .pad = 255, .dac = 0, .bb_mult = 64, }, 2183 { .gm = 255, .pga = 255, .pad = 175, .dac = 0, .bb_mult = 64, },
2183 { .gm = 255, .pga = 170, .pad = 255, .dac = 0, .bb_mult = 64, }, 2184 { .gm = 255, .pga = 255, .pad = 170, .dac = 0, .bb_mult = 64, },
2184 { .gm = 255, .pga = 166, .pad = 255, .dac = 0, .bb_mult = 64, }, 2185 { .gm = 255, .pga = 255, .pad = 166, .dac = 0, .bb_mult = 64, },
2185 { .gm = 255, .pga = 161, .pad = 255, .dac = 0, .bb_mult = 64, }, 2186 { .gm = 255, .pga = 255, .pad = 161, .dac = 0, .bb_mult = 64, },
2186 { .gm = 255, .pga = 156, .pad = 255, .dac = 0, .bb_mult = 64, }, 2187 { .gm = 255, .pga = 255, .pad = 156, .dac = 0, .bb_mult = 64, },
2187 { .gm = 255, .pga = 152, .pad = 255, .dac = 0, .bb_mult = 64, }, 2188 { .gm = 255, .pga = 255, .pad = 152, .dac = 0, .bb_mult = 64, },
2188 { .gm = 255, .pga = 148, .pad = 255, .dac = 0, .bb_mult = 64, }, 2189 { .gm = 255, .pga = 255, .pad = 148, .dac = 0, .bb_mult = 64, },
2189 { .gm = 255, .pga = 143, .pad = 255, .dac = 0, .bb_mult = 64, }, 2190 { .gm = 255, .pga = 255, .pad = 143, .dac = 0, .bb_mult = 64, },
2190 { .gm = 255, .pga = 139, .pad = 255, .dac = 0, .bb_mult = 64, }, 2191 { .gm = 255, .pga = 255, .pad = 139, .dac = 0, .bb_mult = 64, },
2191 { .gm = 255, .pga = 135, .pad = 255, .dac = 0, .bb_mult = 64, }, 2192 { .gm = 255, .pga = 255, .pad = 135, .dac = 0, .bb_mult = 64, },
2192 { .gm = 255, .pga = 132, .pad = 255, .dac = 0, .bb_mult = 64, }, 2193 { .gm = 255, .pga = 255, .pad = 132, .dac = 0, .bb_mult = 64, },
2193 { .gm = 255, .pga = 128, .pad = 255, .dac = 0, .bb_mult = 64, }, 2194 { .gm = 255, .pga = 255, .pad = 128, .dac = 0, .bb_mult = 64, },
2194 { .gm = 255, .pga = 124, .pad = 255, .dac = 0, .bb_mult = 64, }, 2195 { .gm = 255, .pga = 255, .pad = 124, .dac = 0, .bb_mult = 64, },
2195 { .gm = 255, .pga = 121, .pad = 255, .dac = 0, .bb_mult = 64, }, 2196 { .gm = 255, .pga = 255, .pad = 121, .dac = 0, .bb_mult = 64, },
2196 { .gm = 255, .pga = 117, .pad = 255, .dac = 0, .bb_mult = 64, }, 2197 { .gm = 255, .pga = 255, .pad = 117, .dac = 0, .bb_mult = 64, },
2197 { .gm = 255, .pga = 114, .pad = 255, .dac = 0, .bb_mult = 64, }, 2198 { .gm = 255, .pga = 255, .pad = 114, .dac = 0, .bb_mult = 64, },
2198 { .gm = 255, .pga = 111, .pad = 255, .dac = 0, .bb_mult = 64, }, 2199 { .gm = 255, .pga = 255, .pad = 111, .dac = 0, .bb_mult = 64, },
2199 { .gm = 255, .pga = 108, .pad = 255, .dac = 0, .bb_mult = 64, }, 2200 { .gm = 255, .pga = 255, .pad = 108, .dac = 0, .bb_mult = 64, },
2200 { .gm = 255, .pga = 104, .pad = 255, .dac = 0, .bb_mult = 64, }, 2201 { .gm = 255, .pga = 255, .pad = 104, .dac = 0, .bb_mult = 64, },
2201 { .gm = 255, .pga = 102, .pad = 255, .dac = 0, .bb_mult = 64, }, 2202 { .gm = 255, .pga = 255, .pad = 102, .dac = 0, .bb_mult = 64, },
2202 { .gm = 255, .pga = 99, .pad = 255, .dac = 0, .bb_mult = 64, }, 2203 { .gm = 255, .pga = 255, .pad = 99, .dac = 0, .bb_mult = 64, },
2203 { .gm = 255, .pga = 96, .pad = 255, .dac = 0, .bb_mult = 64, }, 2204 { .gm = 255, .pga = 255, .pad = 96, .dac = 0, .bb_mult = 64, },
2204 { .gm = 255, .pga = 93, .pad = 255, .dac = 0, .bb_mult = 64, }, 2205 { .gm = 255, .pga = 255, .pad = 93, .dac = 0, .bb_mult = 64, },
2205 { .gm = 255, .pga = 90, .pad = 255, .dac = 0, .bb_mult = 64, }, 2206 { .gm = 255, .pga = 255, .pad = 90, .dac = 0, .bb_mult = 64, },
2206 { .gm = 255, .pga = 88, .pad = 255, .dac = 0, .bb_mult = 64, }, 2207 { .gm = 255, .pga = 255, .pad = 88, .dac = 0, .bb_mult = 64, },
2207 { .gm = 255, .pga = 85, .pad = 255, .dac = 0, .bb_mult = 64, }, 2208 { .gm = 255, .pga = 255, .pad = 85, .dac = 0, .bb_mult = 64, },
2208 { .gm = 255, .pga = 83, .pad = 255, .dac = 0, .bb_mult = 64, }, 2209 { .gm = 255, .pga = 255, .pad = 83, .dac = 0, .bb_mult = 64, },
2209 { .gm = 255, .pga = 81, .pad = 255, .dac = 0, .bb_mult = 64, }, 2210 { .gm = 255, .pga = 255, .pad = 81, .dac = 0, .bb_mult = 64, },
2210 { .gm = 255, .pga = 78, .pad = 255, .dac = 0, .bb_mult = 64, }, 2211 { .gm = 255, .pga = 255, .pad = 78, .dac = 0, .bb_mult = 64, },
2211 { .gm = 255, .pga = 76, .pad = 255, .dac = 0, .bb_mult = 64, }, 2212 { .gm = 255, .pga = 255, .pad = 76, .dac = 0, .bb_mult = 64, },
2212 { .gm = 255, .pga = 74, .pad = 255, .dac = 0, .bb_mult = 64, }, 2213 { .gm = 255, .pga = 255, .pad = 74, .dac = 0, .bb_mult = 64, },
2213 { .gm = 255, .pga = 72, .pad = 255, .dac = 0, .bb_mult = 64, }, 2214 { .gm = 255, .pga = 255, .pad = 72, .dac = 0, .bb_mult = 64, },
2214 { .gm = 255, .pga = 70, .pad = 255, .dac = 0, .bb_mult = 64, }, 2215 { .gm = 255, .pga = 255, .pad = 70, .dac = 0, .bb_mult = 64, },
2215 { .gm = 255, .pga = 68, .pad = 255, .dac = 0, .bb_mult = 64, }, 2216 { .gm = 255, .pga = 255, .pad = 68, .dac = 0, .bb_mult = 64, },
2216 { .gm = 255, .pga = 66, .pad = 255, .dac = 0, .bb_mult = 64, }, 2217 { .gm = 255, .pga = 255, .pad = 66, .dac = 0, .bb_mult = 64, },
2217 { .gm = 255, .pga = 64, .pad = 255, .dac = 0, .bb_mult = 64, }, 2218 { .gm = 255, .pga = 255, .pad = 64, .dac = 0, .bb_mult = 64, },
2218 { .gm = 255, .pga = 64, .pad = 255, .dac = 0, .bb_mult = 64, }, 2219 { .gm = 255, .pga = 255, .pad = 64, .dac = 0, .bb_mult = 64, },
2219 { .gm = 255, .pga = 62, .pad = 255, .dac = 0, .bb_mult = 64, }, 2220 { .gm = 255, .pga = 255, .pad = 62, .dac = 0, .bb_mult = 64, },
2220 { .gm = 255, .pga = 62, .pad = 248, .dac = 0, .bb_mult = 64, }, 2221 { .gm = 255, .pga = 248, .pad = 62, .dac = 0, .bb_mult = 64, },
2221 { .gm = 255, .pga = 60, .pad = 248, .dac = 0, .bb_mult = 64, }, 2222 { .gm = 255, .pga = 248, .pad = 60, .dac = 0, .bb_mult = 64, },
2222 { .gm = 255, .pga = 60, .pad = 241, .dac = 0, .bb_mult = 64, }, 2223 { .gm = 255, .pga = 241, .pad = 60, .dac = 0, .bb_mult = 64, },
2223 { .gm = 255, .pga = 59, .pad = 241, .dac = 0, .bb_mult = 64, }, 2224 { .gm = 255, .pga = 241, .pad = 59, .dac = 0, .bb_mult = 64, },
2224 { .gm = 255, .pga = 59, .pad = 234, .dac = 0, .bb_mult = 64, }, 2225 { .gm = 255, .pga = 234, .pad = 59, .dac = 0, .bb_mult = 64, },
2225 { .gm = 255, .pga = 57, .pad = 234, .dac = 0, .bb_mult = 64, }, 2226 { .gm = 255, .pga = 234, .pad = 57, .dac = 0, .bb_mult = 64, },
2226 { .gm = 255, .pga = 57, .pad = 227, .dac = 0, .bb_mult = 64, }, 2227 { .gm = 255, .pga = 227, .pad = 57, .dac = 0, .bb_mult = 64, },
2227 { .gm = 255, .pga = 55, .pad = 227, .dac = 0, .bb_mult = 64, }, 2228 { .gm = 255, .pga = 227, .pad = 55, .dac = 0, .bb_mult = 64, },
2228 { .gm = 255, .pga = 55, .pad = 221, .dac = 0, .bb_mult = 64, }, 2229 { .gm = 255, .pga = 221, .pad = 55, .dac = 0, .bb_mult = 64, },
2229 { .gm = 255, .pga = 54, .pad = 221, .dac = 0, .bb_mult = 64, }, 2230 { .gm = 255, .pga = 221, .pad = 54, .dac = 0, .bb_mult = 64, },
2230 { .gm = 255, .pga = 54, .pad = 215, .dac = 0, .bb_mult = 64, }, 2231 { .gm = 255, .pga = 215, .pad = 54, .dac = 0, .bb_mult = 64, },
2231 { .gm = 255, .pga = 52, .pad = 215, .dac = 0, .bb_mult = 64, }, 2232 { .gm = 255, .pga = 215, .pad = 52, .dac = 0, .bb_mult = 64, },
2232 { .gm = 255, .pga = 52, .pad = 208, .dac = 0, .bb_mult = 64, }, 2233 { .gm = 255, .pga = 208, .pad = 52, .dac = 0, .bb_mult = 64, },
2233 { .gm = 255, .pga = 51, .pad = 208, .dac = 0, .bb_mult = 64, }, 2234 { .gm = 255, .pga = 208, .pad = 51, .dac = 0, .bb_mult = 64, },
2234 { .gm = 255, .pga = 51, .pad = 203, .dac = 0, .bb_mult = 64, }, 2235 { .gm = 255, .pga = 203, .pad = 51, .dac = 0, .bb_mult = 64, },
2235 { .gm = 255, .pga = 49, .pad = 203, .dac = 0, .bb_mult = 64, }, 2236 { .gm = 255, .pga = 203, .pad = 49, .dac = 0, .bb_mult = 64, },
2236 { .gm = 255, .pga = 49, .pad = 197, .dac = 0, .bb_mult = 64, }, 2237 { .gm = 255, .pga = 197, .pad = 49, .dac = 0, .bb_mult = 64, },
2237 { .gm = 255, .pga = 48, .pad = 197, .dac = 0, .bb_mult = 64, }, 2238 { .gm = 255, .pga = 197, .pad = 48, .dac = 0, .bb_mult = 64, },
2238 { .gm = 255, .pga = 48, .pad = 191, .dac = 0, .bb_mult = 64, }, 2239 { .gm = 255, .pga = 191, .pad = 48, .dac = 0, .bb_mult = 64, },
2239 { .gm = 255, .pga = 47, .pad = 191, .dac = 0, .bb_mult = 64, }, 2240 { .gm = 255, .pga = 191, .pad = 47, .dac = 0, .bb_mult = 64, },
2240 { .gm = 255, .pga = 47, .pad = 186, .dac = 0, .bb_mult = 64, }, 2241 { .gm = 255, .pga = 186, .pad = 47, .dac = 0, .bb_mult = 64, },
2241 { .gm = 255, .pga = 45, .pad = 186, .dac = 0, .bb_mult = 64, }, 2242 { .gm = 255, .pga = 186, .pad = 45, .dac = 0, .bb_mult = 64, },
2242 { .gm = 255, .pga = 45, .pad = 181, .dac = 0, .bb_mult = 64, }, 2243 { .gm = 255, .pga = 181, .pad = 45, .dac = 0, .bb_mult = 64, },
2243 { .gm = 255, .pga = 44, .pad = 181, .dac = 0, .bb_mult = 64, }, 2244 { .gm = 255, .pga = 181, .pad = 44, .dac = 0, .bb_mult = 64, },
2244 { .gm = 255, .pga = 44, .pad = 175, .dac = 0, .bb_mult = 64, }, 2245 { .gm = 255, .pga = 175, .pad = 44, .dac = 0, .bb_mult = 64, },
2245 { .gm = 255, .pga = 43, .pad = 175, .dac = 0, .bb_mult = 64, }, 2246 { .gm = 255, .pga = 175, .pad = 43, .dac = 0, .bb_mult = 64, },
2246 { .gm = 255, .pga = 43, .pad = 170, .dac = 0, .bb_mult = 64, }, 2247 { .gm = 255, .pga = 170, .pad = 43, .dac = 0, .bb_mult = 64, },
2247 { .gm = 255, .pga = 42, .pad = 170, .dac = 0, .bb_mult = 64, }, 2248 { .gm = 255, .pga = 170, .pad = 42, .dac = 0, .bb_mult = 64, },
2248 { .gm = 255, .pga = 42, .pad = 166, .dac = 0, .bb_mult = 64, }, 2249 { .gm = 255, .pga = 166, .pad = 42, .dac = 0, .bb_mult = 64, },
2249 { .gm = 255, .pga = 40, .pad = 166, .dac = 0, .bb_mult = 64, }, 2250 { .gm = 255, .pga = 166, .pad = 40, .dac = 0, .bb_mult = 64, },
2250 { .gm = 255, .pga = 40, .pad = 161, .dac = 0, .bb_mult = 64, }, 2251 { .gm = 255, .pga = 161, .pad = 40, .dac = 0, .bb_mult = 64, },
2251 { .gm = 255, .pga = 39, .pad = 161, .dac = 0, .bb_mult = 64, }, 2252 { .gm = 255, .pga = 161, .pad = 39, .dac = 0, .bb_mult = 64, },
2252 { .gm = 255, .pga = 39, .pad = 156, .dac = 0, .bb_mult = 64, }, 2253 { .gm = 255, .pga = 156, .pad = 39, .dac = 0, .bb_mult = 64, },
2253 { .gm = 255, .pga = 38, .pad = 156, .dac = 0, .bb_mult = 64, }, 2254 { .gm = 255, .pga = 156, .pad = 38, .dac = 0, .bb_mult = 64, },
2254 { .gm = 255, .pga = 38, .pad = 152, .dac = 0, .bb_mult = 64, }, 2255 { .gm = 255, .pga = 152, .pad = 38, .dac = 0, .bb_mult = 64, },
2255 { .gm = 255, .pga = 37, .pad = 152, .dac = 0, .bb_mult = 64, }, 2256 { .gm = 255, .pga = 152, .pad = 37, .dac = 0, .bb_mult = 64, },
2256 { .gm = 255, .pga = 37, .pad = 148, .dac = 0, .bb_mult = 64, }, 2257 { .gm = 255, .pga = 148, .pad = 37, .dac = 0, .bb_mult = 64, },
2257 { .gm = 255, .pga = 36, .pad = 148, .dac = 0, .bb_mult = 64, }, 2258 { .gm = 255, .pga = 148, .pad = 36, .dac = 0, .bb_mult = 64, },
2258 { .gm = 255, .pga = 36, .pad = 143, .dac = 0, .bb_mult = 64, }, 2259 { .gm = 255, .pga = 143, .pad = 36, .dac = 0, .bb_mult = 64, },
2259 { .gm = 255, .pga = 35, .pad = 143, .dac = 0, .bb_mult = 64, }, 2260 { .gm = 255, .pga = 143, .pad = 35, .dac = 0, .bb_mult = 64, },
2260 { .gm = 255, .pga = 35, .pad = 139, .dac = 0, .bb_mult = 64, }, 2261 { .gm = 255, .pga = 139, .pad = 35, .dac = 0, .bb_mult = 64, },
2261 { .gm = 255, .pga = 34, .pad = 139, .dac = 0, .bb_mult = 64, }, 2262 { .gm = 255, .pga = 139, .pad = 34, .dac = 0, .bb_mult = 64, },
2262 { .gm = 255, .pga = 34, .pad = 135, .dac = 0, .bb_mult = 64, }, 2263 { .gm = 255, .pga = 135, .pad = 34, .dac = 0, .bb_mult = 64, },
2263 { .gm = 255, .pga = 33, .pad = 135, .dac = 0, .bb_mult = 64, }, 2264 { .gm = 255, .pga = 135, .pad = 33, .dac = 0, .bb_mult = 64, },
2264 { .gm = 255, .pga = 33, .pad = 132, .dac = 0, .bb_mult = 64, }, 2265 { .gm = 255, .pga = 132, .pad = 33, .dac = 0, .bb_mult = 64, },
2265 { .gm = 255, .pga = 32, .pad = 132, .dac = 0, .bb_mult = 64, }, 2266 { .gm = 255, .pga = 132, .pad = 32, .dac = 0, .bb_mult = 64, },
2266 { .gm = 255, .pga = 32, .pad = 128, .dac = 0, .bb_mult = 64, }, 2267 { .gm = 255, .pga = 128, .pad = 32, .dac = 0, .bb_mult = 64, },
2267}; 2268};
2268 2269
2269void lpphy_rev0_1_table_init(struct b43_wldev *dev) 2270void lpphy_rev0_1_table_init(struct b43_wldev *dev)
diff --git a/drivers/net/wireless/ipw2x00/Kconfig b/drivers/net/wireless/ipw2x00/Kconfig
index 85cc79995f6f..a8131384c6b9 100644
--- a/drivers/net/wireless/ipw2x00/Kconfig
+++ b/drivers/net/wireless/ipw2x00/Kconfig
@@ -4,7 +4,7 @@
4 4
5config IPW2100 5config IPW2100
6 tristate "Intel PRO/Wireless 2100 Network Connection" 6 tristate "Intel PRO/Wireless 2100 Network Connection"
7 depends on PCI && WLAN_80211 7 depends on PCI && WLAN_80211 && CFG80211
8 select WIRELESS_EXT 8 select WIRELESS_EXT
9 select FW_LOADER 9 select FW_LOADER
10 select LIB80211 10 select LIB80211
@@ -63,7 +63,7 @@ config IPW2100_DEBUG
63 63
64config IPW2200 64config IPW2200
65 tristate "Intel PRO/Wireless 2200BG and 2915ABG Network Connection" 65 tristate "Intel PRO/Wireless 2200BG and 2915ABG Network Connection"
66 depends on PCI && WLAN_80211 66 depends on PCI && WLAN_80211 && CFG80211
67 select WIRELESS_EXT 67 select WIRELESS_EXT
68 select FW_LOADER 68 select FW_LOADER
69 select LIB80211 69 select LIB80211
@@ -150,7 +150,7 @@ config IPW2200_DEBUG
150 150
151config LIBIPW 151config LIBIPW
152 tristate 152 tristate
153 depends on PCI && WLAN_80211 153 depends on PCI && WLAN_80211 && CFG80211
154 select WIRELESS_EXT 154 select WIRELESS_EXT
155 select CRYPTO 155 select CRYPTO
156 select CRYPTO_ARC4 156 select CRYPTO_ARC4
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
index 26ec969e265d..40b207aa8fef 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
@@ -818,15 +818,15 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband,
818{ 818{
819 int status; 819 int status;
820 u8 retries; 820 u8 retries;
821 int rs_index, index = 0; 821 int rs_index, mac_index, index = 0;
822 struct iwl_lq_sta *lq_sta = priv_sta; 822 struct iwl_lq_sta *lq_sta = priv_sta;
823 struct iwl_link_quality_cmd *table; 823 struct iwl_link_quality_cmd *table;
824 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; 824 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
825 struct iwl_priv *priv = (struct iwl_priv *)priv_r; 825 struct iwl_priv *priv = (struct iwl_priv *)priv_r;
826 struct ieee80211_hw *hw = priv->hw;
827 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 826 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
828 struct iwl_rate_scale_data *window = NULL; 827 struct iwl_rate_scale_data *window = NULL;
829 struct iwl_rate_scale_data *search_win = NULL; 828 struct iwl_rate_scale_data *search_win = NULL;
829 enum mac80211_rate_control_flags mac_flags;
830 u32 tx_rate; 830 u32 tx_rate;
831 struct iwl_scale_tbl_info tbl_type; 831 struct iwl_scale_tbl_info tbl_type;
832 struct iwl_scale_tbl_info *curr_tbl, *search_tbl; 832 struct iwl_scale_tbl_info *curr_tbl, *search_tbl;
@@ -876,17 +876,24 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband,
876 rs_get_tbl_info_from_mcs(tx_rate, priv->band, &tbl_type, &rs_index); 876 rs_get_tbl_info_from_mcs(tx_rate, priv->band, &tbl_type, &rs_index);
877 if (priv->band == IEEE80211_BAND_5GHZ) 877 if (priv->band == IEEE80211_BAND_5GHZ)
878 rs_index -= IWL_FIRST_OFDM_RATE; 878 rs_index -= IWL_FIRST_OFDM_RATE;
879 mac_flags = info->status.rates[0].flags;
880 mac_index = info->status.rates[0].idx;
881 /* For HT packets, map MCS to PLCP */
882 if (mac_flags & IEEE80211_TX_RC_MCS) {
883 mac_index &= RATE_MCS_CODE_MSK; /* Remove # of streams */
884 if (mac_index >= (IWL_RATE_9M_INDEX - IWL_FIRST_OFDM_RATE))
885 mac_index++;
886 }
879 887
880 if ((info->status.rates[0].idx < 0) || 888 if ((mac_index < 0) ||
881 (tbl_type.is_SGI != !!(info->status.rates[0].flags & IEEE80211_TX_RC_SHORT_GI)) || 889 (tbl_type.is_SGI != !!(mac_flags & IEEE80211_TX_RC_SHORT_GI)) ||
882 (tbl_type.is_ht40 != !!(info->status.rates[0].flags & IEEE80211_TX_RC_40_MHZ_WIDTH)) || 890 (tbl_type.is_ht40 != !!(mac_flags & IEEE80211_TX_RC_40_MHZ_WIDTH)) ||
883 (tbl_type.is_dup != !!(info->status.rates[0].flags & IEEE80211_TX_RC_DUP_DATA)) || 891 (tbl_type.is_dup != !!(mac_flags & IEEE80211_TX_RC_DUP_DATA)) ||
884 (tbl_type.ant_type != info->antenna_sel_tx) || 892 (tbl_type.ant_type != info->antenna_sel_tx) ||
885 (!!(tx_rate & RATE_MCS_HT_MSK) != !!(info->status.rates[0].flags & IEEE80211_TX_RC_MCS)) || 893 (!!(tx_rate & RATE_MCS_HT_MSK) != !!(mac_flags & IEEE80211_TX_RC_MCS)) ||
886 (!!(tx_rate & RATE_MCS_GF_MSK) != !!(info->status.rates[0].flags & IEEE80211_TX_RC_GREEN_FIELD)) || 894 (!!(tx_rate & RATE_MCS_GF_MSK) != !!(mac_flags & IEEE80211_TX_RC_GREEN_FIELD)) ||
887 (hw->wiphy->bands[priv->band]->bitrates[rs_index].bitrate != 895 (rs_index != mac_index)) {
888 hw->wiphy->bands[info->band]->bitrates[info->status.rates[0].idx].bitrate)) { 896 IWL_DEBUG_RATE(priv, "initial rate %d does not match %d (0x%x)\n", mac_index, rs_index, tx_rate);
889 IWL_DEBUG_RATE(priv, "initial rate does not match 0x%x\n", tx_rate);
890 /* the last LQ command could failed so the LQ in ucode not 897 /* the last LQ command could failed so the LQ in ucode not
891 * the same in driver sync up 898 * the same in driver sync up
892 */ 899 */
@@ -2542,8 +2549,12 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta, void *priv_sta,
2542 if (lq_sta->last_rate_n_flags & RATE_MCS_GF_MSK) 2549 if (lq_sta->last_rate_n_flags & RATE_MCS_GF_MSK)
2543 info->control.rates[0].flags |= IEEE80211_TX_RC_GREEN_FIELD; 2550 info->control.rates[0].flags |= IEEE80211_TX_RC_GREEN_FIELD;
2544 } else { 2551 } else {
2545 if (rate_idx < 0 || rate_idx > IWL_RATE_COUNT) 2552 /* Check for invalid rates */
2553 if ((rate_idx < 0) || (rate_idx >= IWL_RATE_COUNT_LEGACY) ||
2554 ((sband->band == IEEE80211_BAND_5GHZ) &&
2555 (rate_idx < IWL_FIRST_OFDM_RATE)))
2546 rate_idx = rate_lowest_index(sband, sta); 2556 rate_idx = rate_lowest_index(sband, sta);
2557 /* On valid 5 GHz rate, adjust index */
2547 else if (sband->band == IEEE80211_BAND_5GHZ) 2558 else if (sband->band == IEEE80211_BAND_5GHZ)
2548 rate_idx -= IWL_FIRST_OFDM_RATE; 2559 rate_idx -= IWL_FIRST_OFDM_RATE;
2549 info->control.rates[0].flags = 0; 2560 info->control.rates[0].flags = 0;
@@ -2584,9 +2595,6 @@ static void rs_rate_init(void *priv_r, struct ieee80211_supported_band *sband,
2584 struct ieee80211_conf *conf = &priv->hw->conf; 2595 struct ieee80211_conf *conf = &priv->hw->conf;
2585 struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap; 2596 struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap;
2586 struct iwl_lq_sta *lq_sta = priv_sta; 2597 struct iwl_lq_sta *lq_sta = priv_sta;
2587 u16 mask_bit = 0;
2588 int count;
2589 int start_rate = 0;
2590 2598
2591 lq_sta->flush_timer = 0; 2599 lq_sta->flush_timer = 0;
2592 lq_sta->supp_rates = sta->supp_rates[sband->band]; 2600 lq_sta->supp_rates = sta->supp_rates[sband->band];
@@ -2661,20 +2669,10 @@ static void rs_rate_init(void *priv_r, struct ieee80211_supported_band *sband,
2661 lq_sta->tx_agg_tid_en = IWL_AGG_ALL_TID; 2669 lq_sta->tx_agg_tid_en = IWL_AGG_ALL_TID;
2662 lq_sta->drv = priv; 2670 lq_sta->drv = priv;
2663 2671
2664 /* Find highest tx rate supported by hardware and destination station */ 2672 /* Set last_txrate_idx to lowest rate */
2665 mask_bit = sta->supp_rates[sband->band]; 2673 lq_sta->last_txrate_idx = rate_lowest_index(sband, sta);
2666 count = sband->n_bitrates; 2674 if (sband->band == IEEE80211_BAND_5GHZ)
2667 if (sband->band == IEEE80211_BAND_5GHZ) { 2675 lq_sta->last_txrate_idx += IWL_FIRST_OFDM_RATE;
2668 count += IWL_FIRST_OFDM_RATE;
2669 start_rate = IWL_FIRST_OFDM_RATE;
2670 mask_bit <<= IWL_FIRST_OFDM_RATE;
2671 }
2672
2673 mask_bit = mask_bit & lq_sta->active_legacy_rate;
2674 lq_sta->last_txrate_idx = 4;
2675 for (i = start_rate; i < count; i++)
2676 if (mask_bit & BIT(i))
2677 lq_sta->last_txrate_idx = i;
2678 2676
2679 rs_initialize_lq(priv, conf, sta, lq_sta); 2677 rs_initialize_lq(priv, conf, sta, lq_sta);
2680} 2678}
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.h b/drivers/net/wireless/iwlwifi/iwl-agn-rs.h
index 25050bf315a2..9fac530cfb7e 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.h
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.h
@@ -73,6 +73,7 @@ enum {
73 IWL_RATE_54M_INDEX, 73 IWL_RATE_54M_INDEX,
74 IWL_RATE_60M_INDEX, 74 IWL_RATE_60M_INDEX,
75 IWL_RATE_COUNT, /*FIXME:RS:change to IWL_RATE_INDEX_COUNT,*/ 75 IWL_RATE_COUNT, /*FIXME:RS:change to IWL_RATE_INDEX_COUNT,*/
76 IWL_RATE_COUNT_LEGACY = IWL_RATE_COUNT - 1, /* Excluding 60M */
76 IWL_RATE_COUNT_3945 = IWL_RATE_COUNT - 1, 77 IWL_RATE_COUNT_3945 = IWL_RATE_COUNT - 1,
77 IWL_RATE_INVM_INDEX = IWL_RATE_COUNT, 78 IWL_RATE_INVM_INDEX = IWL_RATE_COUNT,
78 IWL_RATE_INVALID = IWL_RATE_COUNT, 79 IWL_RATE_INVALID = IWL_RATE_COUNT,
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index 0bfd4e918139..acfd7b40afb8 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -96,7 +96,6 @@ EXPORT_SYMBOL(iwl_rates);
96void iwl_hwrate_to_tx_control(struct iwl_priv *priv, u32 rate_n_flags, 96void iwl_hwrate_to_tx_control(struct iwl_priv *priv, u32 rate_n_flags,
97 struct ieee80211_tx_info *info) 97 struct ieee80211_tx_info *info)
98{ 98{
99 int rate_index;
100 struct ieee80211_tx_rate *r = &info->control.rates[0]; 99 struct ieee80211_tx_rate *r = &info->control.rates[0];
101 100
102 info->antenna_sel_tx = 101 info->antenna_sel_tx =
@@ -111,10 +110,7 @@ void iwl_hwrate_to_tx_control(struct iwl_priv *priv, u32 rate_n_flags,
111 r->flags |= IEEE80211_TX_RC_DUP_DATA; 110 r->flags |= IEEE80211_TX_RC_DUP_DATA;
112 if (rate_n_flags & RATE_MCS_SGI_MSK) 111 if (rate_n_flags & RATE_MCS_SGI_MSK)
113 r->flags |= IEEE80211_TX_RC_SHORT_GI; 112 r->flags |= IEEE80211_TX_RC_SHORT_GI;
114 rate_index = iwl_hwrate_to_plcp_idx(rate_n_flags); 113 r->idx = iwl_hwrate_to_mac80211_idx(rate_n_flags, info->band);
115 if (info->band == IEEE80211_BAND_5GHZ)
116 rate_index -= IWL_FIRST_OFDM_RATE;
117 r->idx = rate_index;
118} 114}
119EXPORT_SYMBOL(iwl_hwrate_to_tx_control); 115EXPORT_SYMBOL(iwl_hwrate_to_tx_control);
120 116
@@ -149,6 +145,27 @@ int iwl_hwrate_to_plcp_idx(u32 rate_n_flags)
149} 145}
150EXPORT_SYMBOL(iwl_hwrate_to_plcp_idx); 146EXPORT_SYMBOL(iwl_hwrate_to_plcp_idx);
151 147
148int iwl_hwrate_to_mac80211_idx(u32 rate_n_flags, enum ieee80211_band band)
149{
150 int idx = 0;
151 int band_offset = 0;
152
153 /* HT rate format: mac80211 wants an MCS number, which is just LSB */
154 if (rate_n_flags & RATE_MCS_HT_MSK) {
155 idx = (rate_n_flags & 0xff);
156 return idx;
157 /* Legacy rate format, search for match in table */
158 } else {
159 if (band == IEEE80211_BAND_5GHZ)
160 band_offset = IWL_FIRST_OFDM_RATE;
161 for (idx = band_offset; idx < IWL_RATE_COUNT_LEGACY; idx++)
162 if (iwl_rates[idx].plcp == (rate_n_flags & 0xFF))
163 return idx - band_offset;
164 }
165
166 return -1;
167}
168
152u8 iwl_toggle_tx_ant(struct iwl_priv *priv, u8 ant) 169u8 iwl_toggle_tx_ant(struct iwl_priv *priv, u8 ant)
153{ 170{
154 int i; 171 int i;
@@ -439,12 +456,12 @@ static void iwlcore_init_hw_rates(struct iwl_priv *priv,
439{ 456{
440 int i; 457 int i;
441 458
442 for (i = 0; i < IWL_RATE_COUNT; i++) { 459 for (i = 0; i < IWL_RATE_COUNT_LEGACY; i++) {
443 rates[i].bitrate = iwl_rates[i].ieee * 5; 460 rates[i].bitrate = iwl_rates[i].ieee * 5;
444 rates[i].hw_value = i; /* Rate scaling will work on indexes */ 461 rates[i].hw_value = i; /* Rate scaling will work on indexes */
445 rates[i].hw_value_short = i; 462 rates[i].hw_value_short = i;
446 rates[i].flags = 0; 463 rates[i].flags = 0;
447 if ((i > IWL_LAST_OFDM_RATE) || (i < IWL_FIRST_OFDM_RATE)) { 464 if ((i >= IWL_FIRST_CCK_RATE) && (i <= IWL_LAST_CCK_RATE)) {
448 /* 465 /*
449 * If CCK != 1M then set short preamble rate flag. 466 * If CCK != 1M then set short preamble rate flag.
450 */ 467 */
@@ -480,7 +497,7 @@ int iwlcore_init_geos(struct iwl_priv *priv)
480 if (!channels) 497 if (!channels)
481 return -ENOMEM; 498 return -ENOMEM;
482 499
483 rates = kzalloc((sizeof(struct ieee80211_rate) * (IWL_RATE_COUNT + 1)), 500 rates = kzalloc((sizeof(struct ieee80211_rate) * IWL_RATE_COUNT_LEGACY),
484 GFP_KERNEL); 501 GFP_KERNEL);
485 if (!rates) { 502 if (!rates) {
486 kfree(channels); 503 kfree(channels);
@@ -492,7 +509,7 @@ int iwlcore_init_geos(struct iwl_priv *priv)
492 sband->channels = &channels[ARRAY_SIZE(iwl_eeprom_band_1)]; 509 sband->channels = &channels[ARRAY_SIZE(iwl_eeprom_band_1)];
493 /* just OFDM */ 510 /* just OFDM */
494 sband->bitrates = &rates[IWL_FIRST_OFDM_RATE]; 511 sband->bitrates = &rates[IWL_FIRST_OFDM_RATE];
495 sband->n_bitrates = IWL_RATE_COUNT - IWL_FIRST_OFDM_RATE; 512 sband->n_bitrates = IWL_RATE_COUNT_LEGACY - IWL_FIRST_OFDM_RATE;
496 513
497 if (priv->cfg->sku & IWL_SKU_N) 514 if (priv->cfg->sku & IWL_SKU_N)
498 iwlcore_init_ht_hw_capab(priv, &sband->ht_cap, 515 iwlcore_init_ht_hw_capab(priv, &sband->ht_cap,
@@ -502,7 +519,7 @@ int iwlcore_init_geos(struct iwl_priv *priv)
502 sband->channels = channels; 519 sband->channels = channels;
503 /* OFDM & CCK */ 520 /* OFDM & CCK */
504 sband->bitrates = rates; 521 sband->bitrates = rates;
505 sband->n_bitrates = IWL_RATE_COUNT; 522 sband->n_bitrates = IWL_RATE_COUNT_LEGACY;
506 523
507 if (priv->cfg->sku & IWL_SKU_N) 524 if (priv->cfg->sku & IWL_SKU_N)
508 iwlcore_init_ht_hw_capab(priv, &sband->ht_cap, 525 iwlcore_init_ht_hw_capab(priv, &sband->ht_cap,
@@ -1231,7 +1248,7 @@ static void iwl_set_rate(struct iwl_priv *priv)
1231 1248
1232 for (i = 0; i < hw->n_bitrates; i++) { 1249 for (i = 0; i < hw->n_bitrates; i++) {
1233 rate = &(hw->bitrates[i]); 1250 rate = &(hw->bitrates[i]);
1234 if (rate->hw_value < IWL_RATE_COUNT) 1251 if (rate->hw_value < IWL_RATE_COUNT_LEGACY)
1235 priv->active_rate |= (1 << rate->hw_value); 1252 priv->active_rate |= (1 << rate->hw_value);
1236 } 1253 }
1237 1254
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index 62d90364b61d..c04d2a270819 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -423,6 +423,7 @@ int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force);
423void iwl_hwrate_to_tx_control(struct iwl_priv *priv, u32 rate_n_flags, 423void iwl_hwrate_to_tx_control(struct iwl_priv *priv, u32 rate_n_flags,
424 struct ieee80211_tx_info *info); 424 struct ieee80211_tx_info *info);
425int iwl_hwrate_to_plcp_idx(u32 rate_n_flags); 425int iwl_hwrate_to_plcp_idx(u32 rate_n_flags);
426int iwl_hwrate_to_mac80211_idx(u32 rate_n_flags, enum ieee80211_band band);
426 427
427u8 iwl_rate_get_lowest_plcp(struct iwl_priv *priv); 428u8 iwl_rate_get_lowest_plcp(struct iwl_priv *priv);
428 429
diff --git a/drivers/net/wireless/iwlwifi/iwl-power.c b/drivers/net/wireless/iwlwifi/iwl-power.c
index 0b16841f45f4..4ec6a8307cc6 100644
--- a/drivers/net/wireless/iwlwifi/iwl-power.c
+++ b/drivers/net/wireless/iwlwifi/iwl-power.c
@@ -216,8 +216,27 @@ static void iwl_power_fill_sleep_cmd(struct iwl_priv *priv,
216 struct iwl_powertable_cmd *cmd, 216 struct iwl_powertable_cmd *cmd,
217 int dynps_ms, int wakeup_period) 217 int dynps_ms, int wakeup_period)
218{ 218{
219 /*
220 * These are the original power level 3 sleep successions. The
221 * device may behave better with such succession and was also
222 * only tested with that. Just like the original sleep commands,
223 * also adjust the succession here to the wakeup_period below.
224 * The ranges are the same as for the sleep commands, 0-2, 3-9
225 * and >10, which is selected based on the DTIM interval for
226 * the sleep index but here we use the wakeup period since that
227 * is what we need to do for the latency requirements.
228 */
229 static const u8 slp_succ_r0[IWL_POWER_VEC_SIZE] = { 2, 2, 2, 2, 2 };
230 static const u8 slp_succ_r1[IWL_POWER_VEC_SIZE] = { 2, 4, 6, 7, 9 };
231 static const u8 slp_succ_r2[IWL_POWER_VEC_SIZE] = { 2, 7, 9, 9, 0xFF };
232 const u8 *slp_succ = slp_succ_r0;
219 int i; 233 int i;
220 234
235 if (wakeup_period > IWL_DTIM_RANGE_0_MAX)
236 slp_succ = slp_succ_r1;
237 if (wakeup_period > IWL_DTIM_RANGE_1_MAX)
238 slp_succ = slp_succ_r2;
239
221 memset(cmd, 0, sizeof(*cmd)); 240 memset(cmd, 0, sizeof(*cmd));
222 241
223 cmd->flags = IWL_POWER_DRIVER_ALLOW_SLEEP_MSK | 242 cmd->flags = IWL_POWER_DRIVER_ALLOW_SLEEP_MSK |
@@ -230,7 +249,8 @@ static void iwl_power_fill_sleep_cmd(struct iwl_priv *priv,
230 cmd->tx_data_timeout = cpu_to_le32(1000 * dynps_ms); 249 cmd->tx_data_timeout = cpu_to_le32(1000 * dynps_ms);
231 250
232 for (i = 0; i < IWL_POWER_VEC_SIZE; i++) 251 for (i = 0; i < IWL_POWER_VEC_SIZE; i++)
233 cmd->sleep_interval[i] = cpu_to_le32(wakeup_period); 252 cmd->sleep_interval[i] =
253 cpu_to_le32(min_t(int, slp_succ[i], wakeup_period));
234 254
235 IWL_DEBUG_POWER(priv, "Automatic sleep command\n"); 255 IWL_DEBUG_POWER(priv, "Automatic sleep command\n");
236} 256}
@@ -301,7 +321,7 @@ int iwl_power_update_mode(struct iwl_priv *priv, bool force)
301 if (priv->cfg->ops->lib->update_chain_flags && 321 if (priv->cfg->ops->lib->update_chain_flags &&
302 update_chains) 322 update_chains)
303 priv->cfg->ops->lib->update_chain_flags(priv); 323 priv->cfg->ops->lib->update_chain_flags(priv);
304 else 324 else if (priv->cfg->ops->lib->update_chain_flags)
305 IWL_DEBUG_POWER(priv, 325 IWL_DEBUG_POWER(priv,
306 "Cannot update the power, chain noise " 326 "Cannot update the power, chain noise "
307 "calibration running: %d\n", 327 "calibration running: %d\n",
diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c
index e34d3fcb6c3d..8150c5c3a16b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-rx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-rx.c
@@ -962,6 +962,9 @@ void iwl_rx_reply_rx(struct iwl_priv *priv,
962 return; 962 return;
963 } 963 }
964 964
965 /* This will be used in several places later */
966 rate_n_flags = le32_to_cpu(phy_res->rate_n_flags);
967
965 /* rx_status carries information about the packet to mac80211 */ 968 /* rx_status carries information about the packet to mac80211 */
966 rx_status.mactime = le64_to_cpu(phy_res->timestamp); 969 rx_status.mactime = le64_to_cpu(phy_res->timestamp);
967 rx_status.freq = 970 rx_status.freq =
@@ -969,10 +972,7 @@ void iwl_rx_reply_rx(struct iwl_priv *priv,
969 rx_status.band = (phy_res->phy_flags & RX_RES_PHY_FLAGS_BAND_24_MSK) ? 972 rx_status.band = (phy_res->phy_flags & RX_RES_PHY_FLAGS_BAND_24_MSK) ?
970 IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ; 973 IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ;
971 rx_status.rate_idx = 974 rx_status.rate_idx =
972 iwl_hwrate_to_plcp_idx(le32_to_cpu(phy_res->rate_n_flags)); 975 iwl_hwrate_to_mac80211_idx(rate_n_flags, rx_status.band);
973 if (rx_status.band == IEEE80211_BAND_5GHZ)
974 rx_status.rate_idx -= IWL_FIRST_OFDM_RATE;
975
976 rx_status.flag = 0; 976 rx_status.flag = 0;
977 977
978 /* TSF isn't reliable. In order to allow smooth user experience, 978 /* TSF isn't reliable. In order to allow smooth user experience,
@@ -1034,7 +1034,6 @@ void iwl_rx_reply_rx(struct iwl_priv *priv,
1034 rx_status.flag |= RX_FLAG_SHORTPRE; 1034 rx_status.flag |= RX_FLAG_SHORTPRE;
1035 1035
1036 /* Set up the HT phy flags */ 1036 /* Set up the HT phy flags */
1037 rate_n_flags = le32_to_cpu(phy_res->rate_n_flags);
1038 if (rate_n_flags & RATE_MCS_HT_MSK) 1037 if (rate_n_flags & RATE_MCS_HT_MSK)
1039 rx_status.flag |= RX_FLAG_HT; 1038 rx_status.flag |= RX_FLAG_HT;
1040 if (rate_n_flags & RATE_MCS_HT40_MSK) 1039 if (rate_n_flags & RATE_MCS_HT40_MSK)
diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c
index 7bc9c0039f79..a7422e52d883 100644
--- a/drivers/net/wireless/iwlwifi/iwl-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-tx.c
@@ -566,62 +566,81 @@ static void iwl_tx_cmd_build_basic(struct iwl_priv *priv,
566static void iwl_tx_cmd_build_rate(struct iwl_priv *priv, 566static void iwl_tx_cmd_build_rate(struct iwl_priv *priv,
567 struct iwl_tx_cmd *tx_cmd, 567 struct iwl_tx_cmd *tx_cmd,
568 struct ieee80211_tx_info *info, 568 struct ieee80211_tx_info *info,
569 __le16 fc, int sta_id, 569 __le16 fc, int is_hcca)
570 int is_hcca)
571{ 570{
572 u32 rate_flags = 0; 571 u32 rate_flags;
573 int rate_idx; 572 int rate_idx;
574 u8 rts_retry_limit = 0; 573 u8 rts_retry_limit;
575 u8 data_retry_limit = 0; 574 u8 data_retry_limit;
576 u8 rate_plcp; 575 u8 rate_plcp;
577 576
578 rate_idx = min(ieee80211_get_tx_rate(priv->hw, info)->hw_value & 0xffff, 577 /* Set retry limit on DATA packets and Probe Responses*/
579 IWL_RATE_COUNT - 1);
580
581 rate_plcp = iwl_rates[rate_idx].plcp;
582
583 rts_retry_limit = (is_hcca) ?
584 RTS_HCCA_RETRY_LIMIT : RTS_DFAULT_RETRY_LIMIT;
585
586 if ((rate_idx >= IWL_FIRST_CCK_RATE) && (rate_idx <= IWL_LAST_CCK_RATE))
587 rate_flags |= RATE_MCS_CCK_MSK;
588
589
590 if (ieee80211_is_probe_resp(fc)) {
591 data_retry_limit = 3;
592 if (data_retry_limit < rts_retry_limit)
593 rts_retry_limit = data_retry_limit;
594 } else
595 data_retry_limit = IWL_DEFAULT_TX_RETRY;
596
597 if (priv->data_retry_limit != -1) 578 if (priv->data_retry_limit != -1)
598 data_retry_limit = priv->data_retry_limit; 579 data_retry_limit = priv->data_retry_limit;
580 else if (ieee80211_is_probe_resp(fc))
581 data_retry_limit = 3;
582 else
583 data_retry_limit = IWL_DEFAULT_TX_RETRY;
584 tx_cmd->data_retry_limit = data_retry_limit;
599 585
586 /* Set retry limit on RTS packets */
587 rts_retry_limit = (is_hcca) ? RTS_HCCA_RETRY_LIMIT :
588 RTS_DFAULT_RETRY_LIMIT;
589 if (data_retry_limit < rts_retry_limit)
590 rts_retry_limit = data_retry_limit;
591 tx_cmd->rts_retry_limit = rts_retry_limit;
600 592
593 /* DATA packets will use the uCode station table for rate/antenna
594 * selection */
601 if (ieee80211_is_data(fc)) { 595 if (ieee80211_is_data(fc)) {
602 tx_cmd->initial_rate_index = 0; 596 tx_cmd->initial_rate_index = 0;
603 tx_cmd->tx_flags |= TX_CMD_FLG_STA_RATE_MSK; 597 tx_cmd->tx_flags |= TX_CMD_FLG_STA_RATE_MSK;
604 } else { 598 return;
605 switch (fc & cpu_to_le16(IEEE80211_FCTL_STYPE)) { 599 }
606 case cpu_to_le16(IEEE80211_STYPE_AUTH): 600
607 case cpu_to_le16(IEEE80211_STYPE_DEAUTH): 601 /**
608 case cpu_to_le16(IEEE80211_STYPE_ASSOC_REQ): 602 * If the current TX rate stored in mac80211 has the MCS bit set, it's
609 case cpu_to_le16(IEEE80211_STYPE_REASSOC_REQ): 603 * not really a TX rate. Thus, we use the lowest supported rate for
610 if (tx_cmd->tx_flags & TX_CMD_FLG_RTS_MSK) { 604 * this band. Also use the lowest supported rate if the stored rate
611 tx_cmd->tx_flags &= ~TX_CMD_FLG_RTS_MSK; 605 * index is invalid.
612 tx_cmd->tx_flags |= TX_CMD_FLG_CTS_MSK; 606 */
613 } 607 rate_idx = info->control.rates[0].idx;
614 break; 608 if (info->control.rates[0].flags & IEEE80211_TX_RC_MCS ||
615 default: 609 (rate_idx < 0) || (rate_idx > IWL_RATE_COUNT_LEGACY))
616 break; 610 rate_idx = rate_lowest_index(&priv->bands[info->band],
617 } 611 info->control.sta);
612 /* For 5 GHZ band, remap mac80211 rate indices into driver indices */
613 if (info->band == IEEE80211_BAND_5GHZ)
614 rate_idx += IWL_FIRST_OFDM_RATE;
615 /* Get PLCP rate for tx_cmd->rate_n_flags */
616 rate_plcp = iwl_rates[rate_idx].plcp;
617 /* Zero out flags for this packet */
618 rate_flags = 0;
618 619
619 priv->mgmt_tx_ant = iwl_toggle_tx_ant(priv, priv->mgmt_tx_ant); 620 /* Set CCK flag as needed */
620 rate_flags |= iwl_ant_idx_to_flags(priv->mgmt_tx_ant); 621 if ((rate_idx >= IWL_FIRST_CCK_RATE) && (rate_idx <= IWL_LAST_CCK_RATE))
622 rate_flags |= RATE_MCS_CCK_MSK;
623
624 /* Set up RTS and CTS flags for certain packets */
625 switch (fc & cpu_to_le16(IEEE80211_FCTL_STYPE)) {
626 case cpu_to_le16(IEEE80211_STYPE_AUTH):
627 case cpu_to_le16(IEEE80211_STYPE_DEAUTH):
628 case cpu_to_le16(IEEE80211_STYPE_ASSOC_REQ):
629 case cpu_to_le16(IEEE80211_STYPE_REASSOC_REQ):
630 if (tx_cmd->tx_flags & TX_CMD_FLG_RTS_MSK) {
631 tx_cmd->tx_flags &= ~TX_CMD_FLG_RTS_MSK;
632 tx_cmd->tx_flags |= TX_CMD_FLG_CTS_MSK;
633 }
634 break;
635 default:
636 break;
621 } 637 }
622 638
623 tx_cmd->rts_retry_limit = rts_retry_limit; 639 /* Set up antennas */
624 tx_cmd->data_retry_limit = data_retry_limit; 640 priv->mgmt_tx_ant = iwl_toggle_tx_ant(priv, priv->mgmt_tx_ant);
641 rate_flags |= iwl_ant_idx_to_flags(priv->mgmt_tx_ant);
642
643 /* Set the rate in the TX cmd */
625 tx_cmd->rate_n_flags = iwl_hw_set_rate_n_flags(rate_plcp, rate_flags); 644 tx_cmd->rate_n_flags = iwl_hw_set_rate_n_flags(rate_plcp, rate_flags);
626} 645}
627 646
@@ -701,12 +720,6 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
701 goto drop_unlock; 720 goto drop_unlock;
702 } 721 }
703 722
704 if ((ieee80211_get_tx_rate(priv->hw, info)->hw_value & 0xFF) ==
705 IWL_INVALID_RATE) {
706 IWL_ERR(priv, "ERROR: No TX rate available.\n");
707 goto drop_unlock;
708 }
709
710 fc = hdr->frame_control; 723 fc = hdr->frame_control;
711 724
712#ifdef CONFIG_IWLWIFI_DEBUG 725#ifdef CONFIG_IWLWIFI_DEBUG
@@ -807,7 +820,7 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
807 iwl_dbg_log_tx_data_frame(priv, len, hdr); 820 iwl_dbg_log_tx_data_frame(priv, len, hdr);
808 821
809 /* set is_hcca to 0; it probably will never be implemented */ 822 /* set is_hcca to 0; it probably will never be implemented */
810 iwl_tx_cmd_build_rate(priv, tx_cmd, info, fc, sta_id, 0); 823 iwl_tx_cmd_build_rate(priv, tx_cmd, info, fc, 0);
811 824
812 iwl_update_stats(priv, true, fc, len); 825 iwl_update_stats(priv, true, fc, len);
813 /* 826 /*
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index 34790413eadd..2238c9f2018c 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -1373,7 +1373,7 @@ static void iwl3945_rx_handle(struct iwl_priv *priv)
1373 fill_rx = 1; 1373 fill_rx = 1;
1374 /* Rx interrupt, but nothing sent from uCode */ 1374 /* Rx interrupt, but nothing sent from uCode */
1375 if (i == r) 1375 if (i == r)
1376 IWL_DEBUG(priv, IWL_DL_RX | IWL_DL_ISR, "r = %d, i = %d\n", r, i); 1376 IWL_DEBUG_RX(priv, "r = %d, i = %d\n", r, i);
1377 1377
1378 while (i != r) { 1378 while (i != r) {
1379 rxb = rxq->queue[i]; 1379 rxb = rxq->queue[i];
@@ -1404,15 +1404,13 @@ static void iwl3945_rx_handle(struct iwl_priv *priv)
1404 * handle those that need handling via function in 1404 * handle those that need handling via function in
1405 * rx_handlers table. See iwl3945_setup_rx_handlers() */ 1405 * rx_handlers table. See iwl3945_setup_rx_handlers() */
1406 if (priv->rx_handlers[pkt->hdr.cmd]) { 1406 if (priv->rx_handlers[pkt->hdr.cmd]) {
1407 IWL_DEBUG(priv, IWL_DL_HCMD | IWL_DL_RX | IWL_DL_ISR, 1407 IWL_DEBUG_RX(priv, "r = %d, i = %d, %s, 0x%02x\n", r, i,
1408 "r = %d, i = %d, %s, 0x%02x\n", r, i,
1409 get_cmd_string(pkt->hdr.cmd), pkt->hdr.cmd); 1408 get_cmd_string(pkt->hdr.cmd), pkt->hdr.cmd);
1410 priv->rx_handlers[pkt->hdr.cmd] (priv, rxb); 1409 priv->rx_handlers[pkt->hdr.cmd] (priv, rxb);
1411 priv->isr_stats.rx_handlers[pkt->hdr.cmd]++; 1410 priv->isr_stats.rx_handlers[pkt->hdr.cmd]++;
1412 } else { 1411 } else {
1413 /* No handling needed */ 1412 /* No handling needed */
1414 IWL_DEBUG(priv, IWL_DL_HCMD | IWL_DL_RX | IWL_DL_ISR, 1413 IWL_DEBUG_RX(priv, "r %d i %d No handler needed for %s, 0x%02x\n",
1415 "r %d i %d No handler needed for %s, 0x%02x\n",
1416 r, i, get_cmd_string(pkt->hdr.cmd), 1414 r, i, get_cmd_string(pkt->hdr.cmd),
1417 pkt->hdr.cmd); 1415 pkt->hdr.cmd);
1418 } 1416 }
diff --git a/drivers/net/wireless/iwmc3200wifi/cfg80211.c b/drivers/net/wireless/iwmc3200wifi/cfg80211.c
index a6e852f4f92c..a56a2b0ac99a 100644
--- a/drivers/net/wireless/iwmc3200wifi/cfg80211.c
+++ b/drivers/net/wireless/iwmc3200wifi/cfg80211.c
@@ -238,8 +238,9 @@ static int iwm_cfg80211_set_default_key(struct wiphy *wiphy,
238 return iwm_set_tx_key(iwm, key_index); 238 return iwm_set_tx_key(iwm, key_index);
239} 239}
240 240
241int iwm_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev, 241static int iwm_cfg80211_get_station(struct wiphy *wiphy,
242 u8 *mac, struct station_info *sinfo) 242 struct net_device *ndev,
243 u8 *mac, struct station_info *sinfo)
243{ 244{
244 struct iwm_priv *iwm = ndev_to_iwm(ndev); 245 struct iwm_priv *iwm = ndev_to_iwm(ndev);
245 246
@@ -326,11 +327,8 @@ static int iwm_cfg80211_change_iface(struct wiphy *wiphy,
326 327
327 iwm->umac_profile->mode = cpu_to_le32(iwm->conf.mode); 328 iwm->umac_profile->mode = cpu_to_le32(iwm->conf.mode);
328 329
329 if (iwm->umac_profile_active) { 330 if (iwm->umac_profile_active)
330 int ret = iwm_invalidate_mlme_profile(iwm); 331 iwm_invalidate_mlme_profile(iwm);
331 if (ret < 0)
332 IWM_ERR(iwm, "Couldn't invalidate profile\n");
333 }
334 332
335 return 0; 333 return 0;
336} 334}
@@ -565,6 +563,7 @@ static int iwm_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
565{ 563{
566 struct iwm_priv *iwm = wiphy_to_iwm(wiphy); 564 struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
567 struct ieee80211_channel *chan = sme->channel; 565 struct ieee80211_channel *chan = sme->channel;
566 struct key_params key_param;
568 int ret; 567 int ret;
569 568
570 if (!test_bit(IWM_STATUS_READY, &iwm->status)) 569 if (!test_bit(IWM_STATUS_READY, &iwm->status))
@@ -573,6 +572,14 @@ static int iwm_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
573 if (!sme->ssid) 572 if (!sme->ssid)
574 return -EINVAL; 573 return -EINVAL;
575 574
575 if (iwm->umac_profile_active) {
576 ret = iwm_invalidate_mlme_profile(iwm);
577 if (ret) {
578 IWM_ERR(iwm, "Couldn't invalidate profile\n");
579 return ret;
580 }
581 }
582
576 if (chan) 583 if (chan)
577 iwm->channel = 584 iwm->channel =
578 ieee80211_frequency_to_channel(chan->center_freq); 585 ieee80211_frequency_to_channel(chan->center_freq);
@@ -614,7 +621,48 @@ static int iwm_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
614 return ret; 621 return ret;
615 } 622 }
616 623
617 return iwm_send_mlme_profile(iwm); 624 /*
625 * We save the WEP key in case we want to do shared authentication.
626 * We have to do it so because UMAC will assert whenever it gets a
627 * key before a profile.
628 */
629 if (sme->key) {
630 key_param.key = kmemdup(sme->key, sme->key_len, GFP_KERNEL);
631 if (key_param.key == NULL)
632 return -ENOMEM;
633 key_param.key_len = sme->key_len;
634 key_param.seq_len = 0;
635 key_param.cipher = sme->crypto.ciphers_pairwise[0];
636
637 ret = iwm_key_init(&iwm->keys[sme->key_idx], sme->key_idx,
638 NULL, &key_param);
639 kfree(key_param.key);
640 if (ret < 0) {
641 IWM_ERR(iwm, "Invalid key_params\n");
642 return ret;
643 }
644
645 iwm->default_key = sme->key_idx;
646 }
647
648 ret = iwm_send_mlme_profile(iwm);
649
650 if (iwm->umac_profile->sec.auth_type != UMAC_AUTH_TYPE_LEGACY_PSK ||
651 sme->key == NULL)
652 return ret;
653
654 /*
655 * We want to do shared auth.
656 * We need to actually set the key we previously cached,
657 * and then tell the UMAC it's the default one.
658 * That will trigger the auth+assoc UMAC machinery, and again,
659 * this must be done after setting the profile.
660 */
661 ret = iwm_set_key(iwm, 0, &iwm->keys[sme->key_idx]);
662 if (ret < 0)
663 return ret;
664
665 return iwm_set_tx_key(iwm, iwm->default_key);
618} 666}
619 667
620static int iwm_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev, 668static int iwm_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev,
@@ -625,7 +673,7 @@ static int iwm_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev,
625 IWM_DBG_WEXT(iwm, DBG, "Active: %d\n", iwm->umac_profile_active); 673 IWM_DBG_WEXT(iwm, DBG, "Active: %d\n", iwm->umac_profile_active);
626 674
627 if (iwm->umac_profile_active) 675 if (iwm->umac_profile_active)
628 return iwm_invalidate_mlme_profile(iwm); 676 iwm_invalidate_mlme_profile(iwm);
629 677
630 return 0; 678 return 0;
631} 679}
diff --git a/drivers/net/wireless/iwmc3200wifi/commands.c b/drivers/net/wireless/iwmc3200wifi/commands.c
index a68a2aff3c1e..23b52fa2605f 100644
--- a/drivers/net/wireless/iwmc3200wifi/commands.c
+++ b/drivers/net/wireless/iwmc3200wifi/commands.c
@@ -756,6 +756,7 @@ int iwm_send_mlme_profile(struct iwm_priv *iwm)
756 return ret; 756 return ret;
757 } 757 }
758 758
759 set_bit(IWM_STATUS_SME_CONNECTING, &iwm->status);
759 return 0; 760 return 0;
760} 761}
761 762
diff --git a/drivers/net/wireless/iwmc3200wifi/debug.h b/drivers/net/wireless/iwmc3200wifi/debug.h
index 8fbb42d9c21f..e35c9b693d1f 100644
--- a/drivers/net/wireless/iwmc3200wifi/debug.h
+++ b/drivers/net/wireless/iwmc3200wifi/debug.h
@@ -108,6 +108,8 @@ struct iwm_debugfs {
108 struct dentry *txq_dentry; 108 struct dentry *txq_dentry;
109 struct dentry *tx_credit_dentry; 109 struct dentry *tx_credit_dentry;
110 struct dentry *rx_ticket_dentry; 110 struct dentry *rx_ticket_dentry;
111
112 struct dentry *fw_err_dentry;
111}; 113};
112 114
113#ifdef CONFIG_IWM_DEBUG 115#ifdef CONFIG_IWM_DEBUG
diff --git a/drivers/net/wireless/iwmc3200wifi/debugfs.c b/drivers/net/wireless/iwmc3200wifi/debugfs.c
index 0fa7b9150d58..1465379f900a 100644
--- a/drivers/net/wireless/iwmc3200wifi/debugfs.c
+++ b/drivers/net/wireless/iwmc3200wifi/debugfs.c
@@ -98,7 +98,7 @@ DEFINE_SIMPLE_ATTRIBUTE(fops_iwm_dbg_modules,
98 iwm_debugfs_u32_read, iwm_debugfs_dbg_modules_write, 98 iwm_debugfs_u32_read, iwm_debugfs_dbg_modules_write,
99 "%llu\n"); 99 "%llu\n");
100 100
101static int iwm_txrx_open(struct inode *inode, struct file *filp) 101static int iwm_generic_open(struct inode *inode, struct file *filp)
102{ 102{
103 filp->private_data = inode->i_private; 103 filp->private_data = inode->i_private;
104 return 0; 104 return 0;
@@ -289,25 +289,111 @@ static ssize_t iwm_debugfs_rx_ticket_read(struct file *filp,
289 return ret; 289 return ret;
290} 290}
291 291
292static ssize_t iwm_debugfs_fw_err_read(struct file *filp,
293 char __user *buffer,
294 size_t count, loff_t *ppos)
295{
296
297 struct iwm_priv *iwm = filp->private_data;
298 char buf[512];
299 int buf_len = 512;
300 size_t len = 0;
301
302 if (*ppos != 0)
303 return 0;
304 if (count < sizeof(buf))
305 return -ENOSPC;
306
307 if (!iwm->last_fw_err)
308 return -ENOMEM;
309
310 if (iwm->last_fw_err->line_num == 0)
311 goto out;
312
313 len += snprintf(buf + len, buf_len - len, "%cMAC FW ERROR:\n",
314 (le32_to_cpu(iwm->last_fw_err->category) == UMAC_SYS_ERR_CAT_LMAC)
315 ? 'L' : 'U');
316 len += snprintf(buf + len, buf_len - len,
317 "\tCategory: %d\n",
318 le32_to_cpu(iwm->last_fw_err->category));
319
320 len += snprintf(buf + len, buf_len - len,
321 "\tStatus: 0x%x\n",
322 le32_to_cpu(iwm->last_fw_err->status));
323
324 len += snprintf(buf + len, buf_len - len,
325 "\tPC: 0x%x\n",
326 le32_to_cpu(iwm->last_fw_err->pc));
327
328 len += snprintf(buf + len, buf_len - len,
329 "\tblink1: %d\n",
330 le32_to_cpu(iwm->last_fw_err->blink1));
331
332 len += snprintf(buf + len, buf_len - len,
333 "\tblink2: %d\n",
334 le32_to_cpu(iwm->last_fw_err->blink2));
335
336 len += snprintf(buf + len, buf_len - len,
337 "\tilink1: %d\n",
338 le32_to_cpu(iwm->last_fw_err->ilink1));
339
340 len += snprintf(buf + len, buf_len - len,
341 "\tilink2: %d\n",
342 le32_to_cpu(iwm->last_fw_err->ilink2));
343
344 len += snprintf(buf + len, buf_len - len,
345 "\tData1: 0x%x\n",
346 le32_to_cpu(iwm->last_fw_err->data1));
347
348 len += snprintf(buf + len, buf_len - len,
349 "\tData2: 0x%x\n",
350 le32_to_cpu(iwm->last_fw_err->data2));
351
352 len += snprintf(buf + len, buf_len - len,
353 "\tLine number: %d\n",
354 le32_to_cpu(iwm->last_fw_err->line_num));
355
356 len += snprintf(buf + len, buf_len - len,
357 "\tUMAC status: 0x%x\n",
358 le32_to_cpu(iwm->last_fw_err->umac_status));
359
360 len += snprintf(buf + len, buf_len - len,
361 "\tLMAC status: 0x%x\n",
362 le32_to_cpu(iwm->last_fw_err->lmac_status));
363
364 len += snprintf(buf + len, buf_len - len,
365 "\tSDIO status: 0x%x\n",
366 le32_to_cpu(iwm->last_fw_err->sdio_status));
367
368out:
369
370 return simple_read_from_buffer(buffer, len, ppos, buf, buf_len);
371}
292 372
293static const struct file_operations iwm_debugfs_txq_fops = { 373static const struct file_operations iwm_debugfs_txq_fops = {
294 .owner = THIS_MODULE, 374 .owner = THIS_MODULE,
295 .open = iwm_txrx_open, 375 .open = iwm_generic_open,
296 .read = iwm_debugfs_txq_read, 376 .read = iwm_debugfs_txq_read,
297}; 377};
298 378
299static const struct file_operations iwm_debugfs_tx_credit_fops = { 379static const struct file_operations iwm_debugfs_tx_credit_fops = {
300 .owner = THIS_MODULE, 380 .owner = THIS_MODULE,
301 .open = iwm_txrx_open, 381 .open = iwm_generic_open,
302 .read = iwm_debugfs_tx_credit_read, 382 .read = iwm_debugfs_tx_credit_read,
303}; 383};
304 384
305static const struct file_operations iwm_debugfs_rx_ticket_fops = { 385static const struct file_operations iwm_debugfs_rx_ticket_fops = {
306 .owner = THIS_MODULE, 386 .owner = THIS_MODULE,
307 .open = iwm_txrx_open, 387 .open = iwm_generic_open,
308 .read = iwm_debugfs_rx_ticket_read, 388 .read = iwm_debugfs_rx_ticket_read,
309}; 389};
310 390
391static const struct file_operations iwm_debugfs_fw_err_fops = {
392 .owner = THIS_MODULE,
393 .open = iwm_generic_open,
394 .read = iwm_debugfs_fw_err_read,
395};
396
311int iwm_debugfs_init(struct iwm_priv *iwm) 397int iwm_debugfs_init(struct iwm_priv *iwm)
312{ 398{
313 int i, result; 399 int i, result;
@@ -423,6 +509,16 @@ int iwm_debugfs_init(struct iwm_priv *iwm)
423 goto error; 509 goto error;
424 } 510 }
425 511
512 iwm->dbg.fw_err_dentry = debugfs_create_file("last_fw_err", 0200,
513 iwm->dbg.dbgdir, iwm,
514 &iwm_debugfs_fw_err_fops);
515 result = PTR_ERR(iwm->dbg.fw_err_dentry);
516 if (IS_ERR(iwm->dbg.fw_err_dentry) && (result != -ENODEV)) {
517 IWM_ERR(iwm, "Couldn't create last FW err: %d\n", result);
518 goto error;
519 }
520
521
426 return 0; 522 return 0;
427 523
428 error: 524 error:
@@ -441,6 +537,7 @@ void iwm_debugfs_exit(struct iwm_priv *iwm)
441 debugfs_remove(iwm->dbg.txq_dentry); 537 debugfs_remove(iwm->dbg.txq_dentry);
442 debugfs_remove(iwm->dbg.tx_credit_dentry); 538 debugfs_remove(iwm->dbg.tx_credit_dentry);
443 debugfs_remove(iwm->dbg.rx_ticket_dentry); 539 debugfs_remove(iwm->dbg.rx_ticket_dentry);
540 debugfs_remove(iwm->dbg.fw_err_dentry);
444 if (iwm->bus_ops->debugfs_exit) 541 if (iwm->bus_ops->debugfs_exit)
445 iwm->bus_ops->debugfs_exit(iwm); 542 iwm->bus_ops->debugfs_exit(iwm);
446 543
diff --git a/drivers/net/wireless/iwmc3200wifi/fw.c b/drivers/net/wireless/iwmc3200wifi/fw.c
index 0f32cab9ced4..6b0bcad758ca 100644
--- a/drivers/net/wireless/iwmc3200wifi/fw.c
+++ b/drivers/net/wireless/iwmc3200wifi/fw.c
@@ -261,6 +261,33 @@ static int iwm_load_lmac(struct iwm_priv *iwm, const char *img_name)
261 cpu_to_le32(UMAC_RST_CTRL_FLG_LARC_CLK_EN), 0); 261 cpu_to_le32(UMAC_RST_CTRL_FLG_LARC_CLK_EN), 0);
262} 262}
263 263
264static int iwm_init_calib(struct iwm_priv *iwm, unsigned long cfg_bitmap,
265 unsigned long expected_bitmap, u8 rx_iq_cmd)
266{
267 /* Read RX IQ calibration result from EEPROM */
268 if (test_bit(rx_iq_cmd, &cfg_bitmap)) {
269 iwm_store_rxiq_calib_result(iwm);
270 set_bit(PHY_CALIBRATE_RX_IQ_CMD, &iwm->calib_done_map);
271 }
272
273 iwm_send_prio_table(iwm);
274 iwm_send_init_calib_cfg(iwm, cfg_bitmap);
275
276 while (iwm->calib_done_map != expected_bitmap) {
277 if (iwm_notif_handle(iwm, CALIBRATION_RES_NOTIFICATION,
278 IWM_SRC_LMAC, WAIT_NOTIF_TIMEOUT)) {
279 IWM_DBG_FW(iwm, DBG, "Initial calibration timeout\n");
280 return -ETIMEDOUT;
281 }
282
283 IWM_DBG_FW(iwm, DBG, "Got calibration result. calib_done_map: "
284 "0x%lx, expected calibrations: 0x%lx\n",
285 iwm->calib_done_map, expected_bitmap);
286 }
287
288 return 0;
289}
290
264/* 291/*
265 * We currently have to load 3 FWs: 292 * We currently have to load 3 FWs:
266 * 1) The UMAC (Upper MAC). 293 * 1) The UMAC (Upper MAC).
@@ -276,6 +303,7 @@ static int iwm_load_lmac(struct iwm_priv *iwm, const char *img_name)
276int iwm_load_fw(struct iwm_priv *iwm) 303int iwm_load_fw(struct iwm_priv *iwm)
277{ 304{
278 unsigned long init_calib_map, periodic_calib_map; 305 unsigned long init_calib_map, periodic_calib_map;
306 unsigned long expected_calib_map;
279 int ret; 307 int ret;
280 308
281 /* We first start downloading the UMAC */ 309 /* We first start downloading the UMAC */
@@ -317,27 +345,21 @@ int iwm_load_fw(struct iwm_priv *iwm)
317 } 345 }
318 346
319 init_calib_map = iwm->conf.calib_map & IWM_CALIB_MAP_INIT_MSK; 347 init_calib_map = iwm->conf.calib_map & IWM_CALIB_MAP_INIT_MSK;
348 expected_calib_map = iwm->conf.expected_calib_map &
349 IWM_CALIB_MAP_INIT_MSK;
320 periodic_calib_map = IWM_CALIB_MAP_PER_LMAC(iwm->conf.calib_map); 350 periodic_calib_map = IWM_CALIB_MAP_PER_LMAC(iwm->conf.calib_map);
321 351
322 /* Read RX IQ calibration result from EEPROM */ 352 ret = iwm_init_calib(iwm, init_calib_map, expected_calib_map,
323 if (test_bit(PHY_CALIBRATE_RX_IQ_CMD, &init_calib_map)) { 353 CALIB_CFG_RX_IQ_IDX);
324 iwm_store_rxiq_calib_result(iwm); 354 if (ret < 0) {
325 set_bit(PHY_CALIBRATE_RX_IQ_CMD, &iwm->calib_done_map); 355 /* Let's try the old way */
326 } 356 ret = iwm_init_calib(iwm, expected_calib_map,
327 357 expected_calib_map,
328 iwm_send_prio_table(iwm); 358 PHY_CALIBRATE_RX_IQ_CMD);
329 iwm_send_init_calib_cfg(iwm, init_calib_map); 359 if (ret < 0) {
330 360 IWM_ERR(iwm, "Calibration result timeout\n");
331 while (iwm->calib_done_map != init_calib_map) {
332 ret = iwm_notif_handle(iwm, CALIBRATION_RES_NOTIFICATION,
333 IWM_SRC_LMAC, WAIT_NOTIF_TIMEOUT);
334 if (ret) {
335 IWM_ERR(iwm, "Wait for calibration result timeout\n");
336 goto out; 361 goto out;
337 } 362 }
338 IWM_DBG_FW(iwm, DBG, "Got calibration result. calib_done_map: "
339 "0x%lx, requested calibrations: 0x%lx\n",
340 iwm->calib_done_map, init_calib_map);
341 } 363 }
342 364
343 /* Handle LMAC CALIBRATION_COMPLETE notification */ 365 /* Handle LMAC CALIBRATION_COMPLETE notification */
diff --git a/drivers/net/wireless/iwmc3200wifi/iwm.h b/drivers/net/wireless/iwmc3200wifi/iwm.h
index 7a51bc340fda..1b02a4e2a1ac 100644
--- a/drivers/net/wireless/iwmc3200wifi/iwm.h
+++ b/drivers/net/wireless/iwmc3200wifi/iwm.h
@@ -64,6 +64,7 @@
64struct iwm_conf { 64struct iwm_conf {
65 u32 sdio_ior_timeout; 65 u32 sdio_ior_timeout;
66 unsigned long calib_map; 66 unsigned long calib_map;
67 unsigned long expected_calib_map;
67 bool reset_on_fatal_err; 68 bool reset_on_fatal_err;
68 bool auto_connect; 69 bool auto_connect;
69 bool wimax_not_present; 70 bool wimax_not_present;
@@ -175,8 +176,9 @@ struct iwm_key {
175#define IWM_STATUS_READY 0 176#define IWM_STATUS_READY 0
176#define IWM_STATUS_SCANNING 1 177#define IWM_STATUS_SCANNING 1
177#define IWM_STATUS_SCAN_ABORTING 2 178#define IWM_STATUS_SCAN_ABORTING 2
178#define IWM_STATUS_ASSOCIATING 3 179#define IWM_STATUS_SME_CONNECTING 3
179#define IWM_STATUS_ASSOCIATED 4 180#define IWM_STATUS_ASSOCIATED 4
181#define IWM_STATUS_RESETTING 5
180 182
181struct iwm_tx_queue { 183struct iwm_tx_queue {
182 int id; 184 int id;
@@ -273,6 +275,7 @@ struct iwm_priv {
273 275
274 struct iw_statistics wstats; 276 struct iw_statistics wstats;
275 struct delayed_work stats_request; 277 struct delayed_work stats_request;
278 struct delayed_work disconnect;
276 279
277 struct iwm_debugfs dbg; 280 struct iwm_debugfs dbg;
278 281
@@ -286,6 +289,8 @@ struct iwm_priv {
286 u8 *resp_ie; 289 u8 *resp_ie;
287 int resp_ie_len; 290 int resp_ie_len;
288 291
292 struct iwm_fw_error_hdr *last_fw_err;
293
289 char private[0] __attribute__((__aligned__(NETDEV_ALIGN))); 294 char private[0] __attribute__((__aligned__(NETDEV_ALIGN)));
290}; 295};
291 296
@@ -315,6 +320,7 @@ int iwm_mode_to_nl80211_iftype(int mode);
315int iwm_priv_init(struct iwm_priv *iwm); 320int iwm_priv_init(struct iwm_priv *iwm);
316void iwm_priv_deinit(struct iwm_priv *iwm); 321void iwm_priv_deinit(struct iwm_priv *iwm);
317void iwm_reset(struct iwm_priv *iwm); 322void iwm_reset(struct iwm_priv *iwm);
323void iwm_resetting(struct iwm_priv *iwm);
318void iwm_tx_credit_init_pools(struct iwm_priv *iwm, 324void iwm_tx_credit_init_pools(struct iwm_priv *iwm,
319 struct iwm_umac_notif_alive *alive); 325 struct iwm_umac_notif_alive *alive);
320int iwm_tx_credit_alloc(struct iwm_priv *iwm, int id, int nb); 326int iwm_tx_credit_alloc(struct iwm_priv *iwm, int id, int nb);
diff --git a/drivers/net/wireless/iwmc3200wifi/lmac.h b/drivers/net/wireless/iwmc3200wifi/lmac.h
index 19213e165f5f..6c1a14c4480f 100644
--- a/drivers/net/wireless/iwmc3200wifi/lmac.h
+++ b/drivers/net/wireless/iwmc3200wifi/lmac.h
@@ -396,9 +396,24 @@ enum {
396 CALIBRATION_CMD_NUM, 396 CALIBRATION_CMD_NUM,
397}; 397};
398 398
399enum {
400 CALIB_CFG_RX_BB_IDX = 0,
401 CALIB_CFG_DC_IDX = 1,
402 CALIB_CFG_LO_IDX = 2,
403 CALIB_CFG_TX_IQ_IDX = 3,
404 CALIB_CFG_RX_IQ_IDX = 4,
405 CALIB_CFG_NOISE_IDX = 5,
406 CALIB_CFG_CRYSTAL_IDX = 6,
407 CALIB_CFG_TEMPERATURE_IDX = 7,
408 CALIB_CFG_PAPD_IDX = 8,
409 CALIB_CFG_LAST_IDX = CALIB_CFG_PAPD_IDX,
410 CALIB_CFG_MODULE_NUM,
411};
412
399#define IWM_CALIB_MAP_INIT_MSK 0xFFFF 413#define IWM_CALIB_MAP_INIT_MSK 0xFFFF
400#define IWM_CALIB_MAP_PER_LMAC(m) ((m & 0xFF0000) >> 16) 414#define IWM_CALIB_MAP_PER_LMAC(m) ((m & 0xFF0000) >> 16)
401#define IWM_CALIB_MAP_PER_UMAC(m) ((m & 0xFF000000) >> 24) 415#define IWM_CALIB_MAP_PER_UMAC(m) ((m & 0xFF000000) >> 24)
416#define IWM_CALIB_OPCODE_TO_INDEX(op) (op - PHY_CALIBRATE_OPCODES_NUM)
402 417
403struct iwm_lmac_calib_hdr { 418struct iwm_lmac_calib_hdr {
404 u8 opcode; 419 u8 opcode;
diff --git a/drivers/net/wireless/iwmc3200wifi/main.c b/drivers/net/wireless/iwmc3200wifi/main.c
index cf2574442b57..d668e4756324 100644
--- a/drivers/net/wireless/iwmc3200wifi/main.c
+++ b/drivers/net/wireless/iwmc3200wifi/main.c
@@ -53,7 +53,12 @@
53static struct iwm_conf def_iwm_conf = { 53static struct iwm_conf def_iwm_conf = {
54 54
55 .sdio_ior_timeout = 5000, 55 .sdio_ior_timeout = 5000,
56 .calib_map = BIT(PHY_CALIBRATE_DC_CMD) | 56 .calib_map = BIT(CALIB_CFG_DC_IDX) |
57 BIT(CALIB_CFG_LO_IDX) |
58 BIT(CALIB_CFG_TX_IQ_IDX) |
59 BIT(CALIB_CFG_RX_IQ_IDX) |
60 BIT(SHILOH_PHY_CALIBRATE_BASE_BAND_CMD),
61 .expected_calib_map = BIT(PHY_CALIBRATE_DC_CMD) |
57 BIT(PHY_CALIBRATE_LO_CMD) | 62 BIT(PHY_CALIBRATE_LO_CMD) |
58 BIT(PHY_CALIBRATE_TX_IQ_CMD) | 63 BIT(PHY_CALIBRATE_TX_IQ_CMD) |
59 BIT(PHY_CALIBRATE_RX_IQ_CMD) | 64 BIT(PHY_CALIBRATE_RX_IQ_CMD) |
@@ -108,8 +113,28 @@ static void iwm_statistics_request(struct work_struct *work)
108 iwm_send_umac_stats_req(iwm, 0); 113 iwm_send_umac_stats_req(iwm, 0);
109} 114}
110 115
111int __iwm_up(struct iwm_priv *iwm); 116static void iwm_disconnect_work(struct work_struct *work)
112int __iwm_down(struct iwm_priv *iwm); 117{
118 struct iwm_priv *iwm =
119 container_of(work, struct iwm_priv, disconnect.work);
120
121 if (iwm->umac_profile_active)
122 iwm_invalidate_mlme_profile(iwm);
123
124 clear_bit(IWM_STATUS_ASSOCIATED, &iwm->status);
125 iwm->umac_profile_active = 0;
126 memset(iwm->bssid, 0, ETH_ALEN);
127 iwm->channel = 0;
128
129 iwm_link_off(iwm);
130
131 wake_up_interruptible(&iwm->mlme_queue);
132
133 cfg80211_disconnected(iwm_to_ndev(iwm), 0, NULL, 0, GFP_KERNEL);
134}
135
136static int __iwm_up(struct iwm_priv *iwm);
137static int __iwm_down(struct iwm_priv *iwm);
113 138
114static void iwm_reset_worker(struct work_struct *work) 139static void iwm_reset_worker(struct work_struct *work)
115{ 140{
@@ -162,7 +187,8 @@ static void iwm_reset_worker(struct work_struct *work)
162 memcpy(iwm->umac_profile, profile, sizeof(*profile)); 187 memcpy(iwm->umac_profile, profile, sizeof(*profile));
163 iwm_send_mlme_profile(iwm); 188 iwm_send_mlme_profile(iwm);
164 kfree(profile); 189 kfree(profile);
165 } 190 } else
191 clear_bit(IWM_STATUS_RESETTING, &iwm->status);
166 192
167 out: 193 out:
168 mutex_unlock(&iwm->mutex); 194 mutex_unlock(&iwm->mutex);
@@ -175,7 +201,7 @@ static void iwm_watchdog(unsigned long data)
175 IWM_WARN(iwm, "Watchdog expired: UMAC stalls!\n"); 201 IWM_WARN(iwm, "Watchdog expired: UMAC stalls!\n");
176 202
177 if (modparam_reset) 203 if (modparam_reset)
178 schedule_work(&iwm->reset_worker); 204 iwm_resetting(iwm);
179} 205}
180 206
181int iwm_priv_init(struct iwm_priv *iwm) 207int iwm_priv_init(struct iwm_priv *iwm)
@@ -198,6 +224,7 @@ int iwm_priv_init(struct iwm_priv *iwm)
198 spin_lock_init(&iwm->cmd_lock); 224 spin_lock_init(&iwm->cmd_lock);
199 iwm->scan_id = 1; 225 iwm->scan_id = 1;
200 INIT_DELAYED_WORK(&iwm->stats_request, iwm_statistics_request); 226 INIT_DELAYED_WORK(&iwm->stats_request, iwm_statistics_request);
227 INIT_DELAYED_WORK(&iwm->disconnect, iwm_disconnect_work);
201 INIT_WORK(&iwm->reset_worker, iwm_reset_worker); 228 INIT_WORK(&iwm->reset_worker, iwm_reset_worker);
202 INIT_LIST_HEAD(&iwm->bss_list); 229 INIT_LIST_HEAD(&iwm->bss_list);
203 230
@@ -233,6 +260,11 @@ int iwm_priv_init(struct iwm_priv *iwm)
233 iwm->watchdog.data = (unsigned long)iwm; 260 iwm->watchdog.data = (unsigned long)iwm;
234 mutex_init(&iwm->mutex); 261 mutex_init(&iwm->mutex);
235 262
263 iwm->last_fw_err = kzalloc(sizeof(struct iwm_fw_error_hdr),
264 GFP_KERNEL);
265 if (iwm->last_fw_err == NULL)
266 return -ENOMEM;
267
236 return 0; 268 return 0;
237} 269}
238 270
@@ -244,6 +276,7 @@ void iwm_priv_deinit(struct iwm_priv *iwm)
244 destroy_workqueue(iwm->txq[i].wq); 276 destroy_workqueue(iwm->txq[i].wq);
245 277
246 destroy_workqueue(iwm->rx_wq); 278 destroy_workqueue(iwm->rx_wq);
279 kfree(iwm->last_fw_err);
247} 280}
248 281
249/* 282/*
@@ -258,7 +291,11 @@ void iwm_reset(struct iwm_priv *iwm)
258 if (test_bit(IWM_STATUS_READY, &iwm->status)) 291 if (test_bit(IWM_STATUS_READY, &iwm->status))
259 iwm_target_reset(iwm); 292 iwm_target_reset(iwm);
260 293
261 iwm->status = 0; 294 if (test_bit(IWM_STATUS_RESETTING, &iwm->status)) {
295 iwm->status = 0;
296 set_bit(IWM_STATUS_RESETTING, &iwm->status);
297 } else
298 iwm->status = 0;
262 iwm->scan_id = 1; 299 iwm->scan_id = 1;
263 300
264 list_for_each_entry_safe(notif, next, &iwm->pending_notif, pending) { 301 list_for_each_entry_safe(notif, next, &iwm->pending_notif, pending) {
@@ -274,6 +311,13 @@ void iwm_reset(struct iwm_priv *iwm)
274 iwm_link_off(iwm); 311 iwm_link_off(iwm);
275} 312}
276 313
314void iwm_resetting(struct iwm_priv *iwm)
315{
316 set_bit(IWM_STATUS_RESETTING, &iwm->status);
317
318 schedule_work(&iwm->reset_worker);
319}
320
277/* 321/*
278 * Notification code: 322 * Notification code:
279 * 323 *
@@ -538,7 +582,7 @@ static int iwm_channels_init(struct iwm_priv *iwm)
538 return 0; 582 return 0;
539} 583}
540 584
541int __iwm_up(struct iwm_priv *iwm) 585static int __iwm_up(struct iwm_priv *iwm)
542{ 586{
543 int ret; 587 int ret;
544 struct iwm_notif *notif_reboot, *notif_ack = NULL; 588 struct iwm_notif *notif_reboot, *notif_ack = NULL;
@@ -672,7 +716,7 @@ int iwm_up(struct iwm_priv *iwm)
672 return ret; 716 return ret;
673} 717}
674 718
675int __iwm_down(struct iwm_priv *iwm) 719static int __iwm_down(struct iwm_priv *iwm)
676{ 720{
677 int ret; 721 int ret;
678 722
diff --git a/drivers/net/wireless/iwmc3200wifi/rx.c b/drivers/net/wireless/iwmc3200wifi/rx.c
index 86079a187eef..40dbcbc16593 100644
--- a/drivers/net/wireless/iwmc3200wifi/rx.c
+++ b/drivers/net/wireless/iwmc3200wifi/rx.c
@@ -102,6 +102,8 @@ static int iwm_ntf_error(struct iwm_priv *iwm, u8 *buf,
102 error = (struct iwm_umac_notif_error *)buf; 102 error = (struct iwm_umac_notif_error *)buf;
103 fw_err = &error->err; 103 fw_err = &error->err;
104 104
105 memcpy(iwm->last_fw_err, fw_err, sizeof(struct iwm_fw_error_hdr));
106
105 IWM_ERR(iwm, "%cMAC FW ERROR:\n", 107 IWM_ERR(iwm, "%cMAC FW ERROR:\n",
106 (le32_to_cpu(fw_err->category) == UMAC_SYS_ERR_CAT_LMAC) ? 'L' : 'U'); 108 (le32_to_cpu(fw_err->category) == UMAC_SYS_ERR_CAT_LMAC) ? 'L' : 'U');
107 IWM_ERR(iwm, "\tCategory: %d\n", le32_to_cpu(fw_err->category)); 109 IWM_ERR(iwm, "\tCategory: %d\n", le32_to_cpu(fw_err->category));
@@ -118,6 +120,8 @@ static int iwm_ntf_error(struct iwm_priv *iwm, u8 *buf,
118 IWM_ERR(iwm, "\tLMAC status: 0x%x\n", le32_to_cpu(fw_err->lmac_status)); 120 IWM_ERR(iwm, "\tLMAC status: 0x%x\n", le32_to_cpu(fw_err->lmac_status));
119 IWM_ERR(iwm, "\tSDIO status: 0x%x\n", le32_to_cpu(fw_err->sdio_status)); 121 IWM_ERR(iwm, "\tSDIO status: 0x%x\n", le32_to_cpu(fw_err->sdio_status));
120 122
123 iwm_resetting(iwm);
124
121 return 0; 125 return 0;
122} 126}
123 127
@@ -487,8 +491,6 @@ static int iwm_mlme_assoc_start(struct iwm_priv *iwm, u8 *buf,
487 491
488 start = (struct iwm_umac_notif_assoc_start *)buf; 492 start = (struct iwm_umac_notif_assoc_start *)buf;
489 493
490 set_bit(IWM_STATUS_ASSOCIATING, &iwm->status);
491
492 IWM_DBG_MLME(iwm, INFO, "Association with %pM Started, reason: %d\n", 494 IWM_DBG_MLME(iwm, INFO, "Association with %pM Started, reason: %d\n",
493 start->bssid, le32_to_cpu(start->roam_reason)); 495 start->bssid, le32_to_cpu(start->roam_reason));
494 496
@@ -507,47 +509,80 @@ static int iwm_mlme_assoc_complete(struct iwm_priv *iwm, u8 *buf,
507 IWM_DBG_MLME(iwm, INFO, "Association with %pM completed, status: %d\n", 509 IWM_DBG_MLME(iwm, INFO, "Association with %pM completed, status: %d\n",
508 complete->bssid, complete->status); 510 complete->bssid, complete->status);
509 511
510 clear_bit(IWM_STATUS_ASSOCIATING, &iwm->status);
511
512 switch (le32_to_cpu(complete->status)) { 512 switch (le32_to_cpu(complete->status)) {
513 case UMAC_ASSOC_COMPLETE_SUCCESS: 513 case UMAC_ASSOC_COMPLETE_SUCCESS:
514 set_bit(IWM_STATUS_ASSOCIATED, &iwm->status); 514 set_bit(IWM_STATUS_ASSOCIATED, &iwm->status);
515 memcpy(iwm->bssid, complete->bssid, ETH_ALEN); 515 memcpy(iwm->bssid, complete->bssid, ETH_ALEN);
516 iwm->channel = complete->channel; 516 iwm->channel = complete->channel;
517 517
518 /* Internal roaming state, avoid notifying SME. */
519 if (!test_and_clear_bit(IWM_STATUS_SME_CONNECTING, &iwm->status)
520 && iwm->conf.mode == UMAC_MODE_BSS) {
521 cancel_delayed_work(&iwm->disconnect);
522 cfg80211_roamed(iwm_to_ndev(iwm),
523 complete->bssid,
524 iwm->req_ie, iwm->req_ie_len,
525 iwm->resp_ie, iwm->resp_ie_len,
526 GFP_KERNEL);
527 break;
528 }
529
518 iwm_link_on(iwm); 530 iwm_link_on(iwm);
519 531
520 if (iwm->conf.mode == UMAC_MODE_IBSS) 532 if (iwm->conf.mode == UMAC_MODE_IBSS)
521 goto ibss; 533 goto ibss;
522 534
523 cfg80211_connect_result(iwm_to_ndev(iwm), 535 if (!test_bit(IWM_STATUS_RESETTING, &iwm->status))
536 cfg80211_connect_result(iwm_to_ndev(iwm),
537 complete->bssid,
538 iwm->req_ie, iwm->req_ie_len,
539 iwm->resp_ie, iwm->resp_ie_len,
540 WLAN_STATUS_SUCCESS,
541 GFP_KERNEL);
542 else
543 cfg80211_roamed(iwm_to_ndev(iwm),
524 complete->bssid, 544 complete->bssid,
525 iwm->req_ie, iwm->req_ie_len, 545 iwm->req_ie, iwm->req_ie_len,
526 iwm->resp_ie, iwm->resp_ie_len, 546 iwm->resp_ie, iwm->resp_ie_len,
527 WLAN_STATUS_SUCCESS, GFP_KERNEL); 547 GFP_KERNEL);
528 break; 548 break;
529 case UMAC_ASSOC_COMPLETE_FAILURE: 549 case UMAC_ASSOC_COMPLETE_FAILURE:
530 clear_bit(IWM_STATUS_ASSOCIATED, &iwm->status); 550 clear_bit(IWM_STATUS_ASSOCIATED, &iwm->status);
531 memset(iwm->bssid, 0, ETH_ALEN); 551 memset(iwm->bssid, 0, ETH_ALEN);
532 iwm->channel = 0; 552 iwm->channel = 0;
533 553
554 /* Internal roaming state, avoid notifying SME. */
555 if (!test_and_clear_bit(IWM_STATUS_SME_CONNECTING, &iwm->status)
556 && iwm->conf.mode == UMAC_MODE_BSS) {
557 cancel_delayed_work(&iwm->disconnect);
558 break;
559 }
560
534 iwm_link_off(iwm); 561 iwm_link_off(iwm);
535 562
536 if (iwm->conf.mode == UMAC_MODE_IBSS) 563 if (iwm->conf.mode == UMAC_MODE_IBSS)
537 goto ibss; 564 goto ibss;
538 565
539 cfg80211_connect_result(iwm_to_ndev(iwm), complete->bssid, 566 if (!test_bit(IWM_STATUS_RESETTING, &iwm->status))
540 NULL, 0, NULL, 0, 567 cfg80211_connect_result(iwm_to_ndev(iwm),
541 WLAN_STATUS_UNSPECIFIED_FAILURE, 568 complete->bssid,
542 GFP_KERNEL); 569 NULL, 0, NULL, 0,
570 WLAN_STATUS_UNSPECIFIED_FAILURE,
571 GFP_KERNEL);
572 else
573 cfg80211_disconnected(iwm_to_ndev(iwm), 0, NULL, 0,
574 GFP_KERNEL);
575 break;
543 default: 576 default:
544 break; 577 break;
545 } 578 }
546 579
580 clear_bit(IWM_STATUS_RESETTING, &iwm->status);
547 return 0; 581 return 0;
548 582
549 ibss: 583 ibss:
550 cfg80211_ibss_joined(iwm_to_ndev(iwm), iwm->bssid, GFP_KERNEL); 584 cfg80211_ibss_joined(iwm_to_ndev(iwm), iwm->bssid, GFP_KERNEL);
585 clear_bit(IWM_STATUS_RESETTING, &iwm->status);
551 return 0; 586 return 0;
552} 587}
553 588
@@ -556,13 +591,20 @@ static int iwm_mlme_profile_invalidate(struct iwm_priv *iwm, u8 *buf,
556 struct iwm_wifi_cmd *cmd) 591 struct iwm_wifi_cmd *cmd)
557{ 592{
558 struct iwm_umac_notif_profile_invalidate *invalid; 593 struct iwm_umac_notif_profile_invalidate *invalid;
594 u32 reason;
559 595
560 invalid = (struct iwm_umac_notif_profile_invalidate *)buf; 596 invalid = (struct iwm_umac_notif_profile_invalidate *)buf;
597 reason = le32_to_cpu(invalid->reason);
561 598
562 IWM_DBG_MLME(iwm, INFO, "Profile Invalidated. Reason: %d\n", 599 IWM_DBG_MLME(iwm, INFO, "Profile Invalidated. Reason: %d\n", reason);
563 le32_to_cpu(invalid->reason));
564 600
565 clear_bit(IWM_STATUS_ASSOCIATING, &iwm->status); 601 if (reason != UMAC_PROFILE_INVALID_REQUEST &&
602 test_bit(IWM_STATUS_SME_CONNECTING, &iwm->status))
603 cfg80211_connect_result(iwm_to_ndev(iwm), NULL, NULL, 0, NULL,
604 0, WLAN_STATUS_UNSPECIFIED_FAILURE,
605 GFP_KERNEL);
606
607 clear_bit(IWM_STATUS_SME_CONNECTING, &iwm->status);
566 clear_bit(IWM_STATUS_ASSOCIATED, &iwm->status); 608 clear_bit(IWM_STATUS_ASSOCIATED, &iwm->status);
567 609
568 iwm->umac_profile_active = 0; 610 iwm->umac_profile_active = 0;
@@ -576,6 +618,19 @@ static int iwm_mlme_profile_invalidate(struct iwm_priv *iwm, u8 *buf,
576 return 0; 618 return 0;
577} 619}
578 620
621#define IWM_DISCONNECT_INTERVAL (5 * HZ)
622
623static int iwm_mlme_connection_terminated(struct iwm_priv *iwm, u8 *buf,
624 unsigned long buf_size,
625 struct iwm_wifi_cmd *cmd)
626{
627 IWM_DBG_MLME(iwm, DBG, "Connection terminated\n");
628
629 schedule_delayed_work(&iwm->disconnect, IWM_DISCONNECT_INTERVAL);
630
631 return 0;
632}
633
579static int iwm_mlme_scan_complete(struct iwm_priv *iwm, u8 *buf, 634static int iwm_mlme_scan_complete(struct iwm_priv *iwm, u8 *buf,
580 unsigned long buf_size, 635 unsigned long buf_size,
581 struct iwm_wifi_cmd *cmd) 636 struct iwm_wifi_cmd *cmd)
@@ -813,7 +868,8 @@ static int iwm_mlme_mgt_frame(struct iwm_priv *iwm, u8 *buf,
813 iwm->resp_ie = kmemdup(mgt->u.reassoc_resp.variable, 868 iwm->resp_ie = kmemdup(mgt->u.reassoc_resp.variable,
814 iwm->resp_ie_len, GFP_KERNEL); 869 iwm->resp_ie_len, GFP_KERNEL);
815 } else { 870 } else {
816 IWM_ERR(iwm, "Unsupported management frame"); 871 IWM_ERR(iwm, "Unsupported management frame: 0x%x",
872 le16_to_cpu(mgt->frame_control));
817 return 0; 873 return 0;
818 } 874 }
819 875
@@ -834,8 +890,7 @@ static int iwm_ntf_mlme(struct iwm_priv *iwm, u8 *buf,
834 case WIFI_IF_NTFY_PROFILE_INVALIDATE_COMPLETE: 890 case WIFI_IF_NTFY_PROFILE_INVALIDATE_COMPLETE:
835 return iwm_mlme_profile_invalidate(iwm, buf, buf_size, cmd); 891 return iwm_mlme_profile_invalidate(iwm, buf, buf_size, cmd);
836 case WIFI_IF_NTFY_CONNECTION_TERMINATED: 892 case WIFI_IF_NTFY_CONNECTION_TERMINATED:
837 IWM_DBG_MLME(iwm, DBG, "Connection terminated\n"); 893 return iwm_mlme_connection_terminated(iwm, buf, buf_size, cmd);
838 break;
839 case WIFI_IF_NTFY_SCAN_COMPLETE: 894 case WIFI_IF_NTFY_SCAN_COMPLETE:
840 return iwm_mlme_scan_complete(iwm, buf, buf_size, cmd); 895 return iwm_mlme_scan_complete(iwm, buf, buf_size, cmd);
841 case WIFI_IF_NTFY_STA_TABLE_CHANGE: 896 case WIFI_IF_NTFY_STA_TABLE_CHANGE:
diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c
index 402d36757765..54175b6fa86c 100644
--- a/drivers/net/wireless/rndis_wlan.c
+++ b/drivers/net/wireless/rndis_wlan.c
@@ -253,8 +253,8 @@ struct ndis_80211_pmkid_cand_list {
253struct ndis_80211_status_indication { 253struct ndis_80211_status_indication {
254 __le32 status_type; 254 __le32 status_type;
255 union { 255 union {
256 enum ndis_80211_media_stream_mode media_stream_mode; 256 __le32 media_stream_mode;
257 enum ndis_80211_radio_status radio_status; 257 __le32 radio_status;
258 struct ndis_80211_auth_request auth_request[0]; 258 struct ndis_80211_auth_request auth_request[0];
259 struct ndis_80211_pmkid_cand_list cand_list; 259 struct ndis_80211_pmkid_cand_list cand_list;
260 } u; 260 } u;
@@ -466,7 +466,7 @@ struct rndis_wlan_private {
466 u32 param_workaround_interval; 466 u32 param_workaround_interval;
467 467
468 /* hardware state */ 468 /* hardware state */
469 int radio_on; 469 bool radio_on;
470 int infra_mode; 470 int infra_mode;
471 bool connected; 471 bool connected;
472 u8 bssid[ETH_ALEN]; 472 u8 bssid[ETH_ALEN];
@@ -560,7 +560,6 @@ static struct rndis_wlan_private *get_rndis_wlan_priv(struct usbnet *dev)
560 return (struct rndis_wlan_private *)dev->driver_priv; 560 return (struct rndis_wlan_private *)dev->driver_priv;
561} 561}
562 562
563
564static u32 get_bcm4320_power_dbm(struct rndis_wlan_private *priv) 563static u32 get_bcm4320_power_dbm(struct rndis_wlan_private *priv)
565{ 564{
566 switch (priv->param_power_output) { 565 switch (priv->param_power_output) {
@@ -576,7 +575,6 @@ static u32 get_bcm4320_power_dbm(struct rndis_wlan_private *priv)
576 } 575 }
577} 576}
578 577
579
580static bool is_wpa_key(struct rndis_wlan_private *priv, int idx) 578static bool is_wpa_key(struct rndis_wlan_private *priv, int idx)
581{ 579{
582 int cipher = priv->encr_keys[idx].cipher; 580 int cipher = priv->encr_keys[idx].cipher;
@@ -585,7 +583,6 @@ static bool is_wpa_key(struct rndis_wlan_private *priv, int idx)
585 cipher == WLAN_CIPHER_SUITE_TKIP); 583 cipher == WLAN_CIPHER_SUITE_TKIP);
586} 584}
587 585
588
589static int rndis_cipher_to_alg(u32 cipher) 586static int rndis_cipher_to_alg(u32 cipher)
590{ 587{
591 switch (cipher) { 588 switch (cipher) {
@@ -613,7 +610,6 @@ static int rndis_akm_suite_to_key_mgmt(u32 akm_suite)
613 } 610 }
614} 611}
615 612
616
617#ifdef DEBUG 613#ifdef DEBUG
618static const char *oid_to_string(__le32 oid) 614static const char *oid_to_string(__le32 oid)
619{ 615{
@@ -675,7 +671,6 @@ static const char *oid_to_string(__le32 oid)
675} 671}
676#endif 672#endif
677 673
678
679/* translate error code */ 674/* translate error code */
680static int rndis_error_status(__le32 rndis_status) 675static int rndis_error_status(__le32 rndis_status)
681{ 676{
@@ -699,7 +694,6 @@ static int rndis_error_status(__le32 rndis_status)
699 return ret; 694 return ret;
700} 695}
701 696
702
703static int rndis_query_oid(struct usbnet *dev, __le32 oid, void *data, int *len) 697static int rndis_query_oid(struct usbnet *dev, __le32 oid, void *data, int *len)
704{ 698{
705 struct rndis_wlan_private *priv = get_rndis_wlan_priv(dev); 699 struct rndis_wlan_private *priv = get_rndis_wlan_priv(dev);
@@ -758,7 +752,6 @@ static int rndis_query_oid(struct usbnet *dev, __le32 oid, void *data, int *len)
758 return ret; 752 return ret;
759} 753}
760 754
761
762static int rndis_set_oid(struct usbnet *dev, __le32 oid, void *data, int len) 755static int rndis_set_oid(struct usbnet *dev, __le32 oid, void *data, int len)
763{ 756{
764 struct rndis_wlan_private *priv = get_rndis_wlan_priv(dev); 757 struct rndis_wlan_private *priv = get_rndis_wlan_priv(dev);
@@ -817,7 +810,6 @@ static int rndis_set_oid(struct usbnet *dev, __le32 oid, void *data, int len)
817 return ret; 810 return ret;
818} 811}
819 812
820
821static int rndis_reset(struct usbnet *usbdev) 813static int rndis_reset(struct usbnet *usbdev)
822{ 814{
823 struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); 815 struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
@@ -840,7 +832,6 @@ static int rndis_reset(struct usbnet *usbdev)
840 return 0; 832 return 0;
841} 833}
842 834
843
844/* 835/*
845 * Specs say that we can only set config parameters only soon after device 836 * Specs say that we can only set config parameters only soon after device
846 * initialization. 837 * initialization.
@@ -927,16 +918,9 @@ static int rndis_set_config_parameter(struct usbnet *dev, char *param,
927static int rndis_set_config_parameter_str(struct usbnet *dev, 918static int rndis_set_config_parameter_str(struct usbnet *dev,
928 char *param, char *value) 919 char *param, char *value)
929{ 920{
930 return(rndis_set_config_parameter(dev, param, 2, value)); 921 return rndis_set_config_parameter(dev, param, 2, value);
931} 922}
932 923
933/*static int rndis_set_config_parameter_u32(struct usbnet *dev,
934 char *param, u32 value)
935{
936 return(rndis_set_config_parameter(dev, param, 0, &value));
937}*/
938
939
940/* 924/*
941 * data conversion functions 925 * data conversion functions
942 */ 926 */
@@ -946,7 +930,6 @@ static int level_to_qual(int level)
946 return qual >= 0 ? (qual <= 100 ? qual : 100) : 0; 930 return qual >= 0 ? (qual <= 100 ? qual : 100) : 0;
947} 931}
948 932
949
950/* 933/*
951 * common functions 934 * common functions
952 */ 935 */
@@ -966,8 +949,8 @@ static int set_essid(struct usbnet *usbdev, struct ndis_80211_ssid *ssid)
966 } 949 }
967 if (ret == 0) { 950 if (ret == 0) {
968 memcpy(&priv->essid, ssid, sizeof(priv->essid)); 951 memcpy(&priv->essid, ssid, sizeof(priv->essid));
969 priv->radio_on = 1; 952 priv->radio_on = true;
970 devdbg(usbdev, "set_essid: radio_on = 1"); 953 devdbg(usbdev, "set_essid: radio_on = true");
971 } 954 }
972 955
973 return ret; 956 return ret;
@@ -1027,8 +1010,7 @@ static bool is_associated(struct usbnet *usbdev)
1027 return (ret == 0 && !is_zero_ether_addr(bssid)); 1010 return (ret == 0 && !is_zero_ether_addr(bssid));
1028} 1011}
1029 1012
1030 1013static int disassociate(struct usbnet *usbdev, bool reset_ssid)
1031static int disassociate(struct usbnet *usbdev, int reset_ssid)
1032{ 1014{
1033 struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); 1015 struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
1034 struct ndis_80211_ssid ssid; 1016 struct ndis_80211_ssid ssid;
@@ -1037,8 +1019,8 @@ static int disassociate(struct usbnet *usbdev, int reset_ssid)
1037 if (priv->radio_on) { 1019 if (priv->radio_on) {
1038 ret = rndis_set_oid(usbdev, OID_802_11_DISASSOCIATE, NULL, 0); 1020 ret = rndis_set_oid(usbdev, OID_802_11_DISASSOCIATE, NULL, 0);
1039 if (ret == 0) { 1021 if (ret == 0) {
1040 priv->radio_on = 0; 1022 priv->radio_on = false;
1041 devdbg(usbdev, "disassociate: radio_on = 0"); 1023 devdbg(usbdev, "disassociate: radio_on = false");
1042 1024
1043 if (reset_ssid) 1025 if (reset_ssid)
1044 msleep(100); 1026 msleep(100);
@@ -1064,7 +1046,6 @@ static int disassociate(struct usbnet *usbdev, int reset_ssid)
1064 return ret; 1046 return ret;
1065} 1047}
1066 1048
1067
1068static int set_auth_mode(struct usbnet *usbdev, u32 wpa_version, 1049static int set_auth_mode(struct usbnet *usbdev, u32 wpa_version,
1069 enum nl80211_auth_type auth_type, int keymgmt) 1050 enum nl80211_auth_type auth_type, int keymgmt)
1070{ 1051{
@@ -1109,7 +1090,6 @@ static int set_auth_mode(struct usbnet *usbdev, u32 wpa_version,
1109 return 0; 1090 return 0;
1110} 1091}
1111 1092
1112
1113static int set_priv_filter(struct usbnet *usbdev) 1093static int set_priv_filter(struct usbnet *usbdev)
1114{ 1094{
1115 struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); 1095 struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
@@ -1127,7 +1107,6 @@ static int set_priv_filter(struct usbnet *usbdev)
1127 sizeof(tmp)); 1107 sizeof(tmp));
1128} 1108}
1129 1109
1130
1131static int set_encr_mode(struct usbnet *usbdev, int pairwise, int groupwise) 1110static int set_encr_mode(struct usbnet *usbdev, int pairwise, int groupwise)
1132{ 1111{
1133 struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); 1112 struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
@@ -1163,7 +1142,6 @@ static int set_encr_mode(struct usbnet *usbdev, int pairwise, int groupwise)
1163 return 0; 1142 return 0;
1164} 1143}
1165 1144
1166
1167static int set_infra_mode(struct usbnet *usbdev, int mode) 1145static int set_infra_mode(struct usbnet *usbdev, int mode)
1168{ 1146{
1169 struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); 1147 struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
@@ -1189,7 +1167,6 @@ static int set_infra_mode(struct usbnet *usbdev, int mode)
1189 return 0; 1167 return 0;
1190} 1168}
1191 1169
1192
1193static int set_rts_threshold(struct usbnet *usbdev, u32 rts_threshold) 1170static int set_rts_threshold(struct usbnet *usbdev, u32 rts_threshold)
1194{ 1171{
1195 __le32 tmp; 1172 __le32 tmp;
@@ -1204,7 +1181,6 @@ static int set_rts_threshold(struct usbnet *usbdev, u32 rts_threshold)
1204 sizeof(tmp)); 1181 sizeof(tmp));
1205} 1182}
1206 1183
1207
1208static int set_frag_threshold(struct usbnet *usbdev, u32 frag_threshold) 1184static int set_frag_threshold(struct usbnet *usbdev, u32 frag_threshold)
1209{ 1185{
1210 __le32 tmp; 1186 __le32 tmp;
@@ -1219,7 +1195,6 @@ static int set_frag_threshold(struct usbnet *usbdev, u32 frag_threshold)
1219 sizeof(tmp)); 1195 sizeof(tmp));
1220} 1196}
1221 1197
1222
1223static void set_default_iw_params(struct usbnet *usbdev) 1198static void set_default_iw_params(struct usbnet *usbdev)
1224{ 1199{
1225 set_infra_mode(usbdev, NDIS_80211_INFRA_INFRA); 1200 set_infra_mode(usbdev, NDIS_80211_INFRA_INFRA);
@@ -1229,17 +1204,15 @@ static void set_default_iw_params(struct usbnet *usbdev)
1229 set_encr_mode(usbdev, RNDIS_WLAN_ALG_NONE, RNDIS_WLAN_ALG_NONE); 1204 set_encr_mode(usbdev, RNDIS_WLAN_ALG_NONE, RNDIS_WLAN_ALG_NONE);
1230} 1205}
1231 1206
1232
1233static int deauthenticate(struct usbnet *usbdev) 1207static int deauthenticate(struct usbnet *usbdev)
1234{ 1208{
1235 int ret; 1209 int ret;
1236 1210
1237 ret = disassociate(usbdev, 1); 1211 ret = disassociate(usbdev, true);
1238 set_default_iw_params(usbdev); 1212 set_default_iw_params(usbdev);
1239 return ret; 1213 return ret;
1240} 1214}
1241 1215
1242
1243static int set_channel(struct usbnet *usbdev, int channel) 1216static int set_channel(struct usbnet *usbdev, int channel)
1244{ 1217{
1245 struct ndis_80211_conf config; 1218 struct ndis_80211_conf config;
@@ -1270,7 +1243,6 @@ static int set_channel(struct usbnet *usbdev, int channel)
1270 return ret; 1243 return ret;
1271} 1244}
1272 1245
1273
1274/* index must be 0 - N, as per NDIS */ 1246/* index must be 0 - N, as per NDIS */
1275static int add_wep_key(struct usbnet *usbdev, const u8 *key, int key_len, 1247static int add_wep_key(struct usbnet *usbdev, const u8 *key, int key_len,
1276 int index) 1248 int index)
@@ -1322,10 +1294,9 @@ static int add_wep_key(struct usbnet *usbdev, const u8 *key, int key_len,
1322 return 0; 1294 return 0;
1323} 1295}
1324 1296
1325
1326static int add_wpa_key(struct usbnet *usbdev, const u8 *key, int key_len, 1297static int add_wpa_key(struct usbnet *usbdev, const u8 *key, int key_len,
1327 int index, const u8 *addr, const u8 *rx_seq, 1298 int index, const u8 *addr, const u8 *rx_seq,
1328 int seq_len, u32 cipher, int flags) 1299 int seq_len, u32 cipher, __le32 flags)
1329{ 1300{
1330 struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); 1301 struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
1331 struct ndis_80211_key ndis_key; 1302 struct ndis_80211_key ndis_key;
@@ -1417,7 +1388,6 @@ static int add_wpa_key(struct usbnet *usbdev, const u8 *key, int key_len,
1417 return 0; 1388 return 0;
1418} 1389}
1419 1390
1420
1421static int restore_key(struct usbnet *usbdev, int key_idx) 1391static int restore_key(struct usbnet *usbdev, int key_idx)
1422{ 1392{
1423 struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); 1393 struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
@@ -1436,7 +1406,6 @@ static int restore_key(struct usbnet *usbdev, int key_idx)
1436 return add_wep_key(usbdev, key.material, key.len, key_idx); 1406 return add_wep_key(usbdev, key.material, key.len, key_idx);
1437} 1407}
1438 1408
1439
1440static void restore_keys(struct usbnet *usbdev) 1409static void restore_keys(struct usbnet *usbdev)
1441{ 1410{
1442 int i; 1411 int i;
@@ -1445,13 +1414,11 @@ static void restore_keys(struct usbnet *usbdev)
1445 restore_key(usbdev, i); 1414 restore_key(usbdev, i);
1446} 1415}
1447 1416
1448
1449static void clear_key(struct rndis_wlan_private *priv, int idx) 1417static void clear_key(struct rndis_wlan_private *priv, int idx)
1450{ 1418{
1451 memset(&priv->encr_keys[idx], 0, sizeof(priv->encr_keys[idx])); 1419 memset(&priv->encr_keys[idx], 0, sizeof(priv->encr_keys[idx]));
1452} 1420}
1453 1421
1454
1455/* remove_key is for both wep and wpa */ 1422/* remove_key is for both wep and wpa */
1456static int remove_key(struct usbnet *usbdev, int index, const u8 *bssid) 1423static int remove_key(struct usbnet *usbdev, int index, const u8 *bssid)
1457{ 1424{
@@ -1508,7 +1475,6 @@ static int remove_key(struct usbnet *usbdev, int index, const u8 *bssid)
1508 return 0; 1475 return 0;
1509} 1476}
1510 1477
1511
1512static void set_multicast_list(struct usbnet *usbdev) 1478static void set_multicast_list(struct usbnet *usbdev)
1513{ 1479{
1514 struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); 1480 struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
@@ -1568,7 +1534,6 @@ static void set_multicast_list(struct usbnet *usbdev)
1568 le32_to_cpu(filter), ret); 1534 le32_to_cpu(filter), ret);
1569} 1535}
1570 1536
1571
1572/* 1537/*
1573 * cfg80211 ops 1538 * cfg80211 ops
1574 */ 1539 */
@@ -1597,7 +1562,6 @@ static int rndis_change_virtual_intf(struct wiphy *wiphy,
1597 return set_infra_mode(usbdev, mode); 1562 return set_infra_mode(usbdev, mode);
1598} 1563}
1599 1564
1600
1601static int rndis_set_wiphy_params(struct wiphy *wiphy, u32 changed) 1565static int rndis_set_wiphy_params(struct wiphy *wiphy, u32 changed)
1602{ 1566{
1603 struct rndis_wlan_private *priv = wiphy_priv(wiphy); 1567 struct rndis_wlan_private *priv = wiphy_priv(wiphy);
@@ -1619,7 +1583,6 @@ static int rndis_set_wiphy_params(struct wiphy *wiphy, u32 changed)
1619 return 0; 1583 return 0;
1620} 1584}
1621 1585
1622
1623static int rndis_set_tx_power(struct wiphy *wiphy, enum tx_power_setting type, 1586static int rndis_set_tx_power(struct wiphy *wiphy, enum tx_power_setting type,
1624 int dbm) 1587 int dbm)
1625{ 1588{
@@ -1634,7 +1597,7 @@ static int rndis_set_tx_power(struct wiphy *wiphy, enum tx_power_setting type,
1634 */ 1597 */
1635 if (type == TX_POWER_AUTOMATIC || dbm == get_bcm4320_power_dbm(priv)) { 1598 if (type == TX_POWER_AUTOMATIC || dbm == get_bcm4320_power_dbm(priv)) {
1636 if (!priv->radio_on) 1599 if (!priv->radio_on)
1637 disassociate(usbdev, 1); /* turn on radio */ 1600 disassociate(usbdev, true); /* turn on radio */
1638 1601
1639 return 0; 1602 return 0;
1640 } 1603 }
@@ -1642,7 +1605,6 @@ static int rndis_set_tx_power(struct wiphy *wiphy, enum tx_power_setting type,
1642 return -ENOTSUPP; 1605 return -ENOTSUPP;
1643} 1606}
1644 1607
1645
1646static int rndis_get_tx_power(struct wiphy *wiphy, int *dbm) 1608static int rndis_get_tx_power(struct wiphy *wiphy, int *dbm)
1647{ 1609{
1648 struct rndis_wlan_private *priv = wiphy_priv(wiphy); 1610 struct rndis_wlan_private *priv = wiphy_priv(wiphy);
@@ -1655,7 +1617,6 @@ static int rndis_get_tx_power(struct wiphy *wiphy, int *dbm)
1655 return 0; 1617 return 0;
1656} 1618}
1657 1619
1658
1659#define SCAN_DELAY_JIFFIES (6 * HZ) 1620#define SCAN_DELAY_JIFFIES (6 * HZ)
1660static int rndis_scan(struct wiphy *wiphy, struct net_device *dev, 1621static int rndis_scan(struct wiphy *wiphy, struct net_device *dev,
1661 struct cfg80211_scan_request *request) 1622 struct cfg80211_scan_request *request)
@@ -1692,7 +1653,6 @@ static int rndis_scan(struct wiphy *wiphy, struct net_device *dev,
1692 return ret; 1653 return ret;
1693} 1654}
1694 1655
1695
1696static struct cfg80211_bss *rndis_bss_info_update(struct usbnet *usbdev, 1656static struct cfg80211_bss *rndis_bss_info_update(struct usbnet *usbdev,
1697 struct ndis_80211_bssid_ex *bssid) 1657 struct ndis_80211_bssid_ex *bssid)
1698{ 1658{
@@ -1741,7 +1701,6 @@ static struct cfg80211_bss *rndis_bss_info_update(struct usbnet *usbdev,
1741 GFP_KERNEL); 1701 GFP_KERNEL);
1742} 1702}
1743 1703
1744
1745static int rndis_check_bssid_list(struct usbnet *usbdev) 1704static int rndis_check_bssid_list(struct usbnet *usbdev)
1746{ 1705{
1747 void *buf = NULL; 1706 void *buf = NULL;
@@ -1790,7 +1749,6 @@ out:
1790 return ret; 1749 return ret;
1791} 1750}
1792 1751
1793
1794static void rndis_get_scan_results(struct work_struct *work) 1752static void rndis_get_scan_results(struct work_struct *work)
1795{ 1753{
1796 struct rndis_wlan_private *priv = 1754 struct rndis_wlan_private *priv =
@@ -1923,7 +1881,7 @@ static int rndis_connect(struct wiphy *wiphy, struct net_device *dev,
1923 return ret; 1881 return ret;
1924 1882
1925err_turn_radio_on: 1883err_turn_radio_on:
1926 disassociate(usbdev, 1); 1884 disassociate(usbdev, true);
1927 1885
1928 return ret; 1886 return ret;
1929} 1887}
@@ -2031,7 +1989,7 @@ static int rndis_join_ibss(struct wiphy *wiphy, struct net_device *dev,
2031 return ret; 1989 return ret;
2032 1990
2033err_turn_radio_on: 1991err_turn_radio_on:
2034 disassociate(usbdev, 1); 1992 disassociate(usbdev, true);
2035 1993
2036 return ret; 1994 return ret;
2037} 1995}
@@ -2065,7 +2023,7 @@ static int rndis_add_key(struct wiphy *wiphy, struct net_device *netdev,
2065{ 2023{
2066 struct rndis_wlan_private *priv = wiphy_priv(wiphy); 2024 struct rndis_wlan_private *priv = wiphy_priv(wiphy);
2067 struct usbnet *usbdev = priv->usbdev; 2025 struct usbnet *usbdev = priv->usbdev;
2068 int flags; 2026 __le32 flags;
2069 2027
2070 devdbg(usbdev, "rndis_add_key(%i, %pM, %08x)", key_index, mac_addr, 2028 devdbg(usbdev, "rndis_add_key(%i, %pM, %08x)", key_index, mac_addr,
2071 params->cipher); 2029 params->cipher);
@@ -2175,7 +2133,9 @@ static int rndis_dump_station(struct wiphy *wiphy, struct net_device *dev,
2175 return 0; 2133 return 0;
2176} 2134}
2177 2135
2178 2136/*
2137 * workers, indication handlers, device poller
2138 */
2179static void rndis_wlan_do_link_up_work(struct usbnet *usbdev) 2139static void rndis_wlan_do_link_up_work(struct usbnet *usbdev)
2180{ 2140{
2181 struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); 2141 struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
@@ -2293,7 +2253,6 @@ static void rndis_wlan_set_multicast_list(struct net_device *dev)
2293 queue_work(priv->workqueue, &priv->work); 2253 queue_work(priv->workqueue, &priv->work);
2294} 2254}
2295 2255
2296
2297static void rndis_wlan_auth_indication(struct usbnet *usbdev, 2256static void rndis_wlan_auth_indication(struct usbnet *usbdev,
2298 struct ndis_80211_status_indication *indication, 2257 struct ndis_80211_status_indication *indication,
2299 int len) 2258 int len)
@@ -2476,7 +2435,6 @@ static void rndis_wlan_media_specific_indication(struct usbnet *usbdev,
2476 } 2435 }
2477} 2436}
2478 2437
2479
2480static void rndis_wlan_indication(struct usbnet *usbdev, void *ind, int buflen) 2438static void rndis_wlan_indication(struct usbnet *usbdev, void *ind, int buflen)
2481{ 2439{
2482 struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); 2440 struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
@@ -2523,7 +2481,6 @@ static void rndis_wlan_indication(struct usbnet *usbdev, void *ind, int buflen)
2523 } 2481 }
2524} 2482}
2525 2483
2526
2527static int rndis_wlan_get_caps(struct usbnet *usbdev) 2484static int rndis_wlan_get_caps(struct usbnet *usbdev)
2528{ 2485{
2529 struct { 2486 struct {
@@ -2560,7 +2517,6 @@ static int rndis_wlan_get_caps(struct usbnet *usbdev)
2560 return retval; 2517 return retval;
2561} 2518}
2562 2519
2563
2564#define DEVICE_POLLER_JIFFIES (HZ) 2520#define DEVICE_POLLER_JIFFIES (HZ)
2565static void rndis_device_poller(struct work_struct *work) 2521static void rndis_device_poller(struct work_struct *work)
2566{ 2522{
@@ -2632,7 +2588,9 @@ end:
2632 update_jiffies); 2588 update_jiffies);
2633} 2589}
2634 2590
2635 2591/*
2592 * driver/device initialization
2593 */
2636static int bcm4320a_early_init(struct usbnet *usbdev) 2594static int bcm4320a_early_init(struct usbnet *usbdev)
2637{ 2595{
2638 /* bcm4320a doesn't handle configuration parameters well. Try 2596 /* bcm4320a doesn't handle configuration parameters well. Try
@@ -2642,7 +2600,6 @@ static int bcm4320a_early_init(struct usbnet *usbdev)
2642 return 0; 2600 return 0;
2643} 2601}
2644 2602
2645
2646static int bcm4320b_early_init(struct usbnet *usbdev) 2603static int bcm4320b_early_init(struct usbnet *usbdev)
2647{ 2604{
2648 struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); 2605 struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
@@ -2721,7 +2678,6 @@ static const struct net_device_ops rndis_wlan_netdev_ops = {
2721 .ndo_set_multicast_list = rndis_wlan_set_multicast_list, 2678 .ndo_set_multicast_list = rndis_wlan_set_multicast_list,
2722}; 2679};
2723 2680
2724
2725static int rndis_wlan_bind(struct usbnet *usbdev, struct usb_interface *intf) 2681static int rndis_wlan_bind(struct usbnet *usbdev, struct usb_interface *intf)
2726{ 2682{
2727 struct wiphy *wiphy; 2683 struct wiphy *wiphy;
@@ -2823,8 +2779,8 @@ static int rndis_wlan_bind(struct usbnet *usbdev, struct usb_interface *intf)
2823 WIPHY_PARAM_FRAG_THRESHOLD | WIPHY_PARAM_RTS_THRESHOLD); 2779 WIPHY_PARAM_FRAG_THRESHOLD | WIPHY_PARAM_RTS_THRESHOLD);
2824 2780
2825 /* turn radio on */ 2781 /* turn radio on */
2826 priv->radio_on = 1; 2782 priv->radio_on = true;
2827 disassociate(usbdev, 1); 2783 disassociate(usbdev, true);
2828 netif_carrier_off(usbdev->net); 2784 netif_carrier_off(usbdev->net);
2829 2785
2830 return 0; 2786 return 0;
@@ -2840,13 +2796,12 @@ fail:
2840 return retval; 2796 return retval;
2841} 2797}
2842 2798
2843
2844static void rndis_wlan_unbind(struct usbnet *usbdev, struct usb_interface *intf) 2799static void rndis_wlan_unbind(struct usbnet *usbdev, struct usb_interface *intf)
2845{ 2800{
2846 struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); 2801 struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
2847 2802
2848 /* turn radio off */ 2803 /* turn radio off */
2849 disassociate(usbdev, 0); 2804 disassociate(usbdev, false);
2850 2805
2851 cancel_delayed_work_sync(&priv->dev_poller_work); 2806 cancel_delayed_work_sync(&priv->dev_poller_work);
2852 cancel_delayed_work_sync(&priv->scan_work); 2807 cancel_delayed_work_sync(&priv->scan_work);
@@ -2863,7 +2818,6 @@ static void rndis_wlan_unbind(struct usbnet *usbdev, struct usb_interface *intf)
2863 wiphy_free(priv->wdev.wiphy); 2818 wiphy_free(priv->wdev.wiphy);
2864} 2819}
2865 2820
2866
2867static int rndis_wlan_reset(struct usbnet *usbdev) 2821static int rndis_wlan_reset(struct usbnet *usbdev)
2868{ 2822{
2869 struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); 2823 struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
@@ -2885,7 +2839,6 @@ static int rndis_wlan_reset(struct usbnet *usbdev)
2885 return deauthenticate(usbdev); 2839 return deauthenticate(usbdev);
2886} 2840}
2887 2841
2888
2889static int rndis_wlan_stop(struct usbnet *usbdev) 2842static int rndis_wlan_stop(struct usbnet *usbdev)
2890{ 2843{
2891 struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); 2844 struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
@@ -2894,7 +2847,7 @@ static int rndis_wlan_stop(struct usbnet *usbdev)
2894 2847
2895 devdbg(usbdev, "rndis_wlan_stop"); 2848 devdbg(usbdev, "rndis_wlan_stop");
2896 2849
2897 retval = disassociate(usbdev, 0); 2850 retval = disassociate(usbdev, false);
2898 2851
2899 priv->work_pending = 0; 2852 priv->work_pending = 0;
2900 cancel_delayed_work_sync(&priv->dev_poller_work); 2853 cancel_delayed_work_sync(&priv->dev_poller_work);
@@ -2916,7 +2869,6 @@ static int rndis_wlan_stop(struct usbnet *usbdev)
2916 return retval; 2869 return retval;
2917} 2870}
2918 2871
2919
2920static const struct driver_info bcm4320b_info = { 2872static const struct driver_info bcm4320b_info = {
2921 .description = "Wireless RNDIS device, BCM4320b based", 2873 .description = "Wireless RNDIS device, BCM4320b based",
2922 .flags = FLAG_WLAN | FLAG_FRAMING_RN | FLAG_NO_SETINT | 2874 .flags = FLAG_WLAN | FLAG_FRAMING_RN | FLAG_NO_SETINT |
diff --git a/drivers/net/wireless/rt2x00/rt2x00crypto.c b/drivers/net/wireless/rt2x00/rt2x00crypto.c
index 30fbd3bbe08b..de36837dcf86 100644
--- a/drivers/net/wireless/rt2x00/rt2x00crypto.c
+++ b/drivers/net/wireless/rt2x00/rt2x00crypto.c
@@ -154,7 +154,7 @@ void rt2x00crypto_tx_insert_iv(struct sk_buff *skb, unsigned int header_length)
154 skbdesc->flags &= ~SKBDESC_IV_STRIPPED; 154 skbdesc->flags &= ~SKBDESC_IV_STRIPPED;
155} 155}
156 156
157void rt2x00crypto_rx_insert_iv(struct sk_buff *skb, bool l2pad, 157void rt2x00crypto_rx_insert_iv(struct sk_buff *skb,
158 unsigned int header_length, 158 unsigned int header_length,
159 struct rxdone_entry_desc *rxdesc) 159 struct rxdone_entry_desc *rxdesc)
160{ 160{
@@ -199,7 +199,7 @@ void rt2x00crypto_rx_insert_iv(struct sk_buff *skb, bool l2pad,
199 * move the header more then iv_len since we must 199 * move the header more then iv_len since we must
200 * make room for the payload move as well. 200 * make room for the payload move as well.
201 */ 201 */
202 if (l2pad) { 202 if (rxdesc->dev_flags & RXDONE_L2PAD) {
203 skb_push(skb, iv_len - align); 203 skb_push(skb, iv_len - align);
204 skb_put(skb, icv_len); 204 skb_put(skb, icv_len);
205 205
@@ -230,7 +230,7 @@ void rt2x00crypto_rx_insert_iv(struct sk_buff *skb, bool l2pad,
230 * Move payload for alignment purposes. Note that 230 * Move payload for alignment purposes. Note that
231 * this is only needed when no l2 padding is present. 231 * this is only needed when no l2 padding is present.
232 */ 232 */
233 if (!l2pad) { 233 if (!(rxdesc->dev_flags & RXDONE_L2PAD)) {
234 memmove(skb->data + transfer, 234 memmove(skb->data + transfer,
235 skb->data + transfer + align, 235 skb->data + transfer + align,
236 payload_len); 236 payload_len);
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c
index 3f8c70ebe9ad..71761b343839 100644
--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
@@ -206,6 +206,7 @@ void rt2x00lib_txdone(struct queue_entry *entry,
206 unsigned int header_length = ieee80211_get_hdrlen_from_skb(entry->skb); 206 unsigned int header_length = ieee80211_get_hdrlen_from_skb(entry->skb);
207 u8 rate_idx, rate_flags, retry_rates; 207 u8 rate_idx, rate_flags, retry_rates;
208 unsigned int i; 208 unsigned int i;
209 bool success;
209 210
210 /* 211 /*
211 * Unmap the skb. 212 * Unmap the skb.
@@ -216,7 +217,7 @@ void rt2x00lib_txdone(struct queue_entry *entry,
216 * Remove L2 padding which was added during 217 * Remove L2 padding which was added during
217 */ 218 */
218 if (test_bit(DRIVER_REQUIRE_L2PAD, &rt2x00dev->flags)) 219 if (test_bit(DRIVER_REQUIRE_L2PAD, &rt2x00dev->flags))
219 rt2x00queue_payload_align(entry->skb, true, header_length); 220 rt2x00queue_remove_l2pad(entry->skb, header_length);
220 221
221 /* 222 /*
222 * If the IV/EIV data was stripped from the frame before it was 223 * If the IV/EIV data was stripped from the frame before it was
@@ -234,13 +235,18 @@ void rt2x00lib_txdone(struct queue_entry *entry,
234 rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_TXDONE, entry->skb); 235 rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_TXDONE, entry->skb);
235 236
236 /* 237 /*
237 * Update TX statistics. 238 * Determine if the frame has been successfully transmitted.
238 */ 239 */
239 rt2x00dev->link.qual.tx_success += 240 success =
240 test_bit(TXDONE_SUCCESS, &txdesc->flags) || 241 test_bit(TXDONE_SUCCESS, &txdesc->flags) ||
241 test_bit(TXDONE_UNKNOWN, &txdesc->flags); 242 test_bit(TXDONE_UNKNOWN, &txdesc->flags) ||
242 rt2x00dev->link.qual.tx_failed += 243 test_bit(TXDONE_FALLBACK, &txdesc->flags);
243 test_bit(TXDONE_FAILURE, &txdesc->flags); 244
245 /*
246 * Update TX statistics.
247 */
248 rt2x00dev->link.qual.tx_success += success;
249 rt2x00dev->link.qual.tx_failed += !success;
244 250
245 rate_idx = skbdesc->tx_rate_idx; 251 rate_idx = skbdesc->tx_rate_idx;
246 rate_flags = skbdesc->tx_rate_flags; 252 rate_flags = skbdesc->tx_rate_flags;
@@ -263,22 +269,20 @@ void rt2x00lib_txdone(struct queue_entry *entry,
263 tx_info->status.rates[i].flags = rate_flags; 269 tx_info->status.rates[i].flags = rate_flags;
264 tx_info->status.rates[i].count = 1; 270 tx_info->status.rates[i].count = 1;
265 } 271 }
266 if (i < (IEEE80211_TX_MAX_RATES -1)) 272 if (i < (IEEE80211_TX_MAX_RATES - 1))
267 tx_info->status.rates[i].idx = -1; /* terminate */ 273 tx_info->status.rates[i].idx = -1; /* terminate */
268 274
269 if (!(tx_info->flags & IEEE80211_TX_CTL_NO_ACK)) { 275 if (!(tx_info->flags & IEEE80211_TX_CTL_NO_ACK)) {
270 if (test_bit(TXDONE_SUCCESS, &txdesc->flags) || 276 if (success)
271 test_bit(TXDONE_UNKNOWN, &txdesc->flags))
272 tx_info->flags |= IEEE80211_TX_STAT_ACK; 277 tx_info->flags |= IEEE80211_TX_STAT_ACK;
273 else if (test_bit(TXDONE_FAILURE, &txdesc->flags)) 278 else
274 rt2x00dev->low_level_stats.dot11ACKFailureCount++; 279 rt2x00dev->low_level_stats.dot11ACKFailureCount++;
275 } 280 }
276 281
277 if (rate_flags & IEEE80211_TX_RC_USE_RTS_CTS) { 282 if (rate_flags & IEEE80211_TX_RC_USE_RTS_CTS) {
278 if (test_bit(TXDONE_SUCCESS, &txdesc->flags) || 283 if (success)
279 test_bit(TXDONE_UNKNOWN, &txdesc->flags))
280 rt2x00dev->low_level_stats.dot11RTSSuccessCount++; 284 rt2x00dev->low_level_stats.dot11RTSSuccessCount++;
281 else if (test_bit(TXDONE_FAILURE, &txdesc->flags)) 285 else
282 rt2x00dev->low_level_stats.dot11RTSFailureCount++; 286 rt2x00dev->low_level_stats.dot11RTSFailureCount++;
283 } 287 }
284 288
@@ -360,7 +364,6 @@ void rt2x00lib_rxdone(struct rt2x00_dev *rt2x00dev,
360 struct sk_buff *skb; 364 struct sk_buff *skb;
361 struct ieee80211_rx_status *rx_status = &rt2x00dev->rx_status; 365 struct ieee80211_rx_status *rx_status = &rt2x00dev->rx_status;
362 unsigned int header_length; 366 unsigned int header_length;
363 bool l2pad;
364 int rate_idx; 367 int rate_idx;
365 /* 368 /*
366 * Allocate a new sk_buffer. If no new buffer available, drop the 369 * Allocate a new sk_buffer. If no new buffer available, drop the
@@ -389,7 +392,6 @@ void rt2x00lib_rxdone(struct rt2x00_dev *rt2x00dev,
389 * aligned on a 4 byte boundary. 392 * aligned on a 4 byte boundary.
390 */ 393 */
391 header_length = ieee80211_get_hdrlen_from_skb(entry->skb); 394 header_length = ieee80211_get_hdrlen_from_skb(entry->skb);
392 l2pad = !!(rxdesc.dev_flags & RXDONE_L2PAD);
393 395
394 /* 396 /*
395 * Hardware might have stripped the IV/EIV/ICV data, 397 * Hardware might have stripped the IV/EIV/ICV data,
@@ -399,10 +401,12 @@ void rt2x00lib_rxdone(struct rt2x00_dev *rt2x00dev,
399 */ 401 */
400 if ((rxdesc.dev_flags & RXDONE_CRYPTO_IV) && 402 if ((rxdesc.dev_flags & RXDONE_CRYPTO_IV) &&
401 (rxdesc.flags & RX_FLAG_IV_STRIPPED)) 403 (rxdesc.flags & RX_FLAG_IV_STRIPPED))
402 rt2x00crypto_rx_insert_iv(entry->skb, l2pad, header_length, 404 rt2x00crypto_rx_insert_iv(entry->skb, header_length,
403 &rxdesc); 405 &rxdesc);
406 else if (rxdesc.dev_flags & RXDONE_L2PAD)
407 rt2x00queue_remove_l2pad(entry->skb, header_length);
404 else 408 else
405 rt2x00queue_payload_align(entry->skb, l2pad, header_length); 409 rt2x00queue_align_payload(entry->skb, header_length);
406 410
407 /* 411 /*
408 * Check if the frame was received using HT. In that case, 412 * Check if the frame was received using HT. In that case,
diff --git a/drivers/net/wireless/rt2x00/rt2x00lib.h b/drivers/net/wireless/rt2x00/rt2x00lib.h
index eeb2881e818e..5462cb5ad994 100644
--- a/drivers/net/wireless/rt2x00/rt2x00lib.h
+++ b/drivers/net/wireless/rt2x00/rt2x00lib.h
@@ -120,21 +120,42 @@ void rt2x00queue_unmap_skb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb);
120void rt2x00queue_free_skb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb); 120void rt2x00queue_free_skb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb);
121 121
122/** 122/**
123 * rt2x00queue_payload_align - Align 802.11 payload to 4-byte boundary 123 * rt2x00queue_align_frame - Align 802.11 frame to 4-byte boundary
124 * @skb: The skb to align
125 *
126 * Align the start of the 802.11 frame to a 4-byte boundary, this could
127 * mean the payload is not aligned properly though.
128 */
129void rt2x00queue_align_frame(struct sk_buff *skb);
130
131/**
132 * rt2x00queue_align_payload - Align 802.11 payload to 4-byte boundary
133 * @skb: The skb to align
134 * @header_length: Length of 802.11 header
135 *
136 * Align the 802.11 payload to a 4-byte boundary, this could
137 * mean the header is not aligned properly though.
138 */
139void rt2x00queue_align_payload(struct sk_buff *skb, unsigned int header_length);
140
141/**
142 * rt2x00queue_insert_l2pad - Align 802.11 header & payload to 4-byte boundary
143 * @skb: The skb to align
144 * @header_length: Length of 802.11 header
145 *
146 * Apply L2 padding to align both header and payload to 4-byte boundary
147 */
148void rt2x00queue_insert_l2pad(struct sk_buff *skb, unsigned int header_length);
149
150/**
151 * rt2x00queue_insert_l2pad - Remove L2 padding from 802.11 frame
124 * @skb: The skb to align 152 * @skb: The skb to align
125 * @l2pad: Should L2 padding be used
126 * @header_length: Length of 802.11 header 153 * @header_length: Length of 802.11 header
127 * 154 *
128 * This function prepares the @skb to be send to the device or mac80211. 155 * Remove L2 padding used to align both header and payload to 4-byte boundary,
129 * If @l2pad is set to true padding will occur between the 802.11 header 156 * by removing the L2 padding the header will no longer be 4-byte aligned.
130 * and payload. Otherwise the padding will be done in front of the 802.11
131 * header.
132 * When @l2pad is set the function will check for the &SKBDESC_L2_PADDED
133 * flag in &skb_frame_desc. If that flag is set, the padding is removed
134 * and the flag cleared. Otherwise the padding is added and the flag is set.
135 */ 157 */
136void rt2x00queue_payload_align(struct sk_buff *skb, 158void rt2x00queue_remove_l2pad(struct sk_buff *skb, unsigned int header_length);
137 bool l2pad, unsigned int header_length);
138 159
139/** 160/**
140 * rt2x00queue_write_tx_frame - Write TX frame to hardware 161 * rt2x00queue_write_tx_frame - Write TX frame to hardware
@@ -324,7 +345,7 @@ void rt2x00crypto_tx_copy_iv(struct sk_buff *skb,
324void rt2x00crypto_tx_remove_iv(struct sk_buff *skb, 345void rt2x00crypto_tx_remove_iv(struct sk_buff *skb,
325 struct txentry_desc *txdesc); 346 struct txentry_desc *txdesc);
326void rt2x00crypto_tx_insert_iv(struct sk_buff *skb, unsigned int header_length); 347void rt2x00crypto_tx_insert_iv(struct sk_buff *skb, unsigned int header_length);
327void rt2x00crypto_rx_insert_iv(struct sk_buff *skb, bool l2pad, 348void rt2x00crypto_rx_insert_iv(struct sk_buff *skb,
328 unsigned int header_length, 349 unsigned int header_length,
329 struct rxdone_entry_desc *rxdesc); 350 struct rxdone_entry_desc *rxdesc);
330#else 351#else
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c
index 06af823efd83..577029efe320 100644
--- a/drivers/net/wireless/rt2x00/rt2x00queue.c
+++ b/drivers/net/wireless/rt2x00/rt2x00queue.c
@@ -148,35 +148,89 @@ void rt2x00queue_free_skb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb)
148 dev_kfree_skb_any(skb); 148 dev_kfree_skb_any(skb);
149} 149}
150 150
151void rt2x00queue_payload_align(struct sk_buff *skb, 151void rt2x00queue_align_frame(struct sk_buff *skb)
152 bool l2pad, unsigned int header_length)
153{ 152{
154 struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb);
155 unsigned int frame_length = skb->len; 153 unsigned int frame_length = skb->len;
156 unsigned int align = ALIGN_SIZE(skb, header_length); 154 unsigned int align = ALIGN_SIZE(skb, 0);
157 155
158 if (!align) 156 if (!align)
159 return; 157 return;
160 158
161 if (l2pad) { 159 skb_push(skb, align);
162 if (skbdesc->flags & SKBDESC_L2_PADDED) { 160 memmove(skb->data, skb->data + align, frame_length);
163 /* Remove L2 padding */ 161 skb_trim(skb, frame_length);
164 memmove(skb->data + align, skb->data, header_length); 162}
165 skb_pull(skb, align); 163
166 skbdesc->flags &= ~SKBDESC_L2_PADDED; 164void rt2x00queue_align_payload(struct sk_buff *skb, unsigned int header_lengt)
167 } else { 165{
168 /* Add L2 padding */ 166 unsigned int frame_length = skb->len;
169 skb_push(skb, align); 167 unsigned int align = ALIGN_SIZE(skb, header_lengt);
170 memmove(skb->data, skb->data + align, header_length); 168
171 skbdesc->flags |= SKBDESC_L2_PADDED; 169 if (!align)
172 } 170 return;
171
172 skb_push(skb, align);
173 memmove(skb->data, skb->data + align, frame_length);
174 skb_trim(skb, frame_length);
175}
176
177void rt2x00queue_insert_l2pad(struct sk_buff *skb, unsigned int header_length)
178{
179 struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb);
180 unsigned int frame_length = skb->len;
181 unsigned int header_align = ALIGN_SIZE(skb, 0);
182 unsigned int payload_align = ALIGN_SIZE(skb, header_length);
183 unsigned int l2pad = 4 - (payload_align - header_align);
184
185 if (header_align == payload_align) {
186 /*
187 * Both header and payload must be moved the same
188 * amount of bytes to align them properly. This means
189 * we don't use the L2 padding but just move the entire
190 * frame.
191 */
192 rt2x00queue_align_frame(skb);
193 } else if (!payload_align) {
194 /*
195 * Simple L2 padding, only the header needs to be moved,
196 * the payload is already properly aligned.
197 */
198 skb_push(skb, header_align);
199 memmove(skb->data, skb->data + header_align, frame_length);
200 skbdesc->flags |= SKBDESC_L2_PADDED;
173 } else { 201 } else {
174 /* Generic payload alignment to 4-byte boundary */ 202 /*
175 skb_push(skb, align); 203 *
176 memmove(skb->data, skb->data + align, frame_length); 204 * Complicated L2 padding, both header and payload need
205 * to be moved. By default we only move to the start
206 * of the buffer, so our header alignment needs to be
207 * increased if there is not enough room for the header
208 * to be moved.
209 */
210 if (payload_align > header_align)
211 header_align += 4;
212
213 skb_push(skb, header_align);
214 memmove(skb->data, skb->data + header_align, header_length);
215 memmove(skb->data + header_length + l2pad,
216 skb->data + header_length + l2pad + header_align,
217 frame_length - header_length);
218 skbdesc->flags |= SKBDESC_L2_PADDED;
177 } 219 }
178} 220}
179 221
222void rt2x00queue_remove_l2pad(struct sk_buff *skb, unsigned int header_length)
223{
224 struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb);
225 unsigned int l2pad = 4 - (header_length & 3);
226
227 if (!l2pad || (skbdesc->flags & SKBDESC_L2_PADDED))
228 return;
229
230 memmove(skb->data + l2pad, skb->data, header_length);
231 skb_pull(skb, l2pad);
232}
233
180static void rt2x00queue_create_tx_descriptor_seq(struct queue_entry *entry, 234static void rt2x00queue_create_tx_descriptor_seq(struct queue_entry *entry,
181 struct txentry_desc *txdesc) 235 struct txentry_desc *txdesc)
182{ 236{
@@ -456,18 +510,15 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb)
456 /* 510 /*
457 * When DMA allocation is required we should guarentee to the 511 * When DMA allocation is required we should guarentee to the
458 * driver that the DMA is aligned to a 4-byte boundary. 512 * driver that the DMA is aligned to a 4-byte boundary.
459 * Aligning the header to this boundary can be done by calling
460 * rt2x00queue_payload_align with the header length of 0.
461 * However some drivers require L2 padding to pad the payload 513 * However some drivers require L2 padding to pad the payload
462 * rather then the header. This could be a requirement for 514 * rather then the header. This could be a requirement for
463 * PCI and USB devices, while header alignment only is valid 515 * PCI and USB devices, while header alignment only is valid
464 * for PCI devices. 516 * for PCI devices.
465 */ 517 */
466 if (test_bit(DRIVER_REQUIRE_L2PAD, &queue->rt2x00dev->flags)) 518 if (test_bit(DRIVER_REQUIRE_L2PAD, &queue->rt2x00dev->flags))
467 rt2x00queue_payload_align(entry->skb, true, 519 rt2x00queue_insert_l2pad(entry->skb, txdesc.header_length);
468 txdesc.header_length);
469 else if (test_bit(DRIVER_REQUIRE_DMA, &queue->rt2x00dev->flags)) 520 else if (test_bit(DRIVER_REQUIRE_DMA, &queue->rt2x00dev->flags))
470 rt2x00queue_payload_align(entry->skb, false, 0); 521 rt2x00queue_align_frame(entry->skb);
471 522
472 /* 523 /*
473 * It could be possible that the queue was corrupted and this 524 * It could be possible that the queue was corrupted and this