aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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
-rw-r--r--include/linux/rfkill.h23
-rw-r--r--net/mac80211/Kconfig5
-rw-r--r--net/wireless/Kconfig4
-rw-r--r--net/wireless/scan.c2
36 files changed, 894 insertions, 540 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
diff --git a/include/linux/rfkill.h b/include/linux/rfkill.h
index 21ca51bf4dd2..3392c59d2706 100644
--- a/include/linux/rfkill.h
+++ b/include/linux/rfkill.h
@@ -6,20 +6,17 @@
6 * Copyright (C) 2007 Dmitry Torokhov 6 * Copyright (C) 2007 Dmitry Torokhov
7 * Copyright 2009 Johannes Berg <johannes@sipsolutions.net> 7 * Copyright 2009 Johannes Berg <johannes@sipsolutions.net>
8 * 8 *
9 * This program is free software; you can redistribute it and/or modify 9 * Permission to use, copy, modify, and/or distribute this software for any
10 * it under the terms of the GNU General Public License as published by 10 * purpose with or without fee is hereby granted, provided that the above
11 * the Free Software Foundation; either version 2 of the License, or 11 * copyright notice and this permission notice appear in all copies.
12 * (at your option) any later version.
13 * 12 *
14 * This program is distributed in the hope that it will be useful, 13 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
17 * GNU General Public License for more details. 16 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
18 * 17 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
19 * You should have received a copy of the GNU General Public License 18 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
20 * along with this program; if not, write to the 19 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
21 * Free Software Foundation, Inc.,
22 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 */ 20 */
24 21
25#include <linux/types.h> 22#include <linux/types.h>
diff --git a/net/mac80211/Kconfig b/net/mac80211/Kconfig
index 9db4ff836a3d..4d5543af3123 100644
--- a/net/mac80211/Kconfig
+++ b/net/mac80211/Kconfig
@@ -13,8 +13,7 @@ config MAC80211
13comment "CFG80211 needs to be enabled for MAC80211" 13comment "CFG80211 needs to be enabled for MAC80211"
14 depends on CFG80211=n 14 depends on CFG80211=n
15 15
16menu "Rate control algorithm selection" 16if MAC80211 != n
17 depends on MAC80211 != n
18 17
19config MAC80211_RC_PID 18config MAC80211_RC_PID
20 bool "PID controller based rate control algorithm" if EMBEDDED 19 bool "PID controller based rate control algorithm" if EMBEDDED
@@ -61,7 +60,7 @@ config MAC80211_RC_DEFAULT
61 default "pid" if MAC80211_RC_DEFAULT_PID 60 default "pid" if MAC80211_RC_DEFAULT_PID
62 default "" 61 default ""
63 62
64endmenu 63endif
65 64
66config MAC80211_MESH 65config MAC80211_MESH
67 bool "Enable mac80211 mesh networking (pre-802.11s) support" 66 bool "Enable mac80211 mesh networking (pre-802.11s) support"
diff --git a/net/wireless/Kconfig b/net/wireless/Kconfig
index aea7e6824af9..68c504fab122 100644
--- a/net/wireless/Kconfig
+++ b/net/wireless/Kconfig
@@ -40,6 +40,10 @@ config CFG80211_REG_DEBUG
40 default n 40 default n
41 ---help--- 41 ---help---
42 You can enable this if you want to debug regulatory changes. 42 You can enable this if you want to debug regulatory changes.
43 For more information on cfg80211 regulatory refer to the wireless
44 wiki:
45
46 http://wireless.kernel.org/en/developers/Regulatory
43 47
44 If unsure, say N. 48 If unsure, say N.
45 49
diff --git a/net/wireless/scan.c b/net/wireless/scan.c
index 7043de6221ab..19c5a9a8d085 100644
--- a/net/wireless/scan.c
+++ b/net/wireless/scan.c
@@ -141,7 +141,7 @@ void cfg80211_bss_expire(struct cfg80211_registered_device *dev)
141 dev->bss_generation++; 141 dev->bss_generation++;
142} 142}
143 143
144static u8 *find_ie(u8 num, u8 *ies, size_t len) 144static u8 *find_ie(u8 num, u8 *ies, int len)
145{ 145{
146 while (len > 2 && ies[0] != num) { 146 while (len > 2 && ies[0] != num) {
147 len -= ies[1] + 2; 147 len -= ies[1] + 2;