diff options
Diffstat (limited to 'drivers/net')
32 files changed, 877 insertions, 523 deletions
diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig index dda7cc2e1f57..a8871a84d87e 100644 --- a/drivers/net/wireless/Kconfig +++ b/drivers/net/wireless/Kconfig | |||
@@ -2,8 +2,17 @@ | |||
2 | # Wireless LAN device configuration | 2 | # Wireless LAN device configuration |
3 | # | 3 | # |
4 | 4 | ||
5 | menu "Wireless LAN" | 5 | menuconfig 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 | |||
15 | if WLAN | ||
7 | 16 | ||
8 | menuconfig WLAN_PRE80211 | 17 | menuconfig 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" | |||
506 | source "drivers/net/wireless/wl12xx/Kconfig" | 514 | source "drivers/net/wireless/wl12xx/Kconfig" |
507 | source "drivers/net/wireless/iwmc3200wifi/Kconfig" | 515 | source "drivers/net/wireless/iwmc3200wifi/Kconfig" |
508 | 516 | ||
509 | endmenu | 517 | endif # 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 | ||
136 | static int ath_init_btcoex_info(struct ath_hw *hw, | 134 | static 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 | |||
609 | chip_reset: | 610 | chip_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"); | |||
58 | MODULE_AUTHOR("Martin Langer"); | 58 | MODULE_AUTHOR("Martin Langer"); |
59 | MODULE_AUTHOR("Stefano Brivio"); | 59 | MODULE_AUTHOR("Stefano Brivio"); |
60 | MODULE_AUTHOR("Michael Buesch"); | 60 | MODULE_AUTHOR("Michael Buesch"); |
61 | MODULE_AUTHOR("Gábor Stefanik"); | ||
61 | MODULE_LICENSE("GPL"); | 62 | MODULE_LICENSE("GPL"); |
62 | 63 | ||
63 | MODULE_FIRMWARE(B43_SUPPORTED_FIRMWARE_ID); | 64 | MODULE_FIRMWARE(B43_SUPPORTED_FIRMWARE_ID); |
@@ -90,7 +91,7 @@ MODULE_PARM_DESC(qos, "Enable QOS support (default on)"); | |||
90 | 91 | ||
91 | static int modparam_btcoex = 1; | 92 | static int modparam_btcoex = 1; |
92 | module_param_named(btcoex, modparam_btcoex, int, 0444); | 93 | module_param_named(btcoex, modparam_btcoex, int, 0444); |
93 | MODULE_PARM_DESC(btcoex, "Enable Bluetooth coexistance (default on)"); | 94 | MODULE_PARM_DESC(btcoex, "Enable Bluetooth coexistence (default on)"); |
94 | 95 | ||
95 | int b43_modparam_verbose = B43_VERBOSITY_DEFAULT; | 96 | int b43_modparam_verbose = B43_VERBOSITY_DEFAULT; |
96 | module_param_named(verbose, b43_modparam_verbose, int, 0644); | 97 | module_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) | |||
518 | static void b43_aphy_op_set_rx_antenna(struct b43_wldev *dev, int antenna) | 518 | static 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 | ||
575 | static void b43_aphy_op_adjust_txpower(struct b43_wldev *dev) | 557 | static 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) | |||
2651 | static void b43_gphy_op_set_rx_antenna(struct b43_wldev *dev, int antenna) | 2651 | static 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 | ||
2715 | static int b43_gphy_op_interf_mitigation(struct b43_wldev *dev, | 2704 | static 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 | ||
1614 | static struct lpphy_tx_gain_table_entry lpphy_rev1_2ghz_tx_gain_table[] = { | 1615 | static 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 | ||
1745 | static struct lpphy_tx_gain_table_entry lpphy_rev1_5ghz_tx_gain_table[] = { | 1746 | static 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 | ||
2269 | void lpphy_rev0_1_table_init(struct b43_wldev *dev) | 2270 | void 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 | ||
5 | config IPW2100 | 5 | config 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 | ||
64 | config IPW2200 | 64 | config 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 | ||
151 | config LIBIPW | 151 | config 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); | |||
96 | void iwl_hwrate_to_tx_control(struct iwl_priv *priv, u32 rate_n_flags, | 96 | void 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 | } |
119 | EXPORT_SYMBOL(iwl_hwrate_to_tx_control); | 115 | EXPORT_SYMBOL(iwl_hwrate_to_tx_control); |
120 | 116 | ||
@@ -149,6 +145,27 @@ int iwl_hwrate_to_plcp_idx(u32 rate_n_flags) | |||
149 | } | 145 | } |
150 | EXPORT_SYMBOL(iwl_hwrate_to_plcp_idx); | 146 | EXPORT_SYMBOL(iwl_hwrate_to_plcp_idx); |
151 | 147 | ||
148 | int 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 | |||
152 | u8 iwl_toggle_tx_ant(struct iwl_priv *priv, u8 ant) | 169 | u8 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); | |||
423 | void iwl_hwrate_to_tx_control(struct iwl_priv *priv, u32 rate_n_flags, | 423 | void 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); |
425 | int iwl_hwrate_to_plcp_idx(u32 rate_n_flags); | 425 | int iwl_hwrate_to_plcp_idx(u32 rate_n_flags); |
426 | int iwl_hwrate_to_mac80211_idx(u32 rate_n_flags, enum ieee80211_band band); | ||
426 | 427 | ||
427 | u8 iwl_rate_get_lowest_plcp(struct iwl_priv *priv); | 428 | u8 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, | |||
566 | static void iwl_tx_cmd_build_rate(struct iwl_priv *priv, | 566 | static 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 | ||
241 | int iwm_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev, | 241 | static 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 | ||
620 | static int iwm_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev, | 668 | static 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 | ||
101 | static int iwm_txrx_open(struct inode *inode, struct file *filp) | 101 | static 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 | ||
292 | static 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 | |||
368 | out: | ||
369 | |||
370 | return simple_read_from_buffer(buffer, len, ppos, buf, buf_len); | ||
371 | } | ||
292 | 372 | ||
293 | static const struct file_operations iwm_debugfs_txq_fops = { | 373 | static 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 | ||
299 | static const struct file_operations iwm_debugfs_tx_credit_fops = { | 379 | static 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 | ||
305 | static const struct file_operations iwm_debugfs_rx_ticket_fops = { | 385 | static 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 | ||
391 | static 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 | |||
311 | int iwm_debugfs_init(struct iwm_priv *iwm) | 397 | int 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 | ||
264 | static 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) | |||
276 | int iwm_load_fw(struct iwm_priv *iwm) | 303 | int 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 @@ | |||
64 | struct iwm_conf { | 64 | struct 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 | ||
181 | struct iwm_tx_queue { | 183 | struct 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); | |||
315 | int iwm_priv_init(struct iwm_priv *iwm); | 320 | int iwm_priv_init(struct iwm_priv *iwm); |
316 | void iwm_priv_deinit(struct iwm_priv *iwm); | 321 | void iwm_priv_deinit(struct iwm_priv *iwm); |
317 | void iwm_reset(struct iwm_priv *iwm); | 322 | void iwm_reset(struct iwm_priv *iwm); |
323 | void iwm_resetting(struct iwm_priv *iwm); | ||
318 | void iwm_tx_credit_init_pools(struct iwm_priv *iwm, | 324 | void iwm_tx_credit_init_pools(struct iwm_priv *iwm, |
319 | struct iwm_umac_notif_alive *alive); | 325 | struct iwm_umac_notif_alive *alive); |
320 | int iwm_tx_credit_alloc(struct iwm_priv *iwm, int id, int nb); | 326 | int 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 | ||
399 | enum { | ||
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 | ||
403 | struct iwm_lmac_calib_hdr { | 418 | struct 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 @@ | |||
53 | static struct iwm_conf def_iwm_conf = { | 53 | static 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 | ||
111 | int __iwm_up(struct iwm_priv *iwm); | 116 | static void iwm_disconnect_work(struct work_struct *work) |
112 | int __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 | |||
136 | static int __iwm_up(struct iwm_priv *iwm); | ||
137 | static int __iwm_down(struct iwm_priv *iwm); | ||
113 | 138 | ||
114 | static void iwm_reset_worker(struct work_struct *work) | 139 | static 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 | ||
181 | int iwm_priv_init(struct iwm_priv *iwm) | 207 | int 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 | ||
314 | void 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 | ||
541 | int __iwm_up(struct iwm_priv *iwm) | 585 | static 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 | ||
675 | int __iwm_down(struct iwm_priv *iwm) | 719 | static 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 | |||
623 | static 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 | |||
579 | static int iwm_mlme_scan_complete(struct iwm_priv *iwm, u8 *buf, | 634 | static 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 { | |||
253 | struct ndis_80211_status_indication { | 253 | struct 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 | |||
564 | static u32 get_bcm4320_power_dbm(struct rndis_wlan_private *priv) | 563 | static 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 | |||
580 | static bool is_wpa_key(struct rndis_wlan_private *priv, int idx) | 578 | static 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 | |||
589 | static int rndis_cipher_to_alg(u32 cipher) | 586 | static 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 |
618 | static const char *oid_to_string(__le32 oid) | 614 | static 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 */ |
680 | static int rndis_error_status(__le32 rndis_status) | 675 | static 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 | |||
703 | static int rndis_query_oid(struct usbnet *dev, __le32 oid, void *data, int *len) | 697 | static 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 | |||
762 | static int rndis_set_oid(struct usbnet *dev, __le32 oid, void *data, int len) | 755 | static 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 | |||
821 | static int rndis_reset(struct usbnet *usbdev) | 813 | static 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, | |||
927 | static int rndis_set_config_parameter_str(struct usbnet *dev, | 918 | static 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 | 1013 | static int disassociate(struct usbnet *usbdev, bool reset_ssid) | |
1031 | static 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 | |||
1068 | static int set_auth_mode(struct usbnet *usbdev, u32 wpa_version, | 1049 | static 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 | |||
1113 | static int set_priv_filter(struct usbnet *usbdev) | 1093 | static 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 | |||
1131 | static int set_encr_mode(struct usbnet *usbdev, int pairwise, int groupwise) | 1110 | static 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 | |||
1167 | static int set_infra_mode(struct usbnet *usbdev, int mode) | 1145 | static 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 | |||
1193 | static int set_rts_threshold(struct usbnet *usbdev, u32 rts_threshold) | 1170 | static 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 | |||
1208 | static int set_frag_threshold(struct usbnet *usbdev, u32 frag_threshold) | 1184 | static 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 | |||
1223 | static void set_default_iw_params(struct usbnet *usbdev) | 1198 | static 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 | |||
1233 | static int deauthenticate(struct usbnet *usbdev) | 1207 | static 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 | |||
1243 | static int set_channel(struct usbnet *usbdev, int channel) | 1216 | static 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 */ |
1275 | static int add_wep_key(struct usbnet *usbdev, const u8 *key, int key_len, | 1247 | static 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 | |||
1326 | static int add_wpa_key(struct usbnet *usbdev, const u8 *key, int key_len, | 1297 | static 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 | |||
1421 | static int restore_key(struct usbnet *usbdev, int key_idx) | 1391 | static 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 | |||
1440 | static void restore_keys(struct usbnet *usbdev) | 1409 | static 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 | |||
1449 | static void clear_key(struct rndis_wlan_private *priv, int idx) | 1417 | static 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 */ |
1456 | static int remove_key(struct usbnet *usbdev, int index, const u8 *bssid) | 1423 | static 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 | |||
1512 | static void set_multicast_list(struct usbnet *usbdev) | 1478 | static 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 | |||
1601 | static int rndis_set_wiphy_params(struct wiphy *wiphy, u32 changed) | 1565 | static 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 | |||
1623 | static int rndis_set_tx_power(struct wiphy *wiphy, enum tx_power_setting type, | 1586 | static 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 | |||
1646 | static int rndis_get_tx_power(struct wiphy *wiphy, int *dbm) | 1608 | static 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) |
1660 | static int rndis_scan(struct wiphy *wiphy, struct net_device *dev, | 1621 | static 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 | |||
1696 | static struct cfg80211_bss *rndis_bss_info_update(struct usbnet *usbdev, | 1656 | static 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 | |||
1745 | static int rndis_check_bssid_list(struct usbnet *usbdev) | 1704 | static 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 | |||
1794 | static void rndis_get_scan_results(struct work_struct *work) | 1752 | static 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 | ||
1925 | err_turn_radio_on: | 1883 | err_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 | ||
2033 | err_turn_radio_on: | 1991 | err_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 | */ | ||
2179 | static void rndis_wlan_do_link_up_work(struct usbnet *usbdev) | 2139 | static 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 | |||
2297 | static void rndis_wlan_auth_indication(struct usbnet *usbdev, | 2256 | static 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 | |||
2480 | static void rndis_wlan_indication(struct usbnet *usbdev, void *ind, int buflen) | 2438 | static 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 | |||
2527 | static int rndis_wlan_get_caps(struct usbnet *usbdev) | 2484 | static 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) |
2565 | static void rndis_device_poller(struct work_struct *work) | 2521 | static 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 | */ | ||
2636 | static int bcm4320a_early_init(struct usbnet *usbdev) | 2594 | static 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 | |||
2646 | static int bcm4320b_early_init(struct usbnet *usbdev) | 2603 | static 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 | |||
2725 | static int rndis_wlan_bind(struct usbnet *usbdev, struct usb_interface *intf) | 2681 | static 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 | |||
2844 | static void rndis_wlan_unbind(struct usbnet *usbdev, struct usb_interface *intf) | 2799 | static 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 | |||
2867 | static int rndis_wlan_reset(struct usbnet *usbdev) | 2821 | static 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 | |||
2889 | static int rndis_wlan_stop(struct usbnet *usbdev) | 2842 | static 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 | |||
2920 | static const struct driver_info bcm4320b_info = { | 2872 | static 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 | ||
157 | void rt2x00crypto_rx_insert_iv(struct sk_buff *skb, bool l2pad, | 157 | void 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); | |||
120 | void rt2x00queue_free_skb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb); | 120 | void 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 | */ | ||
129 | void 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 | */ | ||
139 | void 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 | */ | ||
148 | void 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 | */ |
136 | void rt2x00queue_payload_align(struct sk_buff *skb, | 158 | void 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, | |||
324 | void rt2x00crypto_tx_remove_iv(struct sk_buff *skb, | 345 | void rt2x00crypto_tx_remove_iv(struct sk_buff *skb, |
325 | struct txentry_desc *txdesc); | 346 | struct txentry_desc *txdesc); |
326 | void rt2x00crypto_tx_insert_iv(struct sk_buff *skb, unsigned int header_length); | 347 | void rt2x00crypto_tx_insert_iv(struct sk_buff *skb, unsigned int header_length); |
327 | void rt2x00crypto_rx_insert_iv(struct sk_buff *skb, bool l2pad, | 348 | void 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 | ||
151 | void rt2x00queue_payload_align(struct sk_buff *skb, | 151 | void 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; | 164 | void 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 | |||
177 | void 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 | ||
222 | void 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 | |||
180 | static void rt2x00queue_create_tx_descriptor_seq(struct queue_entry *entry, | 234 | static 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 |