aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2010-10-08 16:51:11 -0400
committerDavid S. Miller <davem@davemloft.net>2010-10-08 16:51:11 -0400
commit9cf8d1a3b8cb19fa49494c1b8f0f9e3a37f2c218 (patch)
tree0e9262488832ad27f6ba42680bf104872fa3c697
parent8391d07b80e8da957cd888870e23f8e218438622 (diff)
parente9a68707d736f4f73d7e209885d7b4c5c452b1dc (diff)
Merge branch 'for-davem' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6
-rw-r--r--Documentation/feature-removal-schedule.txt9
-rw-r--r--MAINTAINERS2
-rw-r--r--arch/arm/mach-omap2/board-zoom-peripherals.c2
-rw-r--r--drivers/net/wireless/ath/ar9170/usb.c2
-rw-r--r--drivers/net/wireless/ath/ath.h5
-rw-r--r--drivers/net/wireless/ath/ath5k/base.c279
-rw-r--r--drivers/net/wireless/ath/ath5k/base.h26
-rw-r--r--drivers/net/wireless/ath/ath5k/debug.c4
-rw-r--r--drivers/net/wireless/ath/ath5k/reset.c4
-rw-r--r--drivers/net/wireless/ath/ath9k/ani.c655
-rw-r--r--drivers/net/wireless/ath/ath9k/ani.h21
-rw-r--r--drivers/net/wireless/ath/ath9k/ar5008_phy.c28
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9002_calib.c68
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9002_hw.c9
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9002_phy.c1
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_calib.c37
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_hw.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_phy.c21
-rw-r--r--drivers/net/wireless/ath/ath9k/ath9k.h4
-rw-r--r--drivers/net/wireless/ath/ath9k/calib.c43
-rw-r--r--drivers/net/wireless/ath/ath9k/calib.h10
-rw-r--r--drivers/net/wireless/ath/ath9k/debug.c30
-rw-r--r--drivers/net/wireless/ath/ath9k/debug.h12
-rw-r--r--drivers/net/wireless/ath/ath9k/eeprom_4k.c12
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_init.c12
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_main.c13
-rw-r--r--drivers/net/wireless/ath/ath9k/hw-ops.h22
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.c20
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.h45
-rw-r--r--drivers/net/wireless/ath/ath9k/init.c39
-rw-r--r--drivers/net/wireless/ath/ath9k/mac.c8
-rw-r--r--drivers/net/wireless/ath/ath9k/main.c102
-rw-r--r--drivers/net/wireless/ath/ath9k/xmit.c30
-rw-r--r--drivers/net/wireless/ath/carl9170/carl9170.h2
-rw-r--r--drivers/net/wireless/ath/carl9170/cmd.h10
-rw-r--r--drivers/net/wireless/ath/carl9170/fw.c7
-rw-r--r--drivers/net/wireless/ath/carl9170/fwcmd.h16
-rw-r--r--drivers/net/wireless/ath/carl9170/fwdesc.h6
-rw-r--r--drivers/net/wireless/ath/carl9170/hw.h3
-rw-r--r--drivers/net/wireless/ath/carl9170/main.c30
-rw-r--r--drivers/net/wireless/ath/carl9170/phy.h5
-rw-r--r--drivers/net/wireless/ath/carl9170/version.h6
-rw-r--r--drivers/net/wireless/b43/b43.h3
-rw-r--r--drivers/net/wireless/b43/phy_common.c6
-rw-r--r--drivers/net/wireless/b43/phy_n.c31
-rw-r--r--drivers/net/wireless/ipw2x00/ipw2200.c8
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-1000.c102
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945.c43
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965.c47
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-5000.c191
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-6000.c621
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-calib.c40
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c12
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c5
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-ict.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-lib.c47
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-rs.c11
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-rx.c33
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-tt.c6
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-tx.c19
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-ucode.c5
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.c84
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.h4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-commands.h37
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.c103
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.h136
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-csr.h3
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-debugfs.c58
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-dev.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-eeprom.c12
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-led.c6
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-power.c4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-scan.c3
-rw-r--r--drivers/net/wireless/iwlwifi/iwl3945-base.c22
-rw-r--r--drivers/net/wireless/iwmc3200wifi/cfg80211.c7
-rw-r--r--drivers/net/wireless/libertas/cfg.c4
-rw-r--r--drivers/net/wireless/p54/p54usb.c13
-rw-r--r--drivers/net/wireless/rndis_wlan.c12
-rw-r--r--drivers/net/wireless/rt2x00/rt2500usb.c7
-rw-r--r--drivers/net/wireless/rt2x00/rt2800.h61
-rw-r--r--drivers/net/wireless/rt2x00/rt2800lib.c264
-rw-r--r--drivers/net/wireless/rt2x00/rt2800lib.h1
-rw-r--r--drivers/net/wireless/rt2x00/rt2800pci.c165
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00.h18
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00config.c3
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00dev.c38
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00ht.c21
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00mac.c2
-rw-r--r--drivers/net/wireless/rt2x00/rt61pci.c5
-rw-r--r--drivers/net/wireless/rt2x00/rt73usb.c8
-rw-r--r--drivers/net/wireless/rtl818x/rtl8180_dev.c128
-rw-r--r--drivers/net/wireless/wl12xx/wl1271.h29
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_acx.c34
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_acx.h31
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_boot.c39
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_cmd.c143
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_cmd.h73
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_conf.h78
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_event.c15
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_init.c39
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_main.c393
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_ps.c20
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_ps.h2
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_rx.c63
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_scan.c79
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_scan.h6
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_sdio.c3
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_spi.c143
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_testmode.c14
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_tx.c105
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_tx.h17
-rw-r--r--include/linux/nl80211.h25
-rw-r--r--include/linux/wl12xx.h13
-rw-r--r--include/net/cfg80211.h25
-rw-r--r--include/net/genetlink.h18
-rw-r--r--include/net/mac80211.h30
-rw-r--r--net/mac80211/agg-rx.c8
-rw-r--r--net/mac80211/agg-tx.c16
-rw-r--r--net/mac80211/cfg.c79
-rw-r--r--net/mac80211/debugfs_sta.c3
-rw-r--r--net/mac80211/ht.c17
-rw-r--r--net/mac80211/ibss.c65
-rw-r--r--net/mac80211/ieee80211_i.h20
-rw-r--r--net/mac80211/iface.c50
-rw-r--r--net/mac80211/key.c95
-rw-r--r--net/mac80211/key.h3
-rw-r--r--net/mac80211/main.c27
-rw-r--r--net/mac80211/mlme.c33
-rw-r--r--net/mac80211/pm.c5
-rw-r--r--net/mac80211/rx.c42
-rw-r--r--net/mac80211/scan.c154
-rw-r--r--net/mac80211/sta_info.c12
-rw-r--r--net/mac80211/sta_info.h8
-rw-r--r--net/mac80211/status.c6
-rw-r--r--net/mac80211/tx.c5
-rw-r--r--net/mac80211/util.c22
-rw-r--r--net/netlink/genetlink.c14
-rw-r--r--net/wireless/core.c54
-rw-r--r--net/wireless/core.h2
-rw-r--r--net/wireless/ibss.c2
-rw-r--r--net/wireless/mlme.c54
-rw-r--r--net/wireless/nl80211.c2000
-rw-r--r--net/wireless/scan.c12
-rw-r--r--net/wireless/sme.c2
-rw-r--r--net/wireless/util.c12
-rw-r--r--net/wireless/wext-compat.c38
146 files changed, 4231 insertions, 4191 deletions
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt
index 842aa9de84a..f4563896285 100644
--- a/Documentation/feature-removal-schedule.txt
+++ b/Documentation/feature-removal-schedule.txt
@@ -564,3 +564,12 @@ Who: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
564 564
565---------------------------- 565----------------------------
566 566
567What: iwlwifi disable_hw_scan module parameters
568When: 2.6.40
569Why: Hareware scan is the prefer method for iwlwifi devices for
570 scanning operation. Remove software scan support for all the
571 iwlwifi devices.
572
573Who: Wey-Yi Guy <wey-yi.w.guy@intel.com>
574
575----------------------------
diff --git a/MAINTAINERS b/MAINTAINERS
index e967aadddfc..296c3d7cdb5 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -6457,7 +6457,7 @@ WL1271 WIRELESS DRIVER
6457M: Luciano Coelho <luciano.coelho@nokia.com> 6457M: Luciano Coelho <luciano.coelho@nokia.com>
6458L: linux-wireless@vger.kernel.org 6458L: linux-wireless@vger.kernel.org
6459W: http://wireless.kernel.org 6459W: http://wireless.kernel.org
6460T: git git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-testing.git 6460T: git git://git.kernel.org/pub/scm/linux/kernel/git/luca/wl12xx.git
6461S: Maintained 6461S: Maintained
6462F: drivers/net/wireless/wl12xx/wl1271* 6462F: drivers/net/wireless/wl12xx/wl1271*
6463F: include/linux/wl12xx.h 6463F: include/linux/wl12xx.h
diff --git a/arch/arm/mach-omap2/board-zoom-peripherals.c b/arch/arm/mach-omap2/board-zoom-peripherals.c
index 6aa0728fa15..189a6d1600b 100644
--- a/arch/arm/mach-omap2/board-zoom-peripherals.c
+++ b/arch/arm/mach-omap2/board-zoom-peripherals.c
@@ -213,7 +213,7 @@ static struct omap2_hsmmc_info mmc[] __initdata = {
213 { 213 {
214 .name = "wl1271", 214 .name = "wl1271",
215 .mmc = 3, 215 .mmc = 3,
216 .wires = 4, 216 .caps = MMC_CAP_4_BIT_DATA,
217 .gpio_wp = -EINVAL, 217 .gpio_wp = -EINVAL,
218 .gpio_cd = -EINVAL, 218 .gpio_cd = -EINVAL,
219 .nonremovable = true, 219 .nonremovable = true,
diff --git a/drivers/net/wireless/ath/ar9170/usb.c b/drivers/net/wireless/ath/ar9170/usb.c
index a93dc18a45c..5dbb5361fd5 100644
--- a/drivers/net/wireless/ath/ar9170/usb.c
+++ b/drivers/net/wireless/ath/ar9170/usb.c
@@ -54,8 +54,6 @@ MODULE_AUTHOR("Christian Lamparter <chunkeey@web.de>");
54MODULE_LICENSE("GPL"); 54MODULE_LICENSE("GPL");
55MODULE_DESCRIPTION("Atheros AR9170 802.11n USB wireless"); 55MODULE_DESCRIPTION("Atheros AR9170 802.11n USB wireless");
56MODULE_FIRMWARE("ar9170.fw"); 56MODULE_FIRMWARE("ar9170.fw");
57MODULE_FIRMWARE("ar9170-1.fw");
58MODULE_FIRMWARE("ar9170-2.fw");
59 57
60enum ar9170_requirements { 58enum ar9170_requirements {
61 AR9170_REQ_FW1_ONLY = 1, 59 AR9170_REQ_FW1_ONLY = 1,
diff --git a/drivers/net/wireless/ath/ath.h b/drivers/net/wireless/ath/ath.h
index dd236c3b52f..cee0191704f 100644
--- a/drivers/net/wireless/ath/ath.h
+++ b/drivers/net/wireless/ath/ath.h
@@ -35,7 +35,6 @@ static const u8 ath_bcast_mac[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
35 35
36struct ath_ani { 36struct ath_ani {
37 bool caldone; 37 bool caldone;
38 int16_t noise_floor;
39 unsigned int longcal_timer; 38 unsigned int longcal_timer;
40 unsigned int shortcal_timer; 39 unsigned int shortcal_timer;
41 unsigned int resetcal_timer; 40 unsigned int resetcal_timer;
@@ -103,14 +102,12 @@ enum ath_cipher {
103 * @read: Register read 102 * @read: Register read
104 * @write: Register write 103 * @write: Register write
105 * @enable_write_buffer: Enable multiple register writes 104 * @enable_write_buffer: Enable multiple register writes
106 * @disable_write_buffer: Disable multiple register writes 105 * @write_flush: flush buffered register writes and disable buffering
107 * @write_flush: Flush buffered register writes
108 */ 106 */
109struct ath_ops { 107struct ath_ops {
110 unsigned int (*read)(void *, u32 reg_offset); 108 unsigned int (*read)(void *, u32 reg_offset);
111 void (*write)(void *, u32 val, u32 reg_offset); 109 void (*write)(void *, u32 val, u32 reg_offset);
112 void (*enable_write_buffer)(void *); 110 void (*enable_write_buffer)(void *);
113 void (*disable_write_buffer)(void *);
114 void (*write_flush) (void *); 111 void (*write_flush) (void *);
115}; 112};
116 113
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c
index 94cc3354f3a..dad72658563 100644
--- a/drivers/net/wireless/ath/ath5k/base.c
+++ b/drivers/net/wireless/ath/ath5k/base.c
@@ -52,6 +52,7 @@
52#include <linux/ethtool.h> 52#include <linux/ethtool.h>
53#include <linux/uaccess.h> 53#include <linux/uaccess.h>
54#include <linux/slab.h> 54#include <linux/slab.h>
55#include <linux/etherdevice.h>
55 56
56#include <net/ieee80211_radiotap.h> 57#include <net/ieee80211_radiotap.h>
57 58
@@ -509,8 +510,71 @@ ath5k_setcurmode(struct ath5k_softc *sc, unsigned int mode)
509 } 510 }
510} 511}
511 512
513struct ath_vif_iter_data {
514 const u8 *hw_macaddr;
515 u8 mask[ETH_ALEN];
516 u8 active_mac[ETH_ALEN]; /* first active MAC */
517 bool need_set_hw_addr;
518 bool found_active;
519 bool any_assoc;
520};
521
522static void ath_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
523{
524 struct ath_vif_iter_data *iter_data = data;
525 int i;
526
527 if (iter_data->hw_macaddr)
528 for (i = 0; i < ETH_ALEN; i++)
529 iter_data->mask[i] &=
530 ~(iter_data->hw_macaddr[i] ^ mac[i]);
531
532 if (!iter_data->found_active) {
533 iter_data->found_active = true;
534 memcpy(iter_data->active_mac, mac, ETH_ALEN);
535 }
536
537 if (iter_data->need_set_hw_addr && iter_data->hw_macaddr)
538 if (compare_ether_addr(iter_data->hw_macaddr, mac) == 0)
539 iter_data->need_set_hw_addr = false;
540
541 if (!iter_data->any_assoc) {
542 struct ath5k_vif *avf = (void *)vif->drv_priv;
543 if (avf->assoc)
544 iter_data->any_assoc = true;
545 }
546}
547
548void ath5k_update_bssid_mask(struct ath5k_softc *sc, struct ieee80211_vif *vif)
549{
550 struct ath_common *common = ath5k_hw_common(sc->ah);
551 struct ath_vif_iter_data iter_data;
552
553 /*
554 * Use the hardware MAC address as reference, the hardware uses it
555 * together with the BSSID mask when matching addresses.
556 */
557 iter_data.hw_macaddr = common->macaddr;
558 memset(&iter_data.mask, 0xff, ETH_ALEN);
559 iter_data.found_active = false;
560 iter_data.need_set_hw_addr = true;
561
562 if (vif)
563 ath_vif_iter(&iter_data, vif->addr, vif);
564
565 /* Get list of all active MAC addresses */
566 ieee80211_iterate_active_interfaces_atomic(sc->hw, ath_vif_iter,
567 &iter_data);
568 memcpy(sc->bssidmask, iter_data.mask, ETH_ALEN);
569
570 if (iter_data.need_set_hw_addr && iter_data.found_active)
571 ath5k_hw_set_lladdr(sc->ah, iter_data.active_mac);
572
573 ath5k_hw_set_bssid_mask(sc->ah, sc->bssidmask);
574}
575
512static void 576static void
513ath5k_mode_setup(struct ath5k_softc *sc) 577ath5k_mode_setup(struct ath5k_softc *sc, struct ieee80211_vif *vif)
514{ 578{
515 struct ath5k_hw *ah = sc->ah; 579 struct ath5k_hw *ah = sc->ah;
516 u32 rfilt; 580 u32 rfilt;
@@ -520,7 +584,7 @@ ath5k_mode_setup(struct ath5k_softc *sc)
520 ath5k_hw_set_rx_filter(ah, rfilt); 584 ath5k_hw_set_rx_filter(ah, rfilt);
521 585
522 if (ath5k_hw_hasbssidmask(ah)) 586 if (ath5k_hw_hasbssidmask(ah))
523 ath5k_hw_set_bssid_mask(ah, sc->bssidmask); 587 ath5k_update_bssid_mask(sc, vif);
524 588
525 /* configure operational mode */ 589 /* configure operational mode */
526 ath5k_hw_set_opmode(ah, sc->opmode); 590 ath5k_hw_set_opmode(ah, sc->opmode);
@@ -698,13 +762,13 @@ ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf,
698 flags |= AR5K_TXDESC_RTSENA; 762 flags |= AR5K_TXDESC_RTSENA;
699 cts_rate = ieee80211_get_rts_cts_rate(sc->hw, info)->hw_value; 763 cts_rate = ieee80211_get_rts_cts_rate(sc->hw, info)->hw_value;
700 duration = le16_to_cpu(ieee80211_rts_duration(sc->hw, 764 duration = le16_to_cpu(ieee80211_rts_duration(sc->hw,
701 sc->vif, pktlen, info)); 765 info->control.vif, pktlen, info));
702 } 766 }
703 if (rc_flags & IEEE80211_TX_RC_USE_CTS_PROTECT) { 767 if (rc_flags & IEEE80211_TX_RC_USE_CTS_PROTECT) {
704 flags |= AR5K_TXDESC_CTSENA; 768 flags |= AR5K_TXDESC_CTSENA;
705 cts_rate = ieee80211_get_rts_cts_rate(sc->hw, info)->hw_value; 769 cts_rate = ieee80211_get_rts_cts_rate(sc->hw, info)->hw_value;
706 duration = le16_to_cpu(ieee80211_ctstoself_duration(sc->hw, 770 duration = le16_to_cpu(ieee80211_ctstoself_duration(sc->hw,
707 sc->vif, pktlen, info)); 771 info->control.vif, pktlen, info));
708 } 772 }
709 ret = ah->ah_setup_tx_desc(ah, ds, pktlen, 773 ret = ah->ah_setup_tx_desc(ah, ds, pktlen,
710 ieee80211_get_hdrlen_from_skb(skb), padsize, 774 ieee80211_get_hdrlen_from_skb(skb), padsize,
@@ -806,10 +870,13 @@ ath5k_desc_alloc(struct ath5k_softc *sc, struct pci_dev *pdev)
806 list_add_tail(&bf->list, &sc->txbuf); 870 list_add_tail(&bf->list, &sc->txbuf);
807 } 871 }
808 872
809 /* beacon buffer */ 873 /* beacon buffers */
810 bf->desc = ds; 874 INIT_LIST_HEAD(&sc->bcbuf);
811 bf->daddr = da; 875 for (i = 0; i < ATH_BCBUF; i++, bf++, ds++, da += sizeof(*ds)) {
812 sc->bbuf = bf; 876 bf->desc = ds;
877 bf->daddr = da;
878 list_add_tail(&bf->list, &sc->bcbuf);
879 }
813 880
814 return 0; 881 return 0;
815err_free: 882err_free:
@@ -824,11 +891,12 @@ ath5k_desc_free(struct ath5k_softc *sc, struct pci_dev *pdev)
824{ 891{
825 struct ath5k_buf *bf; 892 struct ath5k_buf *bf;
826 893
827 ath5k_txbuf_free_skb(sc, sc->bbuf);
828 list_for_each_entry(bf, &sc->txbuf, list) 894 list_for_each_entry(bf, &sc->txbuf, list)
829 ath5k_txbuf_free_skb(sc, bf); 895 ath5k_txbuf_free_skb(sc, bf);
830 list_for_each_entry(bf, &sc->rxbuf, list) 896 list_for_each_entry(bf, &sc->rxbuf, list)
831 ath5k_rxbuf_free_skb(sc, bf); 897 ath5k_rxbuf_free_skb(sc, bf);
898 list_for_each_entry(bf, &sc->bcbuf, list)
899 ath5k_txbuf_free_skb(sc, bf);
832 900
833 /* Free memory associated with all descriptors */ 901 /* Free memory associated with all descriptors */
834 pci_free_consistent(pdev, sc->desc_len, sc->desc, sc->desc_daddr); 902 pci_free_consistent(pdev, sc->desc_len, sc->desc, sc->desc_daddr);
@@ -837,7 +905,6 @@ ath5k_desc_free(struct ath5k_softc *sc, struct pci_dev *pdev)
837 905
838 kfree(sc->bufptr); 906 kfree(sc->bufptr);
839 sc->bufptr = NULL; 907 sc->bufptr = NULL;
840 sc->bbuf = NULL;
841} 908}
842 909
843 910
@@ -1083,7 +1150,7 @@ ath5k_rx_start(struct ath5k_softc *sc)
1083 spin_unlock_bh(&sc->rxbuflock); 1150 spin_unlock_bh(&sc->rxbuflock);
1084 1151
1085 ath5k_hw_start_rx_dma(ah); /* enable recv descriptors */ 1152 ath5k_hw_start_rx_dma(ah); /* enable recv descriptors */
1086 ath5k_mode_setup(sc); /* set filters, etc. */ 1153 ath5k_mode_setup(sc, NULL); /* set filters, etc. */
1087 ath5k_hw_start_rx_pcu(ah); /* re-enable PCU/DMA engine */ 1154 ath5k_hw_start_rx_pcu(ah); /* re-enable PCU/DMA engine */
1088 1155
1089 return 0; 1156 return 0;
@@ -1366,6 +1433,7 @@ static bool
1366ath5k_receive_frame_ok(struct ath5k_softc *sc, struct ath5k_rx_status *rs) 1433ath5k_receive_frame_ok(struct ath5k_softc *sc, struct ath5k_rx_status *rs)
1367{ 1434{
1368 sc->stats.rx_all_count++; 1435 sc->stats.rx_all_count++;
1436 sc->stats.rx_bytes_count += rs->rs_datalen;
1369 1437
1370 if (unlikely(rs->rs_status)) { 1438 if (unlikely(rs->rs_status)) {
1371 if (rs->rs_status & AR5K_RXERR_CRC) 1439 if (rs->rs_status & AR5K_RXERR_CRC)
@@ -1544,6 +1612,7 @@ ath5k_tx_frame_completed(struct ath5k_softc *sc, struct sk_buff *skb,
1544 int i; 1612 int i;
1545 1613
1546 sc->stats.tx_all_count++; 1614 sc->stats.tx_all_count++;
1615 sc->stats.tx_bytes_count += skb->len;
1547 info = IEEE80211_SKB_CB(skb); 1616 info = IEEE80211_SKB_CB(skb);
1548 1617
1549 ieee80211_tx_info_clear_status(info); 1618 ieee80211_tx_info_clear_status(info);
@@ -1642,7 +1711,7 @@ ath5k_tx_processq(struct ath5k_softc *sc, struct ath5k_txq *txq)
1642 } 1711 }
1643 } 1712 }
1644 spin_unlock(&txq->lock); 1713 spin_unlock(&txq->lock);
1645 if (txq->txq_len < ATH5K_TXQ_LEN_LOW) 1714 if (txq->txq_len < ATH5K_TXQ_LEN_LOW && txq->qnum < 4)
1646 ieee80211_wake_queue(sc->hw, txq->qnum); 1715 ieee80211_wake_queue(sc->hw, txq->qnum);
1647} 1716}
1648 1717
@@ -1750,6 +1819,7 @@ ath5k_beacon_update(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
1750{ 1819{
1751 int ret; 1820 int ret;
1752 struct ath5k_softc *sc = hw->priv; 1821 struct ath5k_softc *sc = hw->priv;
1822 struct ath5k_vif *avf = (void *)vif->drv_priv;
1753 struct sk_buff *skb; 1823 struct sk_buff *skb;
1754 1824
1755 if (WARN_ON(!vif)) { 1825 if (WARN_ON(!vif)) {
@@ -1766,11 +1836,11 @@ ath5k_beacon_update(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
1766 1836
1767 ath5k_debug_dump_skb(sc, skb, "BC ", 1); 1837 ath5k_debug_dump_skb(sc, skb, "BC ", 1);
1768 1838
1769 ath5k_txbuf_free_skb(sc, sc->bbuf); 1839 ath5k_txbuf_free_skb(sc, avf->bbuf);
1770 sc->bbuf->skb = skb; 1840 avf->bbuf->skb = skb;
1771 ret = ath5k_beacon_setup(sc, sc->bbuf); 1841 ret = ath5k_beacon_setup(sc, avf->bbuf);
1772 if (ret) 1842 if (ret)
1773 sc->bbuf->skb = NULL; 1843 avf->bbuf->skb = NULL;
1774out: 1844out:
1775 return ret; 1845 return ret;
1776} 1846}
@@ -1786,16 +1856,14 @@ out:
1786static void 1856static void
1787ath5k_beacon_send(struct ath5k_softc *sc) 1857ath5k_beacon_send(struct ath5k_softc *sc)
1788{ 1858{
1789 struct ath5k_buf *bf = sc->bbuf;
1790 struct ath5k_hw *ah = sc->ah; 1859 struct ath5k_hw *ah = sc->ah;
1860 struct ieee80211_vif *vif;
1861 struct ath5k_vif *avf;
1862 struct ath5k_buf *bf;
1791 struct sk_buff *skb; 1863 struct sk_buff *skb;
1792 1864
1793 ATH5K_DBG_UNLIMIT(sc, ATH5K_DEBUG_BEACON, "in beacon_send\n"); 1865 ATH5K_DBG_UNLIMIT(sc, ATH5K_DEBUG_BEACON, "in beacon_send\n");
1794 1866
1795 if (unlikely(bf->skb == NULL || sc->opmode == NL80211_IFTYPE_STATION)) {
1796 ATH5K_WARN(sc, "bf=%p bf_skb=%p\n", bf, bf ? bf->skb : NULL);
1797 return;
1798 }
1799 /* 1867 /*
1800 * Check if the previous beacon has gone out. If 1868 * Check if the previous beacon has gone out. If
1801 * not, don't don't try to post another: skip this 1869 * not, don't don't try to post another: skip this
@@ -1824,6 +1892,28 @@ ath5k_beacon_send(struct ath5k_softc *sc)
1824 sc->bmisscount = 0; 1892 sc->bmisscount = 0;
1825 } 1893 }
1826 1894
1895 if (sc->opmode == NL80211_IFTYPE_AP && sc->num_ap_vifs > 1) {
1896 u64 tsf = ath5k_hw_get_tsf64(ah);
1897 u32 tsftu = TSF_TO_TU(tsf);
1898 int slot = ((tsftu % sc->bintval) * ATH_BCBUF) / sc->bintval;
1899 vif = sc->bslot[(slot + 1) % ATH_BCBUF];
1900 ATH5K_DBG(sc, ATH5K_DEBUG_BEACON,
1901 "tsf %llx tsftu %x intval %u slot %u vif %p\n",
1902 (unsigned long long)tsf, tsftu, sc->bintval, slot, vif);
1903 } else /* only one interface */
1904 vif = sc->bslot[0];
1905
1906 if (!vif)
1907 return;
1908
1909 avf = (void *)vif->drv_priv;
1910 bf = avf->bbuf;
1911 if (unlikely(bf->skb == NULL || sc->opmode == NL80211_IFTYPE_STATION ||
1912 sc->opmode == NL80211_IFTYPE_MONITOR)) {
1913 ATH5K_WARN(sc, "bf=%p bf_skb=%p\n", bf, bf ? bf->skb : NULL);
1914 return;
1915 }
1916
1827 /* 1917 /*
1828 * Stop any current dma and put the new frame on the queue. 1918 * Stop any current dma and put the new frame on the queue.
1829 * This should never fail since we check above that no frames 1919 * This should never fail since we check above that no frames
@@ -1836,17 +1926,17 @@ ath5k_beacon_send(struct ath5k_softc *sc)
1836 1926
1837 /* refresh the beacon for AP mode */ 1927 /* refresh the beacon for AP mode */
1838 if (sc->opmode == NL80211_IFTYPE_AP) 1928 if (sc->opmode == NL80211_IFTYPE_AP)
1839 ath5k_beacon_update(sc->hw, sc->vif); 1929 ath5k_beacon_update(sc->hw, vif);
1840 1930
1841 ath5k_hw_set_txdp(ah, sc->bhalq, bf->daddr); 1931 ath5k_hw_set_txdp(ah, sc->bhalq, bf->daddr);
1842 ath5k_hw_start_tx_dma(ah, sc->bhalq); 1932 ath5k_hw_start_tx_dma(ah, sc->bhalq);
1843 ATH5K_DBG(sc, ATH5K_DEBUG_BEACON, "TXDP[%u] = %llx (%p)\n", 1933 ATH5K_DBG(sc, ATH5K_DEBUG_BEACON, "TXDP[%u] = %llx (%p)\n",
1844 sc->bhalq, (unsigned long long)bf->daddr, bf->desc); 1934 sc->bhalq, (unsigned long long)bf->daddr, bf->desc);
1845 1935
1846 skb = ieee80211_get_buffered_bc(sc->hw, sc->vif); 1936 skb = ieee80211_get_buffered_bc(sc->hw, vif);
1847 while (skb) { 1937 while (skb) {
1848 ath5k_tx_queue(sc->hw, skb, sc->cabq); 1938 ath5k_tx_queue(sc->hw, skb, sc->cabq);
1849 skb = ieee80211_get_buffered_bc(sc->hw, sc->vif); 1939 skb = ieee80211_get_buffered_bc(sc->hw, vif);
1850 } 1940 }
1851 1941
1852 sc->bsent++; 1942 sc->bsent++;
@@ -1876,6 +1966,12 @@ ath5k_beacon_update_timers(struct ath5k_softc *sc, u64 bc_tsf)
1876 u64 hw_tsf; 1966 u64 hw_tsf;
1877 1967
1878 intval = sc->bintval & AR5K_BEACON_PERIOD; 1968 intval = sc->bintval & AR5K_BEACON_PERIOD;
1969 if (sc->opmode == NL80211_IFTYPE_AP && sc->num_ap_vifs > 1) {
1970 intval /= ATH_BCBUF; /* staggered multi-bss beacons */
1971 if (intval < 15)
1972 ATH5K_WARN(sc, "intval %u is too low, min 15\n",
1973 intval);
1974 }
1879 if (WARN_ON(!intval)) 1975 if (WARN_ON(!intval))
1880 return; 1976 return;
1881 1977
@@ -2323,6 +2419,10 @@ ath5k_init(struct ath5k_softc *sc)
2323 ath_hw_keyreset(common, (u16) i); 2419 ath_hw_keyreset(common, (u16) i);
2324 2420
2325 ath5k_hw_set_ack_bitrate_high(ah, true); 2421 ath5k_hw_set_ack_bitrate_high(ah, true);
2422
2423 for (i = 0; i < ARRAY_SIZE(sc->bslot); i++)
2424 sc->bslot[i] = NULL;
2425
2326 ret = 0; 2426 ret = 0;
2327done: 2427done:
2328 mmiowb(); 2428 mmiowb();
@@ -2382,7 +2482,6 @@ ath5k_stop_hw(struct ath5k_softc *sc)
2382 ATH5K_DBG(sc, ATH5K_DEBUG_RESET, 2482 ATH5K_DBG(sc, ATH5K_DEBUG_RESET,
2383 "putting device to sleep\n"); 2483 "putting device to sleep\n");
2384 } 2484 }
2385 ath5k_txbuf_free_skb(sc, sc->bbuf);
2386 2485
2387 mmiowb(); 2486 mmiowb();
2388 mutex_unlock(&sc->lock); 2487 mutex_unlock(&sc->lock);
@@ -2587,9 +2686,9 @@ ath5k_attach(struct pci_dev *pdev, struct ieee80211_hw *hw)
2587 } 2686 }
2588 2687
2589 SET_IEEE80211_PERM_ADDR(hw, mac); 2688 SET_IEEE80211_PERM_ADDR(hw, mac);
2689 memcpy(&sc->lladdr, mac, ETH_ALEN);
2590 /* All MAC address bits matter for ACKs */ 2690 /* All MAC address bits matter for ACKs */
2591 memcpy(sc->bssidmask, ath_bcast_mac, ETH_ALEN); 2691 ath5k_update_bssid_mask(sc, NULL);
2592 ath5k_hw_set_bssid_mask(sc->ah, sc->bssidmask);
2593 2692
2594 regulatory->current_rd = ah->ah_capabilities.cap_eeprom.ee_regdomain; 2693 regulatory->current_rd = ah->ah_capabilities.cap_eeprom.ee_regdomain;
2595 ret = ath_regd_init(regulatory, hw->wiphy, ath5k_reg_notifier); 2694 ret = ath_regd_init(regulatory, hw->wiphy, ath5k_reg_notifier);
@@ -2687,31 +2786,91 @@ static int ath5k_add_interface(struct ieee80211_hw *hw,
2687{ 2786{
2688 struct ath5k_softc *sc = hw->priv; 2787 struct ath5k_softc *sc = hw->priv;
2689 int ret; 2788 int ret;
2789 struct ath5k_hw *ah = sc->ah;
2790 struct ath5k_vif *avf = (void *)vif->drv_priv;
2690 2791
2691 mutex_lock(&sc->lock); 2792 mutex_lock(&sc->lock);
2692 if (sc->vif) { 2793
2693 ret = 0; 2794 if ((vif->type == NL80211_IFTYPE_AP ||
2795 vif->type == NL80211_IFTYPE_ADHOC)
2796 && (sc->num_ap_vifs + sc->num_adhoc_vifs) >= ATH_BCBUF) {
2797 ret = -ELNRNG;
2694 goto end; 2798 goto end;
2695 } 2799 }
2696 2800
2697 sc->vif = vif; 2801 /* Don't allow other interfaces if one ad-hoc is configured.
2802 * TODO: Fix the problems with ad-hoc and multiple other interfaces.
2803 * We would need to operate the HW in ad-hoc mode to allow TSF updates
2804 * for the IBSS, but this breaks with additional AP or STA interfaces
2805 * at the moment. */
2806 if (sc->num_adhoc_vifs ||
2807 (sc->nvifs && vif->type == NL80211_IFTYPE_ADHOC)) {
2808 ATH5K_ERR(sc, "Only one single ad-hoc interface is allowed.\n");
2809 ret = -ELNRNG;
2810 goto end;
2811 }
2698 2812
2699 switch (vif->type) { 2813 switch (vif->type) {
2700 case NL80211_IFTYPE_AP: 2814 case NL80211_IFTYPE_AP:
2701 case NL80211_IFTYPE_STATION: 2815 case NL80211_IFTYPE_STATION:
2702 case NL80211_IFTYPE_ADHOC: 2816 case NL80211_IFTYPE_ADHOC:
2703 case NL80211_IFTYPE_MESH_POINT: 2817 case NL80211_IFTYPE_MESH_POINT:
2704 sc->opmode = vif->type; 2818 avf->opmode = vif->type;
2705 break; 2819 break;
2706 default: 2820 default:
2707 ret = -EOPNOTSUPP; 2821 ret = -EOPNOTSUPP;
2708 goto end; 2822 goto end;
2709 } 2823 }
2710 2824
2711 ATH5K_DBG(sc, ATH5K_DEBUG_MODE, "add interface mode %d\n", sc->opmode); 2825 sc->nvifs++;
2826 ATH5K_DBG(sc, ATH5K_DEBUG_MODE, "add interface mode %d\n", avf->opmode);
2712 2827
2828 /* Assign the vap/adhoc to a beacon xmit slot. */
2829 if ((avf->opmode == NL80211_IFTYPE_AP) ||
2830 (avf->opmode == NL80211_IFTYPE_ADHOC)) {
2831 int slot;
2832
2833 WARN_ON(list_empty(&sc->bcbuf));
2834 avf->bbuf = list_first_entry(&sc->bcbuf, struct ath5k_buf,
2835 list);
2836 list_del(&avf->bbuf->list);
2837
2838 avf->bslot = 0;
2839 for (slot = 0; slot < ATH_BCBUF; slot++) {
2840 if (!sc->bslot[slot]) {
2841 avf->bslot = slot;
2842 break;
2843 }
2844 }
2845 BUG_ON(sc->bslot[avf->bslot] != NULL);
2846 sc->bslot[avf->bslot] = vif;
2847 if (avf->opmode == NL80211_IFTYPE_AP)
2848 sc->num_ap_vifs++;
2849 else
2850 sc->num_adhoc_vifs++;
2851 }
2852
2853 /* Set combined mode - when APs are configured, operate in AP mode.
2854 * Otherwise use the mode of the new interface. This can currently
2855 * only deal with combinations of APs and STAs. Only one ad-hoc
2856 * interfaces is allowed above.
2857 */
2858 if (sc->num_ap_vifs)
2859 sc->opmode = NL80211_IFTYPE_AP;
2860 else
2861 sc->opmode = vif->type;
2862
2863 ath5k_hw_set_opmode(ah, sc->opmode);
2864
2865 /* Any MAC address is fine, all others are included through the
2866 * filter.
2867 */
2868 memcpy(&sc->lladdr, vif->addr, ETH_ALEN);
2713 ath5k_hw_set_lladdr(sc->ah, vif->addr); 2869 ath5k_hw_set_lladdr(sc->ah, vif->addr);
2714 ath5k_mode_setup(sc); 2870
2871 memcpy(&avf->lladdr, vif->addr, ETH_ALEN);
2872
2873 ath5k_mode_setup(sc, vif);
2715 2874
2716 ret = 0; 2875 ret = 0;
2717end: 2876end:
@@ -2724,15 +2883,29 @@ ath5k_remove_interface(struct ieee80211_hw *hw,
2724 struct ieee80211_vif *vif) 2883 struct ieee80211_vif *vif)
2725{ 2884{
2726 struct ath5k_softc *sc = hw->priv; 2885 struct ath5k_softc *sc = hw->priv;
2727 u8 mac[ETH_ALEN] = {}; 2886 struct ath5k_vif *avf = (void *)vif->drv_priv;
2887 unsigned int i;
2728 2888
2729 mutex_lock(&sc->lock); 2889 mutex_lock(&sc->lock);
2730 if (sc->vif != vif) 2890 sc->nvifs--;
2731 goto end; 2891
2892 if (avf->bbuf) {
2893 ath5k_txbuf_free_skb(sc, avf->bbuf);
2894 list_add_tail(&avf->bbuf->list, &sc->bcbuf);
2895 for (i = 0; i < ATH_BCBUF; i++) {
2896 if (sc->bslot[i] == vif) {
2897 sc->bslot[i] = NULL;
2898 break;
2899 }
2900 }
2901 avf->bbuf = NULL;
2902 }
2903 if (avf->opmode == NL80211_IFTYPE_AP)
2904 sc->num_ap_vifs--;
2905 else if (avf->opmode == NL80211_IFTYPE_ADHOC)
2906 sc->num_adhoc_vifs--;
2732 2907
2733 ath5k_hw_set_lladdr(sc->ah, mac); 2908 ath5k_update_bssid_mask(sc, NULL);
2734 sc->vif = NULL;
2735end:
2736 mutex_unlock(&sc->lock); 2909 mutex_unlock(&sc->lock);
2737} 2910}
2738 2911
@@ -2815,6 +2988,19 @@ static u64 ath5k_prepare_multicast(struct ieee80211_hw *hw,
2815 return ((u64)(mfilt[1]) << 32) | mfilt[0]; 2988 return ((u64)(mfilt[1]) << 32) | mfilt[0];
2816} 2989}
2817 2990
2991static bool ath_any_vif_assoc(struct ath5k_softc *sc)
2992{
2993 struct ath_vif_iter_data iter_data;
2994 iter_data.hw_macaddr = NULL;
2995 iter_data.any_assoc = false;
2996 iter_data.need_set_hw_addr = false;
2997 iter_data.found_active = true;
2998
2999 ieee80211_iterate_active_interfaces_atomic(sc->hw, ath_vif_iter,
3000 &iter_data);
3001 return iter_data.any_assoc;
3002}
3003
2818#define SUPPORTED_FIF_FLAGS \ 3004#define SUPPORTED_FIF_FLAGS \
2819 FIF_PROMISC_IN_BSS | FIF_ALLMULTI | FIF_FCSFAIL | \ 3005 FIF_PROMISC_IN_BSS | FIF_ALLMULTI | FIF_FCSFAIL | \
2820 FIF_PLCPFAIL | FIF_CONTROL | FIF_OTHER_BSS | \ 3006 FIF_PLCPFAIL | FIF_CONTROL | FIF_OTHER_BSS | \
@@ -2885,7 +3071,7 @@ static void ath5k_configure_filter(struct ieee80211_hw *hw,
2885 3071
2886 /* FIF_BCN_PRBRESP_PROMISC really means to enable beacons 3072 /* FIF_BCN_PRBRESP_PROMISC really means to enable beacons
2887 * and probes for any BSSID */ 3073 * and probes for any BSSID */
2888 if (*new_flags & FIF_BCN_PRBRESP_PROMISC) 3074 if ((*new_flags & FIF_BCN_PRBRESP_PROMISC) || (sc->nvifs > 1))
2889 rfilt |= AR5K_RX_FILTER_BEACON; 3075 rfilt |= AR5K_RX_FILTER_BEACON;
2890 3076
2891 /* FIF_CONTROL doc says that if FIF_PROMISC_IN_BSS is not 3077 /* FIF_CONTROL doc says that if FIF_PROMISC_IN_BSS is not
@@ -3070,14 +3256,13 @@ static void ath5k_bss_info_changed(struct ieee80211_hw *hw,
3070 struct ieee80211_bss_conf *bss_conf, 3256 struct ieee80211_bss_conf *bss_conf,
3071 u32 changes) 3257 u32 changes)
3072{ 3258{
3259 struct ath5k_vif *avf = (void *)vif->drv_priv;
3073 struct ath5k_softc *sc = hw->priv; 3260 struct ath5k_softc *sc = hw->priv;
3074 struct ath5k_hw *ah = sc->ah; 3261 struct ath5k_hw *ah = sc->ah;
3075 struct ath_common *common = ath5k_hw_common(ah); 3262 struct ath_common *common = ath5k_hw_common(ah);
3076 unsigned long flags; 3263 unsigned long flags;
3077 3264
3078 mutex_lock(&sc->lock); 3265 mutex_lock(&sc->lock);
3079 if (WARN_ON(sc->vif != vif))
3080 goto unlock;
3081 3266
3082 if (changes & BSS_CHANGED_BSSID) { 3267 if (changes & BSS_CHANGED_BSSID) {
3083 /* Cache for later use during resets */ 3268 /* Cache for later use during resets */
@@ -3091,7 +3276,12 @@ static void ath5k_bss_info_changed(struct ieee80211_hw *hw,
3091 sc->bintval = bss_conf->beacon_int; 3276 sc->bintval = bss_conf->beacon_int;
3092 3277
3093 if (changes & BSS_CHANGED_ASSOC) { 3278 if (changes & BSS_CHANGED_ASSOC) {
3094 sc->assoc = bss_conf->assoc; 3279 avf->assoc = bss_conf->assoc;
3280 if (bss_conf->assoc)
3281 sc->assoc = bss_conf->assoc;
3282 else
3283 sc->assoc = ath_any_vif_assoc(sc);
3284
3095 if (sc->opmode == NL80211_IFTYPE_STATION) 3285 if (sc->opmode == NL80211_IFTYPE_STATION)
3096 set_beacon_filter(hw, sc->assoc); 3286 set_beacon_filter(hw, sc->assoc);
3097 ath5k_hw_set_ledstate(sc->ah, sc->assoc ? 3287 ath5k_hw_set_ledstate(sc->ah, sc->assoc ?
@@ -3119,7 +3309,6 @@ static void ath5k_bss_info_changed(struct ieee80211_hw *hw,
3119 BSS_CHANGED_BEACON_INT)) 3309 BSS_CHANGED_BEACON_INT))
3120 ath5k_beacon_config(sc); 3310 ath5k_beacon_config(sc);
3121 3311
3122 unlock:
3123 mutex_unlock(&sc->lock); 3312 mutex_unlock(&sc->lock);
3124} 3313}
3125 3314
@@ -3394,6 +3583,8 @@ ath5k_pci_probe(struct pci_dev *pdev,
3394 hw->max_rate_tries = 11; 3583 hw->max_rate_tries = 11;
3395 } 3584 }
3396 3585
3586 hw->vif_data_size = sizeof(struct ath5k_vif);
3587
3397 /* Finish private driver data initialization */ 3588 /* Finish private driver data initialization */
3398 ret = ath5k_attach(pdev, hw); 3589 ret = ath5k_attach(pdev, hw);
3399 if (ret) 3590 if (ret)
diff --git a/drivers/net/wireless/ath/ath5k/base.h b/drivers/net/wireless/ath/ath5k/base.h
index 7f9d0d3018e..9a79773cdc2 100644
--- a/drivers/net/wireless/ath/ath5k/base.h
+++ b/drivers/net/wireless/ath/ath5k/base.h
@@ -58,8 +58,7 @@
58 58
59#define ATH_RXBUF 40 /* number of RX buffers */ 59#define ATH_RXBUF 40 /* number of RX buffers */
60#define ATH_TXBUF 200 /* number of TX buffers */ 60#define ATH_TXBUF 200 /* number of TX buffers */
61#define ATH_BCBUF 1 /* number of beacon buffers */ 61#define ATH_BCBUF 4 /* number of beacon buffers */
62
63#define ATH5K_TXQ_LEN_MAX (ATH_TXBUF / 4) /* bufs per queue */ 62#define ATH5K_TXQ_LEN_MAX (ATH_TXBUF / 4) /* bufs per queue */
64#define ATH5K_TXQ_LEN_LOW (ATH5K_TXQ_LEN_MAX / 2) /* low mark */ 63#define ATH5K_TXQ_LEN_LOW (ATH5K_TXQ_LEN_MAX / 2) /* low mark */
65 64
@@ -122,6 +121,13 @@ struct ath5k_statistics {
122 /* frame errors */ 121 /* frame errors */
123 unsigned int rx_all_count; /* all RX frames, including errors */ 122 unsigned int rx_all_count; /* all RX frames, including errors */
124 unsigned int tx_all_count; /* all TX frames, including errors */ 123 unsigned int tx_all_count; /* all TX frames, including errors */
124 unsigned int rx_bytes_count; /* all RX bytes, including errored pks
125 * and the MAC headers for each packet
126 */
127 unsigned int tx_bytes_count; /* all TX bytes, including errored pkts
128 * and the MAC headers and padding for
129 * each packet.
130 */
125 unsigned int rxerr_crc; 131 unsigned int rxerr_crc;
126 unsigned int rxerr_phy; 132 unsigned int rxerr_phy;
127 unsigned int rxerr_phy_code[32]; 133 unsigned int rxerr_phy_code[32];
@@ -152,6 +158,14 @@ struct ath5k_statistics {
152#define ATH_CHAN_MAX (14+14+14+252+20) 158#define ATH_CHAN_MAX (14+14+14+252+20)
153#endif 159#endif
154 160
161struct ath5k_vif {
162 bool assoc; /* are we associated or not */
163 enum nl80211_iftype opmode;
164 int bslot;
165 struct ath5k_buf *bbuf; /* beacon buffer */
166 u8 lladdr[ETH_ALEN];
167};
168
155/* Software Carrier, keeps track of the driver state 169/* Software Carrier, keeps track of the driver state
156 * associated with an instance of a device */ 170 * associated with an instance of a device */
157struct ath5k_softc { 171struct ath5k_softc {
@@ -188,10 +202,11 @@ struct ath5k_softc {
188 unsigned int curmode; /* current phy mode */ 202 unsigned int curmode; /* current phy mode */
189 struct ieee80211_channel *curchan; /* current h/w channel */ 203 struct ieee80211_channel *curchan; /* current h/w channel */
190 204
191 struct ieee80211_vif *vif; 205 u16 nvifs;
192 206
193 enum ath5k_int imask; /* interrupt mask copy */ 207 enum ath5k_int imask; /* interrupt mask copy */
194 208
209 u8 lladdr[ETH_ALEN];
195 u8 bssidmask[ETH_ALEN]; 210 u8 bssidmask[ETH_ALEN];
196 211
197 unsigned int led_pin, /* GPIO pin for driving LED */ 212 unsigned int led_pin, /* GPIO pin for driving LED */
@@ -219,7 +234,10 @@ struct ath5k_softc {
219 234
220 spinlock_t block; /* protects beacon */ 235 spinlock_t block; /* protects beacon */
221 struct tasklet_struct beacontq; /* beacon intr tasklet */ 236 struct tasklet_struct beacontq; /* beacon intr tasklet */
222 struct ath5k_buf *bbuf; /* beacon buffer */ 237 struct list_head bcbuf; /* beacon buffer */
238 struct ieee80211_vif *bslot[ATH_BCBUF];
239 u16 num_ap_vifs;
240 u16 num_adhoc_vifs;
223 unsigned int bhalq, /* SW q for outgoing beacons */ 241 unsigned int bhalq, /* SW q for outgoing beacons */
224 bmisscount, /* missed beacon transmits */ 242 bmisscount, /* missed beacon transmits */
225 bintval, /* beacon interval in TU */ 243 bintval, /* beacon interval in TU */
diff --git a/drivers/net/wireless/ath/ath5k/debug.c b/drivers/net/wireless/ath/ath5k/debug.c
index 0f06e849031..c2d549f871f 100644
--- a/drivers/net/wireless/ath/ath5k/debug.c
+++ b/drivers/net/wireless/ath/ath5k/debug.c
@@ -587,6 +587,8 @@ static ssize_t read_file_frameerrors(struct file *file, char __user *user_buf,
587 st->rxerr_jumbo*100/st->rx_all_count : 0); 587 st->rxerr_jumbo*100/st->rx_all_count : 0);
588 len += snprintf(buf+len, sizeof(buf)-len, "[RX all\t%d]\n", 588 len += snprintf(buf+len, sizeof(buf)-len, "[RX all\t%d]\n",
589 st->rx_all_count); 589 st->rx_all_count);
590 len += snprintf(buf+len, sizeof(buf)-len, "RX-all-bytes\t%d\n",
591 st->rx_bytes_count);
590 592
591 len += snprintf(buf+len, sizeof(buf)-len, 593 len += snprintf(buf+len, sizeof(buf)-len,
592 "\nTX\n---------------------\n"); 594 "\nTX\n---------------------\n");
@@ -604,6 +606,8 @@ static ssize_t read_file_frameerrors(struct file *file, char __user *user_buf,
604 st->txerr_filt*100/st->tx_all_count : 0); 606 st->txerr_filt*100/st->tx_all_count : 0);
605 len += snprintf(buf+len, sizeof(buf)-len, "[TX all\t%d]\n", 607 len += snprintf(buf+len, sizeof(buf)-len, "[TX all\t%d]\n",
606 st->tx_all_count); 608 st->tx_all_count);
609 len += snprintf(buf+len, sizeof(buf)-len, "TX-all-bytes\t%d\n",
610 st->tx_bytes_count);
607 611
608 if (len > sizeof(buf)) 612 if (len > sizeof(buf))
609 len = sizeof(buf); 613 len = sizeof(buf);
diff --git a/drivers/net/wireless/ath/ath5k/reset.c b/drivers/net/wireless/ath/ath5k/reset.c
index 58912cd762d..5b179d01f97 100644
--- a/drivers/net/wireless/ath/ath5k/reset.c
+++ b/drivers/net/wireless/ath/ath5k/reset.c
@@ -167,7 +167,7 @@ static inline void ath5k_hw_write_rate_duration(struct ath5k_hw *ah,
167 * ieee80211_duration() for a brief description of 167 * ieee80211_duration() for a brief description of
168 * what rate we should choose to TX ACKs. */ 168 * what rate we should choose to TX ACKs. */
169 tx_time = le16_to_cpu(ieee80211_generic_frame_duration(sc->hw, 169 tx_time = le16_to_cpu(ieee80211_generic_frame_duration(sc->hw,
170 sc->vif, 10, rate)); 170 NULL, 10, rate));
171 171
172 ath5k_hw_reg_write(ah, tx_time, reg); 172 ath5k_hw_reg_write(ah, tx_time, reg);
173 173
@@ -1060,7 +1060,7 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
1060 * XXX: rethink this after new mode changes to 1060 * XXX: rethink this after new mode changes to
1061 * mac80211 are integrated */ 1061 * mac80211 are integrated */
1062 if (ah->ah_version == AR5K_AR5212 && 1062 if (ah->ah_version == AR5K_AR5212 &&
1063 ah->ah_sc->vif != NULL) 1063 ah->ah_sc->nvifs)
1064 ath5k_hw_write_rate_duration(ah, mode); 1064 ath5k_hw_write_rate_duration(ah, mode);
1065 1065
1066 /* 1066 /*
diff --git a/drivers/net/wireless/ath/ath9k/ani.c b/drivers/net/wireless/ath/ath9k/ani.c
index 0496f965314..f2a907b4acb 100644
--- a/drivers/net/wireless/ath/ath9k/ani.c
+++ b/drivers/net/wireless/ath/ath9k/ani.c
@@ -103,31 +103,9 @@ static const struct ani_cck_level_entry cck_level_table[] = {
103#define ATH9K_ANI_CCK_DEF_LEVEL \ 103#define ATH9K_ANI_CCK_DEF_LEVEL \
104 2 /* default level - matches the INI settings */ 104 2 /* default level - matches the INI settings */
105 105
106/* Private to ani.c */ 106static bool use_new_ani(struct ath_hw *ah)
107static void ath9k_hw_ani_lower_immunity(struct ath_hw *ah)
108{
109 ath9k_hw_private_ops(ah)->ani_lower_immunity(ah);
110}
111
112int ath9k_hw_get_ani_channel_idx(struct ath_hw *ah,
113 struct ath9k_channel *chan)
114{ 107{
115 int i; 108 return AR_SREV_9300_20_OR_LATER(ah) || modparam_force_new_ani;
116
117 for (i = 0; i < ARRAY_SIZE(ah->ani); i++) {
118 if (ah->ani[i].c &&
119 ah->ani[i].c->channel == chan->channel)
120 return i;
121 if (ah->ani[i].c == NULL) {
122 ah->ani[i].c = chan;
123 return i;
124 }
125 }
126
127 ath_print(ath9k_hw_common(ah), ATH_DBG_ANI,
128 "No more channel states left. Using channel 0\n");
129
130 return 0;
131} 109}
132 110
133static void ath9k_hw_update_mibstats(struct ath_hw *ah, 111static void ath9k_hw_update_mibstats(struct ath_hw *ah,
@@ -140,82 +118,34 @@ static void ath9k_hw_update_mibstats(struct ath_hw *ah,
140 stats->beacons += REG_READ(ah, AR_BEACON_CNT); 118 stats->beacons += REG_READ(ah, AR_BEACON_CNT);
141} 119}
142 120
143static void ath9k_ani_restart_old(struct ath_hw *ah) 121static void ath9k_ani_restart(struct ath_hw *ah)
144{ 122{
145 struct ar5416AniState *aniState; 123 struct ar5416AniState *aniState;
146 struct ath_common *common = ath9k_hw_common(ah); 124 struct ath_common *common = ath9k_hw_common(ah);
125 u32 ofdm_base = 0, cck_base = 0;
147 126
148 if (!DO_ANI(ah)) 127 if (!DO_ANI(ah))
149 return; 128 return;
150 129
151 aniState = ah->curani; 130 aniState = &ah->curchan->ani;
152 aniState->listenTime = 0; 131 aniState->listenTime = 0;
153 132
154 if (aniState->ofdmTrigHigh > AR_PHY_COUNTMAX) { 133 if (!use_new_ani(ah)) {
155 aniState->ofdmPhyErrBase = 0; 134 ofdm_base = AR_PHY_COUNTMAX - ah->config.ofdm_trig_high;
156 ath_print(common, ATH_DBG_ANI, 135 cck_base = AR_PHY_COUNTMAX - ah->config.cck_trig_high;
157 "OFDM Trigger is too high for hw counters\n");
158 } else {
159 aniState->ofdmPhyErrBase =
160 AR_PHY_COUNTMAX - aniState->ofdmTrigHigh;
161 } 136 }
162 if (aniState->cckTrigHigh > AR_PHY_COUNTMAX) {
163 aniState->cckPhyErrBase = 0;
164 ath_print(common, ATH_DBG_ANI,
165 "CCK Trigger is too high for hw counters\n");
166 } else {
167 aniState->cckPhyErrBase =
168 AR_PHY_COUNTMAX - aniState->cckTrigHigh;
169 }
170 ath_print(common, ATH_DBG_ANI,
171 "Writing ofdmbase=%u cckbase=%u\n",
172 aniState->ofdmPhyErrBase,
173 aniState->cckPhyErrBase);
174
175 ENABLE_REGWRITE_BUFFER(ah);
176
177 REG_WRITE(ah, AR_PHY_ERR_1, aniState->ofdmPhyErrBase);
178 REG_WRITE(ah, AR_PHY_ERR_2, aniState->cckPhyErrBase);
179 REG_WRITE(ah, AR_PHY_ERR_MASK_1, AR_PHY_ERR_OFDM_TIMING);
180 REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING);
181
182 REGWRITE_BUFFER_FLUSH(ah);
183 DISABLE_REGWRITE_BUFFER(ah);
184
185 ath9k_hw_update_mibstats(ah, &ah->ah_mibStats);
186
187 aniState->ofdmPhyErrCount = 0;
188 aniState->cckPhyErrCount = 0;
189}
190
191static void ath9k_ani_restart_new(struct ath_hw *ah)
192{
193 struct ar5416AniState *aniState;
194 struct ath_common *common = ath9k_hw_common(ah);
195
196 if (!DO_ANI(ah))
197 return;
198
199 aniState = ah->curani;
200 aniState->listenTime = 0;
201
202 aniState->ofdmPhyErrBase = 0;
203 aniState->cckPhyErrBase = 0;
204 137
205 ath_print(common, ATH_DBG_ANI, 138 ath_print(common, ATH_DBG_ANI,
206 "Writing ofdmbase=%08x cckbase=%08x\n", 139 "Writing ofdmbase=%u cckbase=%u\n", ofdm_base, cck_base);
207 aniState->ofdmPhyErrBase,
208 aniState->cckPhyErrBase);
209 140
210 ENABLE_REGWRITE_BUFFER(ah); 141 ENABLE_REGWRITE_BUFFER(ah);
211 142
212 REG_WRITE(ah, AR_PHY_ERR_1, aniState->ofdmPhyErrBase); 143 REG_WRITE(ah, AR_PHY_ERR_1, ofdm_base);
213 REG_WRITE(ah, AR_PHY_ERR_2, aniState->cckPhyErrBase); 144 REG_WRITE(ah, AR_PHY_ERR_2, cck_base);
214 REG_WRITE(ah, AR_PHY_ERR_MASK_1, AR_PHY_ERR_OFDM_TIMING); 145 REG_WRITE(ah, AR_PHY_ERR_MASK_1, AR_PHY_ERR_OFDM_TIMING);
215 REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING); 146 REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING);
216 147
217 REGWRITE_BUFFER_FLUSH(ah); 148 REGWRITE_BUFFER_FLUSH(ah);
218 DISABLE_REGWRITE_BUFFER(ah);
219 149
220 ath9k_hw_update_mibstats(ah, &ah->ah_mibStats); 150 ath9k_hw_update_mibstats(ah, &ah->ah_mibStats);
221 151
@@ -229,10 +159,7 @@ static void ath9k_hw_ani_ofdm_err_trigger_old(struct ath_hw *ah)
229 struct ar5416AniState *aniState; 159 struct ar5416AniState *aniState;
230 int32_t rssi; 160 int32_t rssi;
231 161
232 if (!DO_ANI(ah)) 162 aniState = &ah->curchan->ani;
233 return;
234
235 aniState = ah->curani;
236 163
237 if (aniState->noiseImmunityLevel < HAL_NOISE_IMMUNE_MAX) { 164 if (aniState->noiseImmunityLevel < HAL_NOISE_IMMUNE_MAX) {
238 if (ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL, 165 if (ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL,
@@ -301,10 +228,7 @@ static void ath9k_hw_ani_cck_err_trigger_old(struct ath_hw *ah)
301 struct ar5416AniState *aniState; 228 struct ar5416AniState *aniState;
302 int32_t rssi; 229 int32_t rssi;
303 230
304 if (!DO_ANI(ah)) 231 aniState = &ah->curchan->ani;
305 return;
306
307 aniState = ah->curani;
308 if (aniState->noiseImmunityLevel < HAL_NOISE_IMMUNE_MAX) { 232 if (aniState->noiseImmunityLevel < HAL_NOISE_IMMUNE_MAX) {
309 if (ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL, 233 if (ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL,
310 aniState->noiseImmunityLevel + 1)) { 234 aniState->noiseImmunityLevel + 1)) {
@@ -336,7 +260,7 @@ static void ath9k_hw_ani_cck_err_trigger_old(struct ath_hw *ah)
336/* Adjust the OFDM Noise Immunity Level */ 260/* Adjust the OFDM Noise Immunity Level */
337static void ath9k_hw_set_ofdm_nil(struct ath_hw *ah, u8 immunityLevel) 261static void ath9k_hw_set_ofdm_nil(struct ath_hw *ah, u8 immunityLevel)
338{ 262{
339 struct ar5416AniState *aniState = ah->curani; 263 struct ar5416AniState *aniState = &ah->curchan->ani;
340 struct ath_common *common = ath9k_hw_common(ah); 264 struct ath_common *common = ath9k_hw_common(ah);
341 const struct ani_ofdm_level_entry *entry_ofdm; 265 const struct ani_ofdm_level_entry *entry_ofdm;
342 const struct ani_cck_level_entry *entry_cck; 266 const struct ani_cck_level_entry *entry_cck;
@@ -381,14 +305,19 @@ static void ath9k_hw_set_ofdm_nil(struct ath_hw *ah, u8 immunityLevel)
381 } 305 }
382} 306}
383 307
384static void ath9k_hw_ani_ofdm_err_trigger_new(struct ath_hw *ah) 308static void ath9k_hw_ani_ofdm_err_trigger(struct ath_hw *ah)
385{ 309{
386 struct ar5416AniState *aniState; 310 struct ar5416AniState *aniState;
387 311
388 if (!DO_ANI(ah)) 312 if (!DO_ANI(ah))
389 return; 313 return;
390 314
391 aniState = ah->curani; 315 if (!use_new_ani(ah)) {
316 ath9k_hw_ani_ofdm_err_trigger_old(ah);
317 return;
318 }
319
320 aniState = &ah->curchan->ani;
392 321
393 if (aniState->ofdmNoiseImmunityLevel < ATH9K_ANI_OFDM_MAX_LEVEL) 322 if (aniState->ofdmNoiseImmunityLevel < ATH9K_ANI_OFDM_MAX_LEVEL)
394 ath9k_hw_set_ofdm_nil(ah, aniState->ofdmNoiseImmunityLevel + 1); 323 ath9k_hw_set_ofdm_nil(ah, aniState->ofdmNoiseImmunityLevel + 1);
@@ -399,7 +328,7 @@ static void ath9k_hw_ani_ofdm_err_trigger_new(struct ath_hw *ah)
399 */ 328 */
400static void ath9k_hw_set_cck_nil(struct ath_hw *ah, u_int8_t immunityLevel) 329static void ath9k_hw_set_cck_nil(struct ath_hw *ah, u_int8_t immunityLevel)
401{ 330{
402 struct ar5416AniState *aniState = ah->curani; 331 struct ar5416AniState *aniState = &ah->curchan->ani;
403 struct ath_common *common = ath9k_hw_common(ah); 332 struct ath_common *common = ath9k_hw_common(ah);
404 const struct ani_ofdm_level_entry *entry_ofdm; 333 const struct ani_ofdm_level_entry *entry_ofdm;
405 const struct ani_cck_level_entry *entry_cck; 334 const struct ani_cck_level_entry *entry_cck;
@@ -438,14 +367,19 @@ static void ath9k_hw_set_cck_nil(struct ath_hw *ah, u_int8_t immunityLevel)
438 entry_cck->mrc_cck_on); 367 entry_cck->mrc_cck_on);
439} 368}
440 369
441static void ath9k_hw_ani_cck_err_trigger_new(struct ath_hw *ah) 370static void ath9k_hw_ani_cck_err_trigger(struct ath_hw *ah)
442{ 371{
443 struct ar5416AniState *aniState; 372 struct ar5416AniState *aniState;
444 373
445 if (!DO_ANI(ah)) 374 if (!DO_ANI(ah))
446 return; 375 return;
447 376
448 aniState = ah->curani; 377 if (!use_new_ani(ah)) {
378 ath9k_hw_ani_cck_err_trigger_old(ah);
379 return;
380 }
381
382 aniState = &ah->curchan->ani;
449 383
450 if (aniState->cckNoiseImmunityLevel < ATH9K_ANI_CCK_MAX_LEVEL) 384 if (aniState->cckNoiseImmunityLevel < ATH9K_ANI_CCK_MAX_LEVEL)
451 ath9k_hw_set_cck_nil(ah, aniState->cckNoiseImmunityLevel + 1); 385 ath9k_hw_set_cck_nil(ah, aniState->cckNoiseImmunityLevel + 1);
@@ -456,7 +390,7 @@ static void ath9k_hw_ani_lower_immunity_old(struct ath_hw *ah)
456 struct ar5416AniState *aniState; 390 struct ar5416AniState *aniState;
457 int32_t rssi; 391 int32_t rssi;
458 392
459 aniState = ah->curani; 393 aniState = &ah->curchan->ani;
460 394
461 if (ah->opmode == NL80211_IFTYPE_AP) { 395 if (ah->opmode == NL80211_IFTYPE_AP) {
462 if (aniState->firstepLevel > 0) { 396 if (aniState->firstepLevel > 0) {
@@ -508,11 +442,16 @@ static void ath9k_hw_ani_lower_immunity_old(struct ath_hw *ah)
508 * only lower either OFDM or CCK errors per turn 442 * only lower either OFDM or CCK errors per turn
509 * we lower the other one next time 443 * we lower the other one next time
510 */ 444 */
511static void ath9k_hw_ani_lower_immunity_new(struct ath_hw *ah) 445static void ath9k_hw_ani_lower_immunity(struct ath_hw *ah)
512{ 446{
513 struct ar5416AniState *aniState; 447 struct ar5416AniState *aniState;
514 448
515 aniState = ah->curani; 449 aniState = &ah->curchan->ani;
450
451 if (!use_new_ani(ah)) {
452 ath9k_hw_ani_lower_immunity_old(ah);
453 return;
454 }
516 455
517 /* lower OFDM noise immunity */ 456 /* lower OFDM noise immunity */
518 if (aniState->ofdmNoiseImmunityLevel > 0 && 457 if (aniState->ofdmNoiseImmunityLevel > 0 &&
@@ -544,52 +483,20 @@ static u8 ath9k_hw_chan_2_clockrate_mhz(struct ath_hw *ah)
544 if (conf_is_ht40(conf)) 483 if (conf_is_ht40(conf))
545 return clockrate * 2; 484 return clockrate * 2;
546 485
547 return clockrate * 2; 486 return clockrate;
548} 487}
549 488
550static int32_t ath9k_hw_ani_get_listen_time(struct ath_hw *ah) 489static int32_t ath9k_hw_ani_get_listen_time(struct ath_hw *ah)
551{ 490{
552 struct ar5416AniState *aniState; 491 int32_t listen_time;
553 struct ath_common *common = ath9k_hw_common(ah); 492 int32_t clock_rate;
554 u32 txFrameCount, rxFrameCount, cycleCount;
555 int32_t listenTime;
556
557 txFrameCount = REG_READ(ah, AR_TFCNT);
558 rxFrameCount = REG_READ(ah, AR_RFCNT);
559 cycleCount = REG_READ(ah, AR_CCCNT);
560
561 aniState = ah->curani;
562 if (aniState->cycleCount == 0 || aniState->cycleCount > cycleCount) {
563 listenTime = 0;
564 ah->stats.ast_ani_lzero++;
565 ath_print(common, ATH_DBG_ANI,
566 "1st call: aniState->cycleCount=%d\n",
567 aniState->cycleCount);
568 } else {
569 int32_t ccdelta = cycleCount - aniState->cycleCount;
570 int32_t rfdelta = rxFrameCount - aniState->rxFrameCount;
571 int32_t tfdelta = txFrameCount - aniState->txFrameCount;
572 int32_t clock_rate;
573 493
574 /* 494 ath9k_hw_update_cycle_counters(ah);
575 * convert HW counter values to ms using mode 495 clock_rate = ath9k_hw_chan_2_clockrate_mhz(ah) * 1000;
576 * specifix clock rate 496 listen_time = ah->listen_time / clock_rate;
577 */ 497 ah->listen_time = 0;
578 clock_rate = ath9k_hw_chan_2_clockrate_mhz(ah) * 1000;;
579 498
580 listenTime = (ccdelta - rfdelta - tfdelta) / clock_rate; 499 return listen_time;
581
582 ath_print(common, ATH_DBG_ANI,
583 "cyclecount=%d, rfcount=%d, "
584 "tfcount=%d, listenTime=%d CLOCK_RATE=%d\n",
585 ccdelta, rfdelta, tfdelta, listenTime, clock_rate);
586 }
587
588 aniState->cycleCount = cycleCount;
589 aniState->txFrameCount = txFrameCount;
590 aniState->rxFrameCount = rxFrameCount;
591
592 return listenTime;
593} 500}
594 501
595static void ath9k_ani_reset_old(struct ath_hw *ah, bool is_scanning) 502static void ath9k_ani_reset_old(struct ath_hw *ah, bool is_scanning)
@@ -597,16 +504,13 @@ static void ath9k_ani_reset_old(struct ath_hw *ah, bool is_scanning)
597 struct ar5416AniState *aniState; 504 struct ar5416AniState *aniState;
598 struct ath9k_channel *chan = ah->curchan; 505 struct ath9k_channel *chan = ah->curchan;
599 struct ath_common *common = ath9k_hw_common(ah); 506 struct ath_common *common = ath9k_hw_common(ah);
600 int index;
601 507
602 if (!DO_ANI(ah)) 508 if (!DO_ANI(ah))
603 return; 509 return;
604 510
605 index = ath9k_hw_get_ani_channel_idx(ah, chan); 511 aniState = &ah->curchan->ani;
606 aniState = &ah->ani[index];
607 ah->curani = aniState;
608 512
609 if (DO_ANI(ah) && ah->opmode != NL80211_IFTYPE_STATION 513 if (ah->opmode != NL80211_IFTYPE_STATION
610 && ah->opmode != NL80211_IFTYPE_ADHOC) { 514 && ah->opmode != NL80211_IFTYPE_ADHOC) {
611 ath_print(common, ATH_DBG_ANI, 515 ath_print(common, ATH_DBG_ANI,
612 "Reset ANI state opmode %u\n", ah->opmode); 516 "Reset ANI state opmode %u\n", ah->opmode);
@@ -635,17 +539,7 @@ static void ath9k_ani_reset_old(struct ath_hw *ah, bool is_scanning)
635 ath9k_hw_setrxfilter(ah, ath9k_hw_getrxfilter(ah) | 539 ath9k_hw_setrxfilter(ah, ath9k_hw_getrxfilter(ah) |
636 ATH9K_RX_FILTER_PHYERR); 540 ATH9K_RX_FILTER_PHYERR);
637 541
638 if (ah->opmode == NL80211_IFTYPE_AP) { 542 ath9k_ani_restart(ah);
639 ah->curani->ofdmTrigHigh =
640 ah->config.ofdm_trig_high;
641 ah->curani->ofdmTrigLow =
642 ah->config.ofdm_trig_low;
643 ah->curani->cckTrigHigh =
644 ah->config.cck_trig_high;
645 ah->curani->cckTrigLow =
646 ah->config.cck_trig_low;
647 }
648 ath9k_ani_restart_old(ah);
649 return; 543 return;
650 } 544 }
651 545
@@ -667,7 +561,7 @@ static void ath9k_ani_reset_old(struct ath_hw *ah, bool is_scanning)
667 561
668 ath9k_hw_setrxfilter(ah, ath9k_hw_getrxfilter(ah) & 562 ath9k_hw_setrxfilter(ah, ath9k_hw_getrxfilter(ah) &
669 ~ATH9K_RX_FILTER_PHYERR); 563 ~ATH9K_RX_FILTER_PHYERR);
670 ath9k_ani_restart_old(ah); 564 ath9k_ani_restart(ah);
671 565
672 ENABLE_REGWRITE_BUFFER(ah); 566 ENABLE_REGWRITE_BUFFER(ah);
673 567
@@ -675,7 +569,6 @@ static void ath9k_ani_reset_old(struct ath_hw *ah, bool is_scanning)
675 REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING); 569 REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING);
676 570
677 REGWRITE_BUFFER_FLUSH(ah); 571 REGWRITE_BUFFER_FLUSH(ah);
678 DISABLE_REGWRITE_BUFFER(ah);
679} 572}
680 573
681/* 574/*
@@ -683,15 +576,18 @@ static void ath9k_ani_reset_old(struct ath_hw *ah, bool is_scanning)
683 * This routine should be called for every hardware reset and for 576 * This routine should be called for every hardware reset and for
684 * every channel change. 577 * every channel change.
685 */ 578 */
686static void ath9k_ani_reset_new(struct ath_hw *ah, bool is_scanning) 579void ath9k_ani_reset(struct ath_hw *ah, bool is_scanning)
687{ 580{
688 struct ar5416AniState *aniState = ah->curani; 581 struct ar5416AniState *aniState = &ah->curchan->ani;
689 struct ath9k_channel *chan = ah->curchan; 582 struct ath9k_channel *chan = ah->curchan;
690 struct ath_common *common = ath9k_hw_common(ah); 583 struct ath_common *common = ath9k_hw_common(ah);
691 584
692 if (!DO_ANI(ah)) 585 if (!DO_ANI(ah))
693 return; 586 return;
694 587
588 if (!use_new_ani(ah))
589 return ath9k_ani_reset_old(ah, is_scanning);
590
695 BUG_ON(aniState == NULL); 591 BUG_ON(aniState == NULL);
696 ah->stats.ast_ani_reset++; 592 ah->stats.ast_ani_reset++;
697 593
@@ -761,7 +657,7 @@ static void ath9k_ani_reset_new(struct ath_hw *ah, bool is_scanning)
761 * enable phy counters if hw supports or if not, enable phy 657 * enable phy counters if hw supports or if not, enable phy
762 * interrupts (so we can count each one) 658 * interrupts (so we can count each one)
763 */ 659 */
764 ath9k_ani_restart_new(ah); 660 ath9k_ani_restart(ah);
765 661
766 ENABLE_REGWRITE_BUFFER(ah); 662 ENABLE_REGWRITE_BUFFER(ah);
767 663
@@ -769,30 +665,30 @@ static void ath9k_ani_reset_new(struct ath_hw *ah, bool is_scanning)
769 REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING); 665 REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING);
770 666
771 REGWRITE_BUFFER_FLUSH(ah); 667 REGWRITE_BUFFER_FLUSH(ah);
772 DISABLE_REGWRITE_BUFFER(ah);
773} 668}
774 669
775static void ath9k_hw_ani_monitor_old(struct ath_hw *ah, 670static void ath9k_hw_ani_read_counters(struct ath_hw *ah)
776 struct ath9k_channel *chan)
777{ 671{
778 struct ar5416AniState *aniState;
779 struct ath_common *common = ath9k_hw_common(ah); 672 struct ath_common *common = ath9k_hw_common(ah);
780 int32_t listenTime; 673 struct ar5416AniState *aniState = &ah->curchan->ani;
781 u32 phyCnt1, phyCnt2; 674 u32 ofdm_base = 0;
675 u32 cck_base = 0;
782 u32 ofdmPhyErrCnt, cckPhyErrCnt; 676 u32 ofdmPhyErrCnt, cckPhyErrCnt;
783 677 u32 phyCnt1, phyCnt2;
784 if (!DO_ANI(ah)) 678 int32_t listenTime;
785 return;
786
787 aniState = ah->curani;
788 679
789 listenTime = ath9k_hw_ani_get_listen_time(ah); 680 listenTime = ath9k_hw_ani_get_listen_time(ah);
790 if (listenTime < 0) { 681 if (listenTime < 0) {
791 ah->stats.ast_ani_lneg++; 682 ah->stats.ast_ani_lneg++;
792 ath9k_ani_restart_old(ah); 683 ath9k_ani_restart(ah);
793 return; 684 return;
794 } 685 }
795 686
687 if (!use_new_ani(ah)) {
688 ofdm_base = AR_PHY_COUNTMAX - ah->config.ofdm_trig_high;
689 cck_base = AR_PHY_COUNTMAX - ah->config.cck_trig_high;
690 }
691
796 aniState->listenTime += listenTime; 692 aniState->listenTime += listenTime;
797 693
798 ath9k_hw_update_mibstats(ah, &ah->ah_mibStats); 694 ath9k_hw_update_mibstats(ah, &ah->ah_mibStats);
@@ -800,145 +696,54 @@ static void ath9k_hw_ani_monitor_old(struct ath_hw *ah,
800 phyCnt1 = REG_READ(ah, AR_PHY_ERR_1); 696 phyCnt1 = REG_READ(ah, AR_PHY_ERR_1);
801 phyCnt2 = REG_READ(ah, AR_PHY_ERR_2); 697 phyCnt2 = REG_READ(ah, AR_PHY_ERR_2);
802 698
803 if (phyCnt1 < aniState->ofdmPhyErrBase || 699 if (use_new_ani(ah) && (phyCnt1 < ofdm_base || phyCnt2 < cck_base)) {
804 phyCnt2 < aniState->cckPhyErrBase) { 700 if (phyCnt1 < ofdm_base) {
805 if (phyCnt1 < aniState->ofdmPhyErrBase) {
806 ath_print(common, ATH_DBG_ANI, 701 ath_print(common, ATH_DBG_ANI,
807 "phyCnt1 0x%x, resetting " 702 "phyCnt1 0x%x, resetting "
808 "counter value to 0x%x\n", 703 "counter value to 0x%x\n",
809 phyCnt1, 704 phyCnt1, ofdm_base);
810 aniState->ofdmPhyErrBase); 705 REG_WRITE(ah, AR_PHY_ERR_1, ofdm_base);
811 REG_WRITE(ah, AR_PHY_ERR_1,
812 aniState->ofdmPhyErrBase);
813 REG_WRITE(ah, AR_PHY_ERR_MASK_1, 706 REG_WRITE(ah, AR_PHY_ERR_MASK_1,
814 AR_PHY_ERR_OFDM_TIMING); 707 AR_PHY_ERR_OFDM_TIMING);
815 } 708 }
816 if (phyCnt2 < aniState->cckPhyErrBase) { 709 if (phyCnt2 < cck_base) {
817 ath_print(common, ATH_DBG_ANI, 710 ath_print(common, ATH_DBG_ANI,
818 "phyCnt2 0x%x, resetting " 711 "phyCnt2 0x%x, resetting "
819 "counter value to 0x%x\n", 712 "counter value to 0x%x\n",
820 phyCnt2, 713 phyCnt2, cck_base);
821 aniState->cckPhyErrBase); 714 REG_WRITE(ah, AR_PHY_ERR_2, cck_base);
822 REG_WRITE(ah, AR_PHY_ERR_2,
823 aniState->cckPhyErrBase);
824 REG_WRITE(ah, AR_PHY_ERR_MASK_2, 715 REG_WRITE(ah, AR_PHY_ERR_MASK_2,
825 AR_PHY_ERR_CCK_TIMING); 716 AR_PHY_ERR_CCK_TIMING);
826 } 717 }
827 return; 718 return;
828 } 719 }
829 720
830 ofdmPhyErrCnt = phyCnt1 - aniState->ofdmPhyErrBase; 721 ofdmPhyErrCnt = phyCnt1 - ofdm_base;
831 ah->stats.ast_ani_ofdmerrs += 722 ah->stats.ast_ani_ofdmerrs +=
832 ofdmPhyErrCnt - aniState->ofdmPhyErrCount; 723 ofdmPhyErrCnt - aniState->ofdmPhyErrCount;
833 aniState->ofdmPhyErrCount = ofdmPhyErrCnt; 724 aniState->ofdmPhyErrCount = ofdmPhyErrCnt;
834 725
835 cckPhyErrCnt = phyCnt2 - aniState->cckPhyErrBase; 726 cckPhyErrCnt = phyCnt2 - cck_base;
836 ah->stats.ast_ani_cckerrs += 727 ah->stats.ast_ani_cckerrs +=
837 cckPhyErrCnt - aniState->cckPhyErrCount; 728 cckPhyErrCnt - aniState->cckPhyErrCount;
838 aniState->cckPhyErrCount = cckPhyErrCnt; 729 aniState->cckPhyErrCount = cckPhyErrCnt;
839 730
840 if (aniState->listenTime > 5 * ah->aniperiod) {
841 if (aniState->ofdmPhyErrCount <= aniState->listenTime *
842 aniState->ofdmTrigLow / 1000 &&
843 aniState->cckPhyErrCount <= aniState->listenTime *
844 aniState->cckTrigLow / 1000)
845 ath9k_hw_ani_lower_immunity(ah);
846 ath9k_ani_restart_old(ah);
847 } else if (aniState->listenTime > ah->aniperiod) {
848 if (aniState->ofdmPhyErrCount > aniState->listenTime *
849 aniState->ofdmTrigHigh / 1000) {
850 ath9k_hw_ani_ofdm_err_trigger_old(ah);
851 ath9k_ani_restart_old(ah);
852 } else if (aniState->cckPhyErrCount >
853 aniState->listenTime * aniState->cckTrigHigh /
854 1000) {
855 ath9k_hw_ani_cck_err_trigger_old(ah);
856 ath9k_ani_restart_old(ah);
857 }
858 }
859} 731}
860 732
861static void ath9k_hw_ani_monitor_new(struct ath_hw *ah, 733void ath9k_hw_ani_monitor(struct ath_hw *ah, struct ath9k_channel *chan)
862 struct ath9k_channel *chan)
863{ 734{
864 struct ar5416AniState *aniState; 735 struct ar5416AniState *aniState;
865 struct ath_common *common = ath9k_hw_common(ah); 736 struct ath_common *common = ath9k_hw_common(ah);
866 int32_t listenTime;
867 u32 phyCnt1, phyCnt2;
868 u32 ofdmPhyErrCnt, cckPhyErrCnt;
869 u32 ofdmPhyErrRate, cckPhyErrRate; 737 u32 ofdmPhyErrRate, cckPhyErrRate;
870 738
871 if (!DO_ANI(ah)) 739 if (!DO_ANI(ah))
872 return; 740 return;
873 741
874 aniState = ah->curani; 742 aniState = &ah->curchan->ani;
875 if (WARN_ON(!aniState)) 743 if (WARN_ON(!aniState))
876 return; 744 return;
877 745
878 listenTime = ath9k_hw_ani_get_listen_time(ah); 746 ath9k_hw_ani_read_counters(ah);
879 if (listenTime <= 0) {
880 ah->stats.ast_ani_lneg++;
881 /* restart ANI period if listenTime is invalid */
882 ath_print(common, ATH_DBG_ANI,
883 "listenTime=%d - on new ani monitor\n",
884 listenTime);
885 ath9k_ani_restart_new(ah);
886 return;
887 }
888
889 aniState->listenTime += listenTime;
890
891 ath9k_hw_update_mibstats(ah, &ah->ah_mibStats);
892
893 phyCnt1 = REG_READ(ah, AR_PHY_ERR_1);
894 phyCnt2 = REG_READ(ah, AR_PHY_ERR_2);
895
896 if (phyCnt1 < aniState->ofdmPhyErrBase ||
897 phyCnt2 < aniState->cckPhyErrBase) {
898 if (phyCnt1 < aniState->ofdmPhyErrBase) {
899 ath_print(common, ATH_DBG_ANI,
900 "phyCnt1 0x%x, resetting "
901 "counter value to 0x%x\n",
902 phyCnt1,
903 aniState->ofdmPhyErrBase);
904 REG_WRITE(ah, AR_PHY_ERR_1,
905 aniState->ofdmPhyErrBase);
906 REG_WRITE(ah, AR_PHY_ERR_MASK_1,
907 AR_PHY_ERR_OFDM_TIMING);
908 }
909 if (phyCnt2 < aniState->cckPhyErrBase) {
910 ath_print(common, ATH_DBG_ANI,
911 "phyCnt2 0x%x, resetting "
912 "counter value to 0x%x\n",
913 phyCnt2,
914 aniState->cckPhyErrBase);
915 REG_WRITE(ah, AR_PHY_ERR_2,
916 aniState->cckPhyErrBase);
917 REG_WRITE(ah, AR_PHY_ERR_MASK_2,
918 AR_PHY_ERR_CCK_TIMING);
919 }
920 return;
921 }
922
923 ofdmPhyErrCnt = phyCnt1 - aniState->ofdmPhyErrBase;
924 ah->stats.ast_ani_ofdmerrs +=
925 ofdmPhyErrCnt - aniState->ofdmPhyErrCount;
926 aniState->ofdmPhyErrCount = ofdmPhyErrCnt;
927
928 cckPhyErrCnt = phyCnt2 - aniState->cckPhyErrBase;
929 ah->stats.ast_ani_cckerrs +=
930 cckPhyErrCnt - aniState->cckPhyErrCount;
931 aniState->cckPhyErrCount = cckPhyErrCnt;
932
933 ath_print(common, ATH_DBG_ANI,
934 "Errors: OFDM=0x%08x-0x%08x=%d "
935 "CCK=0x%08x-0x%08x=%d\n",
936 phyCnt1,
937 aniState->ofdmPhyErrBase,
938 ofdmPhyErrCnt,
939 phyCnt2,
940 aniState->cckPhyErrBase,
941 cckPhyErrCnt);
942 747
943 ofdmPhyErrRate = aniState->ofdmPhyErrCount * 1000 / 748 ofdmPhyErrRate = aniState->ofdmPhyErrCount * 1000 /
944 aniState->listenTime; 749 aniState->listenTime;
@@ -948,61 +753,34 @@ static void ath9k_hw_ani_monitor_new(struct ath_hw *ah,
948 ath_print(common, ATH_DBG_ANI, 753 ath_print(common, ATH_DBG_ANI,
949 "listenTime=%d OFDM:%d errs=%d/s CCK:%d " 754 "listenTime=%d OFDM:%d errs=%d/s CCK:%d "
950 "errs=%d/s ofdm_turn=%d\n", 755 "errs=%d/s ofdm_turn=%d\n",
951 listenTime, aniState->ofdmNoiseImmunityLevel, 756 aniState->listenTime,
757 aniState->ofdmNoiseImmunityLevel,
952 ofdmPhyErrRate, aniState->cckNoiseImmunityLevel, 758 ofdmPhyErrRate, aniState->cckNoiseImmunityLevel,
953 cckPhyErrRate, aniState->ofdmsTurn); 759 cckPhyErrRate, aniState->ofdmsTurn);
954 760
955 if (aniState->listenTime > 5 * ah->aniperiod) { 761 if (aniState->listenTime > 5 * ah->aniperiod) {
956 if (ofdmPhyErrRate <= aniState->ofdmTrigLow && 762 if (ofdmPhyErrRate <= ah->config.ofdm_trig_low &&
957 cckPhyErrRate <= aniState->cckTrigLow) { 763 cckPhyErrRate <= ah->config.cck_trig_low) {
958 ath_print(common, ATH_DBG_ANI,
959 "1. listenTime=%d OFDM:%d errs=%d/s(<%d) "
960 "CCK:%d errs=%d/s(<%d) -> "
961 "ath9k_hw_ani_lower_immunity()\n",
962 aniState->listenTime,
963 aniState->ofdmNoiseImmunityLevel,
964 ofdmPhyErrRate,
965 aniState->ofdmTrigLow,
966 aniState->cckNoiseImmunityLevel,
967 cckPhyErrRate,
968 aniState->cckTrigLow);
969 ath9k_hw_ani_lower_immunity(ah); 764 ath9k_hw_ani_lower_immunity(ah);
970 aniState->ofdmsTurn = !aniState->ofdmsTurn; 765 aniState->ofdmsTurn = !aniState->ofdmsTurn;
971 } 766 }
972 ath_print(common, ATH_DBG_ANI, 767 ath9k_ani_restart(ah);
973 "1 listenTime=%d ofdm=%d/s cck=%d/s - "
974 "calling ath9k_ani_restart_new()\n",
975 aniState->listenTime, ofdmPhyErrRate, cckPhyErrRate);
976 ath9k_ani_restart_new(ah);
977 } else if (aniState->listenTime > ah->aniperiod) { 768 } else if (aniState->listenTime > ah->aniperiod) {
978 /* check to see if need to raise immunity */ 769 /* check to see if need to raise immunity */
979 if (ofdmPhyErrRate > aniState->ofdmTrigHigh && 770 if (ofdmPhyErrRate > ah->config.ofdm_trig_high &&
980 (cckPhyErrRate <= aniState->cckTrigHigh || 771 (cckPhyErrRate <= ah->config.cck_trig_high ||
981 aniState->ofdmsTurn)) { 772 aniState->ofdmsTurn)) {
982 ath_print(common, ATH_DBG_ANI, 773 ath9k_hw_ani_ofdm_err_trigger(ah);
983 "2 listenTime=%d OFDM:%d errs=%d/s(>%d) -> " 774 ath9k_ani_restart(ah);
984 "ath9k_hw_ani_ofdm_err_trigger_new()\n",
985 aniState->listenTime,
986 aniState->ofdmNoiseImmunityLevel,
987 ofdmPhyErrRate,
988 aniState->ofdmTrigHigh);
989 ath9k_hw_ani_ofdm_err_trigger_new(ah);
990 ath9k_ani_restart_new(ah);
991 aniState->ofdmsTurn = false; 775 aniState->ofdmsTurn = false;
992 } else if (cckPhyErrRate > aniState->cckTrigHigh) { 776 } else if (cckPhyErrRate > ah->config.cck_trig_high) {
993 ath_print(common, ATH_DBG_ANI, 777 ath9k_hw_ani_cck_err_trigger(ah);
994 "3 listenTime=%d CCK:%d errs=%d/s(>%d) -> " 778 ath9k_ani_restart(ah);
995 "ath9k_hw_ani_cck_err_trigger_new()\n",
996 aniState->listenTime,
997 aniState->cckNoiseImmunityLevel,
998 cckPhyErrRate,
999 aniState->cckTrigHigh);
1000 ath9k_hw_ani_cck_err_trigger_new(ah);
1001 ath9k_ani_restart_new(ah);
1002 aniState->ofdmsTurn = true; 779 aniState->ofdmsTurn = true;
1003 } 780 }
1004 } 781 }
1005} 782}
783EXPORT_SYMBOL(ath9k_hw_ani_monitor);
1006 784
1007void ath9k_enable_mib_counters(struct ath_hw *ah) 785void ath9k_enable_mib_counters(struct ath_hw *ah)
1008{ 786{
@@ -1023,7 +801,6 @@ void ath9k_enable_mib_counters(struct ath_hw *ah)
1023 REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING); 801 REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING);
1024 802
1025 REGWRITE_BUFFER_FLUSH(ah); 803 REGWRITE_BUFFER_FLUSH(ah);
1026 DISABLE_REGWRITE_BUFFER(ah);
1027} 804}
1028 805
1029/* Freeze the MIB counters, get the stats and then clear them */ 806/* Freeze the MIB counters, get the stats and then clear them */
@@ -1041,107 +818,52 @@ void ath9k_hw_disable_mib_counters(struct ath_hw *ah)
1041} 818}
1042EXPORT_SYMBOL(ath9k_hw_disable_mib_counters); 819EXPORT_SYMBOL(ath9k_hw_disable_mib_counters);
1043 820
1044u32 ath9k_hw_GetMibCycleCountsPct(struct ath_hw *ah, 821void ath9k_hw_update_cycle_counters(struct ath_hw *ah)
1045 u32 *rxc_pcnt,
1046 u32 *rxf_pcnt,
1047 u32 *txf_pcnt)
1048{ 822{
1049 struct ath_common *common = ath9k_hw_common(ah); 823 struct ath_cycle_counters cc;
1050 static u32 cycles, rx_clear, rx_frame, tx_frame; 824 bool clear;
1051 u32 good = 1;
1052 825
1053 u32 rc = REG_READ(ah, AR_RCCNT); 826 memcpy(&cc, &ah->cc, sizeof(cc));
1054 u32 rf = REG_READ(ah, AR_RFCNT);
1055 u32 tf = REG_READ(ah, AR_TFCNT);
1056 u32 cc = REG_READ(ah, AR_CCCNT);
1057 827
1058 if (cycles == 0 || cycles > cc) { 828 /* freeze counters */
1059 ath_print(common, ATH_DBG_ANI, 829 REG_WRITE(ah, AR_MIBC, AR_MIBC_FMC);
1060 "cycle counter wrap. ExtBusy = 0\n");
1061 good = 0;
1062 } else {
1063 u32 cc_d = cc - cycles;
1064 u32 rc_d = rc - rx_clear;
1065 u32 rf_d = rf - rx_frame;
1066 u32 tf_d = tf - tx_frame;
1067
1068 if (cc_d != 0) {
1069 *rxc_pcnt = rc_d * 100 / cc_d;
1070 *rxf_pcnt = rf_d * 100 / cc_d;
1071 *txf_pcnt = tf_d * 100 / cc_d;
1072 } else {
1073 good = 0;
1074 }
1075 }
1076 830
1077 cycles = cc; 831 ah->cc.cycles = REG_READ(ah, AR_CCCNT);
1078 rx_frame = rf; 832 if (ah->cc.cycles < cc.cycles) {
1079 rx_clear = rc; 833 clear = true;
1080 tx_frame = tf; 834 goto skip;
835 }
1081 836
1082 return good; 837 ah->cc.rx_clear = REG_READ(ah, AR_RCCNT);
1083} 838 ah->cc.rx_frame = REG_READ(ah, AR_RFCNT);
839 ah->cc.tx_frame = REG_READ(ah, AR_TFCNT);
1084 840
1085/* 841 /* prevent wraparound */
1086 * Process a MIB interrupt. We may potentially be invoked because 842 if (ah->cc.cycles & BIT(31))
1087 * any of the MIB counters overflow/trigger so don't assume we're 843 clear = true;
1088 * here because a PHY error counter triggered.
1089 */
1090static void ath9k_hw_proc_mib_event_old(struct ath_hw *ah)
1091{
1092 u32 phyCnt1, phyCnt2;
1093 844
1094 /* Reset these counters regardless */ 845#define CC_DELTA(_field, _reg) ah->cc_delta._field += ah->cc._field - cc._field
1095 REG_WRITE(ah, AR_FILT_OFDM, 0); 846 CC_DELTA(cycles, AR_CCCNT);
1096 REG_WRITE(ah, AR_FILT_CCK, 0); 847 CC_DELTA(rx_frame, AR_RFCNT);
1097 if (!(REG_READ(ah, AR_SLP_MIB_CTRL) & AR_SLP_MIB_PENDING)) 848 CC_DELTA(rx_clear, AR_RCCNT);
1098 REG_WRITE(ah, AR_SLP_MIB_CTRL, AR_SLP_MIB_CLEAR); 849 CC_DELTA(tx_frame, AR_TFCNT);
850#undef CC_DELTA
1099 851
1100 /* Clear the mib counters and save them in the stats */ 852 ah->listen_time += (ah->cc.cycles - cc.cycles) -
1101 ath9k_hw_update_mibstats(ah, &ah->ah_mibStats); 853 ((ah->cc.rx_frame - cc.rx_frame) +
854 (ah->cc.tx_frame - cc.tx_frame));
1102 855
1103 if (!DO_ANI(ah)) { 856skip:
1104 /* 857 if (clear) {
1105 * We must always clear the interrupt cause by 858 REG_WRITE(ah, AR_CCCNT, 0);
1106 * resetting the phy error regs. 859 REG_WRITE(ah, AR_RFCNT, 0);
1107 */ 860 REG_WRITE(ah, AR_RCCNT, 0);
1108 REG_WRITE(ah, AR_PHY_ERR_1, 0); 861 REG_WRITE(ah, AR_TFCNT, 0);
1109 REG_WRITE(ah, AR_PHY_ERR_2, 0); 862 memset(&ah->cc, 0, sizeof(ah->cc));
1110 return;
1111 } 863 }
1112 864
1113 /* NB: these are not reset-on-read */ 865 /* unfreeze counters */
1114 phyCnt1 = REG_READ(ah, AR_PHY_ERR_1); 866 REG_WRITE(ah, AR_MIBC, 0);
1115 phyCnt2 = REG_READ(ah, AR_PHY_ERR_2);
1116 if (((phyCnt1 & AR_MIBCNT_INTRMASK) == AR_MIBCNT_INTRMASK) ||
1117 ((phyCnt2 & AR_MIBCNT_INTRMASK) == AR_MIBCNT_INTRMASK)) {
1118 struct ar5416AniState *aniState = ah->curani;
1119 u32 ofdmPhyErrCnt, cckPhyErrCnt;
1120
1121 /* NB: only use ast_ani_*errs with AH_PRIVATE_DIAG */
1122 ofdmPhyErrCnt = phyCnt1 - aniState->ofdmPhyErrBase;
1123 ah->stats.ast_ani_ofdmerrs +=
1124 ofdmPhyErrCnt - aniState->ofdmPhyErrCount;
1125 aniState->ofdmPhyErrCount = ofdmPhyErrCnt;
1126
1127 cckPhyErrCnt = phyCnt2 - aniState->cckPhyErrBase;
1128 ah->stats.ast_ani_cckerrs +=
1129 cckPhyErrCnt - aniState->cckPhyErrCount;
1130 aniState->cckPhyErrCount = cckPhyErrCnt;
1131
1132 /*
1133 * NB: figure out which counter triggered. If both
1134 * trigger we'll only deal with one as the processing
1135 * clobbers the error counter so the trigger threshold
1136 * check will never be true.
1137 */
1138 if (aniState->ofdmPhyErrCount > aniState->ofdmTrigHigh)
1139 ath9k_hw_ani_ofdm_err_trigger_new(ah);
1140 if (aniState->cckPhyErrCount > aniState->cckTrigHigh)
1141 ath9k_hw_ani_cck_err_trigger_old(ah);
1142 /* NB: always restart to insure the h/w counters are reset */
1143 ath9k_ani_restart_old(ah);
1144 }
1145} 867}
1146 868
1147/* 869/*
@@ -1149,7 +871,7 @@ static void ath9k_hw_proc_mib_event_old(struct ath_hw *ah)
1149 * any of the MIB counters overflow/trigger so don't assume we're 871 * any of the MIB counters overflow/trigger so don't assume we're
1150 * here because a PHY error counter triggered. 872 * here because a PHY error counter triggered.
1151 */ 873 */
1152static void ath9k_hw_proc_mib_event_new(struct ath_hw *ah) 874void ath9k_hw_proc_mib_event(struct ath_hw *ah)
1153{ 875{
1154 u32 phyCnt1, phyCnt2; 876 u32 phyCnt1, phyCnt2;
1155 877
@@ -1175,12 +897,17 @@ static void ath9k_hw_proc_mib_event_new(struct ath_hw *ah)
1175 /* NB: these are not reset-on-read */ 897 /* NB: these are not reset-on-read */
1176 phyCnt1 = REG_READ(ah, AR_PHY_ERR_1); 898 phyCnt1 = REG_READ(ah, AR_PHY_ERR_1);
1177 phyCnt2 = REG_READ(ah, AR_PHY_ERR_2); 899 phyCnt2 = REG_READ(ah, AR_PHY_ERR_2);
1178
1179 /* NB: always restart to insure the h/w counters are reset */
1180 if (((phyCnt1 & AR_MIBCNT_INTRMASK) == AR_MIBCNT_INTRMASK) || 900 if (((phyCnt1 & AR_MIBCNT_INTRMASK) == AR_MIBCNT_INTRMASK) ||
1181 ((phyCnt2 & AR_MIBCNT_INTRMASK) == AR_MIBCNT_INTRMASK)) 901 ((phyCnt2 & AR_MIBCNT_INTRMASK) == AR_MIBCNT_INTRMASK)) {
1182 ath9k_ani_restart_new(ah); 902
903 if (!use_new_ani(ah))
904 ath9k_hw_ani_read_counters(ah);
905
906 /* NB: always restart to insure the h/w counters are reset */
907 ath9k_ani_restart(ah);
908 }
1183} 909}
910EXPORT_SYMBOL(ath9k_hw_proc_mib_event);
1184 911
1185void ath9k_hw_ani_setup(struct ath_hw *ah) 912void ath9k_hw_ani_setup(struct ath_hw *ah)
1186{ 913{
@@ -1206,61 +933,58 @@ void ath9k_hw_ani_init(struct ath_hw *ah)
1206 933
1207 ath_print(common, ATH_DBG_ANI, "Initialize ANI\n"); 934 ath_print(common, ATH_DBG_ANI, "Initialize ANI\n");
1208 935
1209 memset(ah->ani, 0, sizeof(ah->ani)); 936 if (use_new_ani(ah)) {
1210 for (i = 0; i < ARRAY_SIZE(ah->ani); i++) { 937 ah->config.ofdm_trig_high = ATH9K_ANI_OFDM_TRIG_HIGH_NEW;
1211 if (AR_SREV_9300_20_OR_LATER(ah) || modparam_force_new_ani) { 938 ah->config.ofdm_trig_low = ATH9K_ANI_OFDM_TRIG_LOW_NEW;
1212 ah->ani[i].ofdmTrigHigh = ATH9K_ANI_OFDM_TRIG_HIGH_NEW;
1213 ah->ani[i].ofdmTrigLow = ATH9K_ANI_OFDM_TRIG_LOW_NEW;
1214 939
1215 ah->ani[i].cckTrigHigh = ATH9K_ANI_CCK_TRIG_HIGH_NEW; 940 ah->config.cck_trig_high = ATH9K_ANI_CCK_TRIG_HIGH_NEW;
1216 ah->ani[i].cckTrigLow = ATH9K_ANI_CCK_TRIG_LOW_NEW; 941 ah->config.cck_trig_low = ATH9K_ANI_CCK_TRIG_LOW_NEW;
942 } else {
943 ah->config.ofdm_trig_high = ATH9K_ANI_OFDM_TRIG_HIGH_OLD;
944 ah->config.ofdm_trig_low = ATH9K_ANI_OFDM_TRIG_LOW_OLD;
1217 945
1218 ah->ani[i].spurImmunityLevel = 946 ah->config.cck_trig_high = ATH9K_ANI_CCK_TRIG_HIGH_OLD;
1219 ATH9K_ANI_SPUR_IMMUNE_LVL_NEW; 947 ah->config.cck_trig_low = ATH9K_ANI_CCK_TRIG_LOW_OLD;
948 }
949
950 for (i = 0; i < ARRAY_SIZE(ah->channels); i++) {
951 struct ath9k_channel *chan = &ah->channels[i];
952 struct ar5416AniState *ani = &chan->ani;
1220 953
1221 ah->ani[i].firstepLevel = ATH9K_ANI_FIRSTEP_LVL_NEW; 954 if (use_new_ani(ah)) {
955 ani->spurImmunityLevel =
956 ATH9K_ANI_SPUR_IMMUNE_LVL_NEW;
1222 957
1223 ah->ani[i].ofdmPhyErrBase = 0; 958 ani->firstepLevel = ATH9K_ANI_FIRSTEP_LVL_NEW;
1224 ah->ani[i].cckPhyErrBase = 0;
1225 959
1226 if (AR_SREV_9300_20_OR_LATER(ah)) 960 if (AR_SREV_9300_20_OR_LATER(ah))
1227 ah->ani[i].mrcCCKOff = 961 ani->mrcCCKOff =
1228 !ATH9K_ANI_ENABLE_MRC_CCK; 962 !ATH9K_ANI_ENABLE_MRC_CCK;
1229 else 963 else
1230 ah->ani[i].mrcCCKOff = true; 964 ani->mrcCCKOff = true;
1231 965
1232 ah->ani[i].ofdmsTurn = true; 966 ani->ofdmsTurn = true;
1233 } else { 967 } else {
1234 ah->ani[i].ofdmTrigHigh = ATH9K_ANI_OFDM_TRIG_HIGH_OLD; 968 ani->spurImmunityLevel =
1235 ah->ani[i].ofdmTrigLow = ATH9K_ANI_OFDM_TRIG_LOW_OLD;
1236
1237 ah->ani[i].cckTrigHigh = ATH9K_ANI_CCK_TRIG_HIGH_OLD;
1238 ah->ani[i].cckTrigLow = ATH9K_ANI_CCK_TRIG_LOW_OLD;
1239
1240 ah->ani[i].spurImmunityLevel =
1241 ATH9K_ANI_SPUR_IMMUNE_LVL_OLD; 969 ATH9K_ANI_SPUR_IMMUNE_LVL_OLD;
1242 ah->ani[i].firstepLevel = ATH9K_ANI_FIRSTEP_LVL_OLD; 970 ani->firstepLevel = ATH9K_ANI_FIRSTEP_LVL_OLD;
1243 971
1244 ah->ani[i].ofdmPhyErrBase = 972 ani->cckWeakSigThreshold =
1245 AR_PHY_COUNTMAX - ATH9K_ANI_OFDM_TRIG_HIGH_OLD;
1246 ah->ani[i].cckPhyErrBase =
1247 AR_PHY_COUNTMAX - ATH9K_ANI_CCK_TRIG_HIGH_OLD;
1248 ah->ani[i].cckWeakSigThreshold =
1249 ATH9K_ANI_CCK_WEAK_SIG_THR; 973 ATH9K_ANI_CCK_WEAK_SIG_THR;
1250 } 974 }
1251 975
1252 ah->ani[i].rssiThrHigh = ATH9K_ANI_RSSI_THR_HIGH; 976 ani->rssiThrHigh = ATH9K_ANI_RSSI_THR_HIGH;
1253 ah->ani[i].rssiThrLow = ATH9K_ANI_RSSI_THR_LOW; 977 ani->rssiThrLow = ATH9K_ANI_RSSI_THR_LOW;
1254 ah->ani[i].ofdmWeakSigDetectOff = 978 ani->ofdmWeakSigDetectOff =
1255 !ATH9K_ANI_USE_OFDM_WEAK_SIG; 979 !ATH9K_ANI_USE_OFDM_WEAK_SIG;
1256 ah->ani[i].cckNoiseImmunityLevel = ATH9K_ANI_CCK_DEF_LEVEL; 980 ani->cckNoiseImmunityLevel = ATH9K_ANI_CCK_DEF_LEVEL;
1257 } 981 }
1258 982
1259 /* 983 /*
1260 * since we expect some ongoing maintenance on the tables, let's sanity 984 * since we expect some ongoing maintenance on the tables, let's sanity
1261 * check here default level should not modify INI setting. 985 * check here default level should not modify INI setting.
1262 */ 986 */
1263 if (AR_SREV_9300_20_OR_LATER(ah) || modparam_force_new_ani) { 987 if (use_new_ani(ah)) {
1264 const struct ani_ofdm_level_entry *entry_ofdm; 988 const struct ani_ofdm_level_entry *entry_ofdm;
1265 const struct ani_cck_level_entry *entry_cck; 989 const struct ani_cck_level_entry *entry_cck;
1266 990
@@ -1274,50 +998,9 @@ void ath9k_hw_ani_init(struct ath_hw *ah)
1274 ah->config.ani_poll_interval = ATH9K_ANI_POLLINTERVAL_OLD; 998 ah->config.ani_poll_interval = ATH9K_ANI_POLLINTERVAL_OLD;
1275 } 999 }
1276 1000
1277 ath_print(common, ATH_DBG_ANI,
1278 "Setting OfdmErrBase = 0x%08x\n",
1279 ah->ani[0].ofdmPhyErrBase);
1280 ath_print(common, ATH_DBG_ANI, "Setting cckErrBase = 0x%08x\n",
1281 ah->ani[0].cckPhyErrBase);
1282
1283 ENABLE_REGWRITE_BUFFER(ah);
1284
1285 REG_WRITE(ah, AR_PHY_ERR_1, ah->ani[0].ofdmPhyErrBase);
1286 REG_WRITE(ah, AR_PHY_ERR_2, ah->ani[0].cckPhyErrBase);
1287
1288 REGWRITE_BUFFER_FLUSH(ah);
1289 DISABLE_REGWRITE_BUFFER(ah);
1290
1291 ath9k_enable_mib_counters(ah);
1292
1293 if (ah->config.enable_ani) 1001 if (ah->config.enable_ani)
1294 ah->proc_phyerr |= HAL_PROCESS_ANI; 1002 ah->proc_phyerr |= HAL_PROCESS_ANI;
1295}
1296
1297void ath9k_hw_attach_ani_ops_old(struct ath_hw *ah)
1298{
1299 struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
1300 struct ath_hw_ops *ops = ath9k_hw_ops(ah);
1301 1003
1302 priv_ops->ani_reset = ath9k_ani_reset_old; 1004 ath9k_ani_restart(ah);
1303 priv_ops->ani_lower_immunity = ath9k_hw_ani_lower_immunity_old; 1005 ath9k_enable_mib_counters(ah);
1304
1305 ops->ani_proc_mib_event = ath9k_hw_proc_mib_event_old;
1306 ops->ani_monitor = ath9k_hw_ani_monitor_old;
1307
1308 ath_print(ath9k_hw_common(ah), ATH_DBG_ANY, "Using ANI v1\n");
1309}
1310
1311void ath9k_hw_attach_ani_ops_new(struct ath_hw *ah)
1312{
1313 struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
1314 struct ath_hw_ops *ops = ath9k_hw_ops(ah);
1315
1316 priv_ops->ani_reset = ath9k_ani_reset_new;
1317 priv_ops->ani_lower_immunity = ath9k_hw_ani_lower_immunity_new;
1318
1319 ops->ani_proc_mib_event = ath9k_hw_proc_mib_event_new;
1320 ops->ani_monitor = ath9k_hw_ani_monitor_new;
1321
1322 ath_print(ath9k_hw_common(ah), ATH_DBG_ANY, "Using ANI v2\n");
1323} 1006}
diff --git a/drivers/net/wireless/ath/ath9k/ani.h b/drivers/net/wireless/ath/ath9k/ani.h
index f4d0a4d48b3..98cfd8154c7 100644
--- a/drivers/net/wireless/ath/ath9k/ani.h
+++ b/drivers/net/wireless/ath/ath9k/ani.h
@@ -19,7 +19,7 @@
19 19
20#define HAL_PROCESS_ANI 0x00000001 20#define HAL_PROCESS_ANI 0x00000001
21 21
22#define DO_ANI(ah) (((ah)->proc_phyerr & HAL_PROCESS_ANI)) 22#define DO_ANI(ah) (((ah)->proc_phyerr & HAL_PROCESS_ANI) && ah->curchan)
23 23
24#define BEACON_RSSI(ahp) (ahp->stats.avgbrssi) 24#define BEACON_RSSI(ahp) (ahp->stats.avgbrssi)
25 25
@@ -93,6 +93,13 @@ struct ath9k_mib_stats {
93 u32 beacons; 93 u32 beacons;
94}; 94};
95 95
96struct ath_cycle_counters {
97 u32 cycles;
98 u32 rx_frame;
99 u32 rx_clear;
100 u32 tx_frame;
101};
102
96/* INI default values for ANI registers */ 103/* INI default values for ANI registers */
97struct ath9k_ani_default { 104struct ath9k_ani_default {
98 u16 m1ThreshLow; 105 u16 m1ThreshLow;
@@ -123,20 +130,11 @@ struct ar5416AniState {
123 u8 ofdmWeakSigDetectOff; 130 u8 ofdmWeakSigDetectOff;
124 u8 cckWeakSigThreshold; 131 u8 cckWeakSigThreshold;
125 u32 listenTime; 132 u32 listenTime;
126 u32 ofdmTrigHigh;
127 u32 ofdmTrigLow;
128 int32_t cckTrigHigh;
129 int32_t cckTrigLow;
130 int32_t rssiThrLow; 133 int32_t rssiThrLow;
131 int32_t rssiThrHigh; 134 int32_t rssiThrHigh;
132 u32 noiseFloor; 135 u32 noiseFloor;
133 u32 txFrameCount;
134 u32 rxFrameCount;
135 u32 cycleCount;
136 u32 ofdmPhyErrCount; 136 u32 ofdmPhyErrCount;
137 u32 cckPhyErrCount; 137 u32 cckPhyErrCount;
138 u32 ofdmPhyErrBase;
139 u32 cckPhyErrBase;
140 int16_t pktRssi[2]; 138 int16_t pktRssi[2];
141 int16_t ofdmErrRssi[2]; 139 int16_t ofdmErrRssi[2];
142 int16_t cckErrRssi[2]; 140 int16_t cckErrRssi[2];
@@ -166,8 +164,7 @@ struct ar5416Stats {
166 164
167void ath9k_enable_mib_counters(struct ath_hw *ah); 165void ath9k_enable_mib_counters(struct ath_hw *ah);
168void ath9k_hw_disable_mib_counters(struct ath_hw *ah); 166void ath9k_hw_disable_mib_counters(struct ath_hw *ah);
169u32 ath9k_hw_GetMibCycleCountsPct(struct ath_hw *ah, u32 *rxc_pcnt, 167void ath9k_hw_update_cycle_counters(struct ath_hw *ah);
170 u32 *rxf_pcnt, u32 *txf_pcnt);
171void ath9k_hw_ani_setup(struct ath_hw *ah); 168void ath9k_hw_ani_setup(struct ath_hw *ah);
172void ath9k_hw_ani_init(struct ath_hw *ah); 169void ath9k_hw_ani_init(struct ath_hw *ah);
173int ath9k_hw_get_ani_channel_idx(struct ath_hw *ah, 170int ath9k_hw_get_ani_channel_idx(struct ath_hw *ah,
diff --git a/drivers/net/wireless/ath/ath9k/ar5008_phy.c b/drivers/net/wireless/ath/ath9k/ar5008_phy.c
index 525671f52b4..ea9f4497f58 100644
--- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c
@@ -613,14 +613,11 @@ static void ar5008_hw_init_chain_masks(struct ath_hw *ah)
613 rx_chainmask = ah->rxchainmask; 613 rx_chainmask = ah->rxchainmask;
614 tx_chainmask = ah->txchainmask; 614 tx_chainmask = ah->txchainmask;
615 615
616 ENABLE_REGWRITE_BUFFER(ah);
617 616
618 switch (rx_chainmask) { 617 switch (rx_chainmask) {
619 case 0x5: 618 case 0x5:
620 DISABLE_REGWRITE_BUFFER(ah);
621 REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP, 619 REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP,
622 AR_PHY_SWAP_ALT_CHAIN); 620 AR_PHY_SWAP_ALT_CHAIN);
623 ENABLE_REGWRITE_BUFFER(ah);
624 case 0x3: 621 case 0x3:
625 if (ah->hw_version.macVersion == AR_SREV_REVISION_5416_10) { 622 if (ah->hw_version.macVersion == AR_SREV_REVISION_5416_10) {
626 REG_WRITE(ah, AR_PHY_RX_CHAINMASK, 0x7); 623 REG_WRITE(ah, AR_PHY_RX_CHAINMASK, 0x7);
@@ -630,17 +627,18 @@ static void ar5008_hw_init_chain_masks(struct ath_hw *ah)
630 case 0x1: 627 case 0x1:
631 case 0x2: 628 case 0x2:
632 case 0x7: 629 case 0x7:
630 ENABLE_REGWRITE_BUFFER(ah);
633 REG_WRITE(ah, AR_PHY_RX_CHAINMASK, rx_chainmask); 631 REG_WRITE(ah, AR_PHY_RX_CHAINMASK, rx_chainmask);
634 REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, rx_chainmask); 632 REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, rx_chainmask);
635 break; 633 break;
636 default: 634 default:
635 ENABLE_REGWRITE_BUFFER(ah);
637 break; 636 break;
638 } 637 }
639 638
640 REG_WRITE(ah, AR_SELFGEN_MASK, tx_chainmask); 639 REG_WRITE(ah, AR_SELFGEN_MASK, tx_chainmask);
641 640
642 REGWRITE_BUFFER_FLUSH(ah); 641 REGWRITE_BUFFER_FLUSH(ah);
643 DISABLE_REGWRITE_BUFFER(ah);
644 642
645 if (tx_chainmask == 0x5) { 643 if (tx_chainmask == 0x5) {
646 REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP, 644 REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP,
@@ -726,7 +724,6 @@ static void ar5008_hw_set_channel_regs(struct ath_hw *ah,
726 REG_WRITE(ah, AR_CST, 0xF << AR_CST_TIMEOUT_LIMIT_S); 724 REG_WRITE(ah, AR_CST, 0xF << AR_CST_TIMEOUT_LIMIT_S);
727 725
728 REGWRITE_BUFFER_FLUSH(ah); 726 REGWRITE_BUFFER_FLUSH(ah);
729 DISABLE_REGWRITE_BUFFER(ah);
730} 727}
731 728
732 729
@@ -818,7 +815,6 @@ static int ar5008_hw_process_ini(struct ath_hw *ah,
818 } 815 }
819 816
820 REGWRITE_BUFFER_FLUSH(ah); 817 REGWRITE_BUFFER_FLUSH(ah);
821 DISABLE_REGWRITE_BUFFER(ah);
822 818
823 if (AR_SREV_9280(ah) || AR_SREV_9287_11_OR_LATER(ah)) 819 if (AR_SREV_9280(ah) || AR_SREV_9287_11_OR_LATER(ah))
824 REG_WRITE_ARRAY(&ah->iniModesRxGain, modesIndex, regWrites); 820 REG_WRITE_ARRAY(&ah->iniModesRxGain, modesIndex, regWrites);
@@ -849,7 +845,6 @@ static int ar5008_hw_process_ini(struct ath_hw *ah,
849 } 845 }
850 846
851 REGWRITE_BUFFER_FLUSH(ah); 847 REGWRITE_BUFFER_FLUSH(ah);
852 DISABLE_REGWRITE_BUFFER(ah);
853 848
854 if (AR_SREV_9271(ah)) { 849 if (AR_SREV_9271(ah)) {
855 if (ah->eep_ops->get_eeprom(ah, EEP_TXGAIN_TYPE) == 1) 850 if (ah->eep_ops->get_eeprom(ah, EEP_TXGAIN_TYPE) == 1)
@@ -1053,7 +1048,7 @@ static bool ar5008_hw_ani_control_old(struct ath_hw *ah,
1053 enum ath9k_ani_cmd cmd, 1048 enum ath9k_ani_cmd cmd,
1054 int param) 1049 int param)
1055{ 1050{
1056 struct ar5416AniState *aniState = ah->curani; 1051 struct ar5416AniState *aniState = &ah->curchan->ani;
1057 struct ath_common *common = ath9k_hw_common(ah); 1052 struct ath_common *common = ath9k_hw_common(ah);
1058 1053
1059 switch (cmd & ah->ani_function) { 1054 switch (cmd & ah->ani_function) {
@@ -1225,8 +1220,7 @@ static bool ar5008_hw_ani_control_old(struct ath_hw *ah,
1225 aniState->firstepLevel, 1220 aniState->firstepLevel,
1226 aniState->listenTime); 1221 aniState->listenTime);
1227 ath_print(common, ATH_DBG_ANI, 1222 ath_print(common, ATH_DBG_ANI,
1228 "cycleCount=%d, ofdmPhyErrCount=%d, cckPhyErrCount=%d\n\n", 1223 "ofdmPhyErrCount=%d, cckPhyErrCount=%d\n\n",
1229 aniState->cycleCount,
1230 aniState->ofdmPhyErrCount, 1224 aniState->ofdmPhyErrCount,
1231 aniState->cckPhyErrCount); 1225 aniState->cckPhyErrCount);
1232 1226
@@ -1237,9 +1231,9 @@ static bool ar5008_hw_ani_control_new(struct ath_hw *ah,
1237 enum ath9k_ani_cmd cmd, 1231 enum ath9k_ani_cmd cmd,
1238 int param) 1232 int param)
1239{ 1233{
1240 struct ar5416AniState *aniState = ah->curani;
1241 struct ath_common *common = ath9k_hw_common(ah); 1234 struct ath_common *common = ath9k_hw_common(ah);
1242 struct ath9k_channel *chan = ah->curchan; 1235 struct ath9k_channel *chan = ah->curchan;
1236 struct ar5416AniState *aniState = &chan->ani;
1243 s32 value, value2; 1237 s32 value, value2;
1244 1238
1245 switch (cmd & ah->ani_function) { 1239 switch (cmd & ah->ani_function) {
@@ -1478,15 +1472,13 @@ static bool ar5008_hw_ani_control_new(struct ath_hw *ah,
1478 1472
1479 ath_print(common, ATH_DBG_ANI, 1473 ath_print(common, ATH_DBG_ANI,
1480 "ANI parameters: SI=%d, ofdmWS=%s FS=%d " 1474 "ANI parameters: SI=%d, ofdmWS=%s FS=%d "
1481 "MRCcck=%s listenTime=%d CC=%d listen=%d " 1475 "MRCcck=%s listenTime=%d "
1482 "ofdmErrs=%d cckErrs=%d\n", 1476 "ofdmErrs=%d cckErrs=%d\n",
1483 aniState->spurImmunityLevel, 1477 aniState->spurImmunityLevel,
1484 !aniState->ofdmWeakSigDetectOff ? "on" : "off", 1478 !aniState->ofdmWeakSigDetectOff ? "on" : "off",
1485 aniState->firstepLevel, 1479 aniState->firstepLevel,
1486 !aniState->mrcCCKOff ? "on" : "off", 1480 !aniState->mrcCCKOff ? "on" : "off",
1487 aniState->listenTime, 1481 aniState->listenTime,
1488 aniState->cycleCount,
1489 aniState->listenTime,
1490 aniState->ofdmPhyErrCount, 1482 aniState->ofdmPhyErrCount,
1491 aniState->cckPhyErrCount); 1483 aniState->cckPhyErrCount);
1492 return true; 1484 return true;
@@ -1526,16 +1518,12 @@ static void ar5008_hw_do_getnf(struct ath_hw *ah,
1526 */ 1518 */
1527static void ar5008_hw_ani_cache_ini_regs(struct ath_hw *ah) 1519static void ar5008_hw_ani_cache_ini_regs(struct ath_hw *ah)
1528{ 1520{
1529 struct ar5416AniState *aniState;
1530 struct ath_common *common = ath9k_hw_common(ah); 1521 struct ath_common *common = ath9k_hw_common(ah);
1531 struct ath9k_channel *chan = ah->curchan; 1522 struct ath9k_channel *chan = ah->curchan;
1523 struct ar5416AniState *aniState = &chan->ani;
1532 struct ath9k_ani_default *iniDef; 1524 struct ath9k_ani_default *iniDef;
1533 int index;
1534 u32 val; 1525 u32 val;
1535 1526
1536 index = ath9k_hw_get_ani_channel_idx(ah, chan);
1537 aniState = &ah->ani[index];
1538 ah->curani = aniState;
1539 iniDef = &aniState->iniDef; 1527 iniDef = &aniState->iniDef;
1540 1528
1541 ath_print(common, ATH_DBG_ANI, 1529 ath_print(common, ATH_DBG_ANI,
@@ -1579,8 +1567,6 @@ static void ar5008_hw_ani_cache_ini_regs(struct ath_hw *ah)
1579 aniState->firstepLevel = ATH9K_ANI_FIRSTEP_LVL_NEW; 1567 aniState->firstepLevel = ATH9K_ANI_FIRSTEP_LVL_NEW;
1580 aniState->ofdmWeakSigDetectOff = !ATH9K_ANI_USE_OFDM_WEAK_SIG; 1568 aniState->ofdmWeakSigDetectOff = !ATH9K_ANI_USE_OFDM_WEAK_SIG;
1581 aniState->mrcCCKOff = true; /* not available on pre AR9003 */ 1569 aniState->mrcCCKOff = true; /* not available on pre AR9003 */
1582
1583 aniState->cycleCount = 0;
1584} 1570}
1585 1571
1586static void ar5008_hw_set_nf_limits(struct ath_hw *ah) 1572static void ar5008_hw_set_nf_limits(struct ath_hw *ah)
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_calib.c b/drivers/net/wireless/ath/ath9k/ar9002_calib.c
index d7d1d55362e..15f62cd0cc3 100644
--- a/drivers/net/wireless/ath/ath9k/ar9002_calib.c
+++ b/drivers/net/wireless/ath/ath9k/ar9002_calib.c
@@ -20,6 +20,13 @@
20 20
21#define AR9285_CLCAL_REDO_THRESH 1 21#define AR9285_CLCAL_REDO_THRESH 1
22 22
23enum ar9002_cal_types {
24 ADC_GAIN_CAL = BIT(0),
25 ADC_DC_CAL = BIT(1),
26 IQ_MISMATCH_CAL = BIT(2),
27};
28
29
23static void ar9002_hw_setup_calibration(struct ath_hw *ah, 30static void ar9002_hw_setup_calibration(struct ath_hw *ah,
24 struct ath9k_cal_list *currCal) 31 struct ath9k_cal_list *currCal)
25{ 32{
@@ -45,13 +52,6 @@ static void ar9002_hw_setup_calibration(struct ath_hw *ah,
45 ath_print(common, ATH_DBG_CALIBRATE, 52 ath_print(common, ATH_DBG_CALIBRATE,
46 "starting ADC DC Calibration\n"); 53 "starting ADC DC Calibration\n");
47 break; 54 break;
48 case ADC_DC_INIT_CAL:
49 REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_DC_INIT);
50 ath_print(common, ATH_DBG_CALIBRATE,
51 "starting Init ADC DC Calibration\n");
52 break;
53 case TEMP_COMP_CAL:
54 break; /* Not supported */
55 } 55 }
56 56
57 REG_SET_BIT(ah, AR_PHY_TIMING_CTRL4(0), 57 REG_SET_BIT(ah, AR_PHY_TIMING_CTRL4(0),
@@ -96,25 +96,6 @@ static bool ar9002_hw_per_calibration(struct ath_hw *ah,
96 return iscaldone; 96 return iscaldone;
97} 97}
98 98
99/* Assumes you are talking about the currently configured channel */
100static bool ar9002_hw_iscal_supported(struct ath_hw *ah,
101 enum ath9k_cal_types calType)
102{
103 struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf;
104
105 switch (calType & ah->supp_cals) {
106 case IQ_MISMATCH_CAL: /* Both 2 GHz and 5 GHz support OFDM */
107 return true;
108 case ADC_GAIN_CAL:
109 case ADC_DC_CAL:
110 if (!(conf->channel->band == IEEE80211_BAND_2GHZ &&
111 conf_is_ht20(conf)))
112 return true;
113 break;
114 }
115 return false;
116}
117
118static void ar9002_hw_iqcal_collect(struct ath_hw *ah) 99static void ar9002_hw_iqcal_collect(struct ath_hw *ah)
119{ 100{
120 int i; 101 int i;
@@ -541,7 +522,6 @@ static void ar9271_hw_pa_cal(struct ath_hw *ah, bool is_reset)
541 REG_WRITE(ah, regList[i][0], regList[i][1]); 522 REG_WRITE(ah, regList[i][0], regList[i][1]);
542 523
543 REGWRITE_BUFFER_FLUSH(ah); 524 REGWRITE_BUFFER_FLUSH(ah);
544 DISABLE_REGWRITE_BUFFER(ah);
545} 525}
546 526
547static inline void ar9285_hw_pa_cal(struct ath_hw *ah, bool is_reset) 527static inline void ar9285_hw_pa_cal(struct ath_hw *ah, bool is_reset)
@@ -877,24 +857,28 @@ static bool ar9002_hw_init_cal(struct ath_hw *ah, struct ath9k_channel *chan)
877 857
878 /* Enable IQ, ADC Gain and ADC DC offset CALs */ 858 /* Enable IQ, ADC Gain and ADC DC offset CALs */
879 if (AR_SREV_9100(ah) || AR_SREV_9160_10_OR_LATER(ah)) { 859 if (AR_SREV_9100(ah) || AR_SREV_9160_10_OR_LATER(ah)) {
880 if (ar9002_hw_iscal_supported(ah, ADC_GAIN_CAL)) { 860 ah->supp_cals = IQ_MISMATCH_CAL;
861
862 if (AR_SREV_9160_10_OR_LATER(ah) &&
863 !(IS_CHAN_2GHZ(chan) && IS_CHAN_HT20(chan))) {
864 ah->supp_cals |= ADC_GAIN_CAL | ADC_DC_CAL;
865
866
881 INIT_CAL(&ah->adcgain_caldata); 867 INIT_CAL(&ah->adcgain_caldata);
882 INSERT_CAL(ah, &ah->adcgain_caldata); 868 INSERT_CAL(ah, &ah->adcgain_caldata);
883 ath_print(common, ATH_DBG_CALIBRATE, 869 ath_print(common, ATH_DBG_CALIBRATE,
884 "enabling ADC Gain Calibration.\n"); 870 "enabling ADC Gain Calibration.\n");
885 } 871
886 if (ar9002_hw_iscal_supported(ah, ADC_DC_CAL)) {
887 INIT_CAL(&ah->adcdc_caldata); 872 INIT_CAL(&ah->adcdc_caldata);
888 INSERT_CAL(ah, &ah->adcdc_caldata); 873 INSERT_CAL(ah, &ah->adcdc_caldata);
889 ath_print(common, ATH_DBG_CALIBRATE, 874 ath_print(common, ATH_DBG_CALIBRATE,
890 "enabling ADC DC Calibration.\n"); 875 "enabling ADC DC Calibration.\n");
891 } 876 }
892 if (ar9002_hw_iscal_supported(ah, IQ_MISMATCH_CAL)) { 877
893 INIT_CAL(&ah->iq_caldata); 878 INIT_CAL(&ah->iq_caldata);
894 INSERT_CAL(ah, &ah->iq_caldata); 879 INSERT_CAL(ah, &ah->iq_caldata);
895 ath_print(common, ATH_DBG_CALIBRATE, 880 ath_print(common, ATH_DBG_CALIBRATE,
896 "enabling IQ Calibration.\n"); 881 "enabling IQ Calibration.\n");
897 }
898 882
899 ah->cal_list_curr = ah->cal_list; 883 ah->cal_list_curr = ah->cal_list;
900 884
@@ -950,13 +934,6 @@ static const struct ath9k_percal_data adc_dc_cal_single_sample = {
950 ar9002_hw_adc_dccal_collect, 934 ar9002_hw_adc_dccal_collect,
951 ar9002_hw_adc_dccal_calibrate 935 ar9002_hw_adc_dccal_calibrate
952}; 936};
953static const struct ath9k_percal_data adc_init_dc_cal = {
954 ADC_DC_INIT_CAL,
955 MIN_CAL_SAMPLES,
956 INIT_LOG_COUNT,
957 ar9002_hw_adc_dccal_collect,
958 ar9002_hw_adc_dccal_calibrate
959};
960 937
961static void ar9002_hw_init_cal_settings(struct ath_hw *ah) 938static void ar9002_hw_init_cal_settings(struct ath_hw *ah)
962{ 939{
@@ -973,16 +950,12 @@ static void ar9002_hw_init_cal_settings(struct ath_hw *ah)
973 &adc_gain_cal_single_sample; 950 &adc_gain_cal_single_sample;
974 ah->adcdc_caldata.calData = 951 ah->adcdc_caldata.calData =
975 &adc_dc_cal_single_sample; 952 &adc_dc_cal_single_sample;
976 ah->adcdc_calinitdata.calData =
977 &adc_init_dc_cal;
978 } else { 953 } else {
979 ah->iq_caldata.calData = &iq_cal_multi_sample; 954 ah->iq_caldata.calData = &iq_cal_multi_sample;
980 ah->adcgain_caldata.calData = 955 ah->adcgain_caldata.calData =
981 &adc_gain_cal_multi_sample; 956 &adc_gain_cal_multi_sample;
982 ah->adcdc_caldata.calData = 957 ah->adcdc_caldata.calData =
983 &adc_dc_cal_multi_sample; 958 &adc_dc_cal_multi_sample;
984 ah->adcdc_calinitdata.calData =
985 &adc_init_dc_cal;
986 } 959 }
987 ah->supp_cals = ADC_GAIN_CAL | ADC_DC_CAL | IQ_MISMATCH_CAL; 960 ah->supp_cals = ADC_GAIN_CAL | ADC_DC_CAL | IQ_MISMATCH_CAL;
988 } 961 }
@@ -996,7 +969,6 @@ void ar9002_hw_attach_calib_ops(struct ath_hw *ah)
996 priv_ops->init_cal_settings = ar9002_hw_init_cal_settings; 969 priv_ops->init_cal_settings = ar9002_hw_init_cal_settings;
997 priv_ops->init_cal = ar9002_hw_init_cal; 970 priv_ops->init_cal = ar9002_hw_init_cal;
998 priv_ops->setup_calibration = ar9002_hw_setup_calibration; 971 priv_ops->setup_calibration = ar9002_hw_setup_calibration;
999 priv_ops->iscal_supported = ar9002_hw_iscal_supported;
1000 972
1001 ops->calibrate = ar9002_hw_calibrate; 973 ops->calibrate = ar9002_hw_calibrate;
1002} 974}
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_hw.c b/drivers/net/wireless/ath/ath9k/ar9002_hw.c
index fde45082a13..a0471f2e1c7 100644
--- a/drivers/net/wireless/ath/ath9k/ar9002_hw.c
+++ b/drivers/net/wireless/ath/ath9k/ar9002_hw.c
@@ -371,7 +371,6 @@ static void ar9002_hw_configpcipowersave(struct ath_hw *ah,
371 REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000); 371 REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000);
372 372
373 REGWRITE_BUFFER_FLUSH(ah); 373 REGWRITE_BUFFER_FLUSH(ah);
374 DISABLE_REGWRITE_BUFFER(ah);
375 } 374 }
376 375
377 udelay(1000); 376 udelay(1000);
@@ -468,7 +467,6 @@ static int ar9002_hw_get_radiorev(struct ath_hw *ah)
468 REG_WRITE(ah, AR_PHY(0x20), 0x00010000); 467 REG_WRITE(ah, AR_PHY(0x20), 0x00010000);
469 468
470 REGWRITE_BUFFER_FLUSH(ah); 469 REGWRITE_BUFFER_FLUSH(ah);
471 DISABLE_REGWRITE_BUFFER(ah);
472 470
473 val = (REG_READ(ah, AR_PHY(256)) >> 24) & 0xff; 471 val = (REG_READ(ah, AR_PHY(256)) >> 24) & 0xff;
474 val = ((val & 0xf0) >> 4) | ((val & 0x0f) << 4); 472 val = ((val & 0xf0) >> 4) | ((val & 0x0f) << 4);
@@ -574,11 +572,6 @@ void ar9002_hw_attach_ops(struct ath_hw *ah)
574 572
575 ar9002_hw_attach_calib_ops(ah); 573 ar9002_hw_attach_calib_ops(ah);
576 ar9002_hw_attach_mac_ops(ah); 574 ar9002_hw_attach_mac_ops(ah);
577
578 if (modparam_force_new_ani)
579 ath9k_hw_attach_ani_ops_new(ah);
580 else
581 ath9k_hw_attach_ani_ops_old(ah);
582} 575}
583 576
584void ar9002_hw_load_ani_reg(struct ath_hw *ah, struct ath9k_channel *chan) 577void ar9002_hw_load_ani_reg(struct ath_hw *ah, struct ath9k_channel *chan)
@@ -627,6 +620,4 @@ void ar9002_hw_load_ani_reg(struct ath_hw *ah, struct ath9k_channel *chan)
627 } 620 }
628 621
629 REGWRITE_BUFFER_FLUSH(ah); 622 REGWRITE_BUFFER_FLUSH(ah);
630 DISABLE_REGWRITE_BUFFER(ah);
631
632} 623}
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_phy.c b/drivers/net/wireless/ath/ath9k/ar9002_phy.c
index cd56c869270..c00cdc67b55 100644
--- a/drivers/net/wireless/ath/ath9k/ar9002_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar9002_phy.c
@@ -415,7 +415,6 @@ static void ar9002_hw_spur_mitigate(struct ath_hw *ah,
415 REG_WRITE(ah, AR_PHY_MASK2_P_61_45, tmp_mask); 415 REG_WRITE(ah, AR_PHY_MASK2_P_61_45, tmp_mask);
416 416
417 REGWRITE_BUFFER_FLUSH(ah); 417 REGWRITE_BUFFER_FLUSH(ah);
418 DISABLE_REGWRITE_BUFFER(ah);
419} 418}
420 419
421static void ar9002_olc_init(struct ath_hw *ah) 420static void ar9002_olc_init(struct ath_hw *ah)
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_calib.c b/drivers/net/wireless/ath/ath9k/ar9003_calib.c
index 4674ea8c9c9..9e6edffe0bd 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_calib.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_calib.c
@@ -18,6 +18,11 @@
18#include "hw-ops.h" 18#include "hw-ops.h"
19#include "ar9003_phy.h" 19#include "ar9003_phy.h"
20 20
21enum ar9003_cal_types {
22 IQ_MISMATCH_CAL = BIT(0),
23 TEMP_COMP_CAL = BIT(1),
24};
25
21static void ar9003_hw_setup_calibration(struct ath_hw *ah, 26static void ar9003_hw_setup_calibration(struct ath_hw *ah,
22 struct ath9k_cal_list *currCal) 27 struct ath9k_cal_list *currCal)
23{ 28{
@@ -50,11 +55,6 @@ static void ar9003_hw_setup_calibration(struct ath_hw *ah,
50 ath_print(common, ATH_DBG_CALIBRATE, 55 ath_print(common, ATH_DBG_CALIBRATE,
51 "starting Temperature Compensation Calibration\n"); 56 "starting Temperature Compensation Calibration\n");
52 break; 57 break;
53 case ADC_DC_INIT_CAL:
54 case ADC_GAIN_CAL:
55 case ADC_DC_CAL:
56 /* Not yet */
57 break;
58 } 58 }
59} 59}
60 60
@@ -314,27 +314,6 @@ static const struct ath9k_percal_data iq_cal_single_sample = {
314static void ar9003_hw_init_cal_settings(struct ath_hw *ah) 314static void ar9003_hw_init_cal_settings(struct ath_hw *ah)
315{ 315{
316 ah->iq_caldata.calData = &iq_cal_single_sample; 316 ah->iq_caldata.calData = &iq_cal_single_sample;
317 ah->supp_cals = IQ_MISMATCH_CAL;
318}
319
320static bool ar9003_hw_iscal_supported(struct ath_hw *ah,
321 enum ath9k_cal_types calType)
322{
323 switch (calType & ah->supp_cals) {
324 case IQ_MISMATCH_CAL:
325 /*
326 * XXX: Run IQ Mismatch for non-CCK only
327 * Note that CHANNEL_B is never set though.
328 */
329 return true;
330 case ADC_GAIN_CAL:
331 case ADC_DC_CAL:
332 return false;
333 case TEMP_COMP_CAL:
334 return true;
335 }
336
337 return false;
338} 317}
339 318
340/* 319/*
@@ -773,15 +752,16 @@ static bool ar9003_hw_init_cal(struct ath_hw *ah,
773 752
774 /* Initialize list pointers */ 753 /* Initialize list pointers */
775 ah->cal_list = ah->cal_list_last = ah->cal_list_curr = NULL; 754 ah->cal_list = ah->cal_list_last = ah->cal_list_curr = NULL;
755 ah->supp_cals = IQ_MISMATCH_CAL;
776 756
777 if (ar9003_hw_iscal_supported(ah, IQ_MISMATCH_CAL)) { 757 if (ah->supp_cals & IQ_MISMATCH_CAL) {
778 INIT_CAL(&ah->iq_caldata); 758 INIT_CAL(&ah->iq_caldata);
779 INSERT_CAL(ah, &ah->iq_caldata); 759 INSERT_CAL(ah, &ah->iq_caldata);
780 ath_print(common, ATH_DBG_CALIBRATE, 760 ath_print(common, ATH_DBG_CALIBRATE,
781 "enabling IQ Calibration.\n"); 761 "enabling IQ Calibration.\n");
782 } 762 }
783 763
784 if (ar9003_hw_iscal_supported(ah, TEMP_COMP_CAL)) { 764 if (ah->supp_cals & TEMP_COMP_CAL) {
785 INIT_CAL(&ah->tempCompCalData); 765 INIT_CAL(&ah->tempCompCalData);
786 INSERT_CAL(ah, &ah->tempCompCalData); 766 INSERT_CAL(ah, &ah->tempCompCalData);
787 ath_print(common, ATH_DBG_CALIBRATE, 767 ath_print(common, ATH_DBG_CALIBRATE,
@@ -808,7 +788,6 @@ void ar9003_hw_attach_calib_ops(struct ath_hw *ah)
808 priv_ops->init_cal_settings = ar9003_hw_init_cal_settings; 788 priv_ops->init_cal_settings = ar9003_hw_init_cal_settings;
809 priv_ops->init_cal = ar9003_hw_init_cal; 789 priv_ops->init_cal = ar9003_hw_init_cal;
810 priv_ops->setup_calibration = ar9003_hw_setup_calibration; 790 priv_ops->setup_calibration = ar9003_hw_setup_calibration;
811 priv_ops->iscal_supported = ar9003_hw_iscal_supported;
812 791
813 ops->calibrate = ar9003_hw_calibrate; 792 ops->calibrate = ar9003_hw_calibrate;
814} 793}
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_hw.c b/drivers/net/wireless/ath/ath9k/ar9003_hw.c
index 06416890910..02c970819f7 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_hw.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_hw.c
@@ -333,6 +333,4 @@ void ar9003_hw_attach_ops(struct ath_hw *ah)
333 ar9003_hw_attach_phy_ops(ah); 333 ar9003_hw_attach_phy_ops(ah);
334 ar9003_hw_attach_calib_ops(ah); 334 ar9003_hw_attach_calib_ops(ah);
335 ar9003_hw_attach_mac_ops(ah); 335 ar9003_hw_attach_mac_ops(ah);
336
337 ath9k_hw_attach_ani_ops_new(ah);
338} 336}
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
index a491854fa38..efb05599b84 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
@@ -747,9 +747,9 @@ static void ar9003_hw_set_diversity(struct ath_hw *ah, bool value)
747static bool ar9003_hw_ani_control(struct ath_hw *ah, 747static bool ar9003_hw_ani_control(struct ath_hw *ah,
748 enum ath9k_ani_cmd cmd, int param) 748 enum ath9k_ani_cmd cmd, int param)
749{ 749{
750 struct ar5416AniState *aniState = ah->curani;
751 struct ath_common *common = ath9k_hw_common(ah); 750 struct ath_common *common = ath9k_hw_common(ah);
752 struct ath9k_channel *chan = ah->curchan; 751 struct ath9k_channel *chan = ah->curchan;
752 struct ar5416AniState *aniState = &chan->ani;
753 s32 value, value2; 753 s32 value, value2;
754 754
755 switch (cmd & ah->ani_function) { 755 switch (cmd & ah->ani_function) {
@@ -1005,15 +1005,13 @@ static bool ar9003_hw_ani_control(struct ath_hw *ah,
1005 1005
1006 ath_print(common, ATH_DBG_ANI, 1006 ath_print(common, ATH_DBG_ANI,
1007 "ANI parameters: SI=%d, ofdmWS=%s FS=%d " 1007 "ANI parameters: SI=%d, ofdmWS=%s FS=%d "
1008 "MRCcck=%s listenTime=%d CC=%d listen=%d " 1008 "MRCcck=%s listenTime=%d "
1009 "ofdmErrs=%d cckErrs=%d\n", 1009 "ofdmErrs=%d cckErrs=%d\n",
1010 aniState->spurImmunityLevel, 1010 aniState->spurImmunityLevel,
1011 !aniState->ofdmWeakSigDetectOff ? "on" : "off", 1011 !aniState->ofdmWeakSigDetectOff ? "on" : "off",
1012 aniState->firstepLevel, 1012 aniState->firstepLevel,
1013 !aniState->mrcCCKOff ? "on" : "off", 1013 !aniState->mrcCCKOff ? "on" : "off",
1014 aniState->listenTime, 1014 aniState->listenTime,
1015 aniState->cycleCount,
1016 aniState->listenTime,
1017 aniState->ofdmPhyErrCount, 1015 aniState->ofdmPhyErrCount,
1018 aniState->cckPhyErrCount); 1016 aniState->cckPhyErrCount);
1019 return true; 1017 return true;
@@ -1067,12 +1065,9 @@ static void ar9003_hw_ani_cache_ini_regs(struct ath_hw *ah)
1067 struct ath_common *common = ath9k_hw_common(ah); 1065 struct ath_common *common = ath9k_hw_common(ah);
1068 struct ath9k_channel *chan = ah->curchan; 1066 struct ath9k_channel *chan = ah->curchan;
1069 struct ath9k_ani_default *iniDef; 1067 struct ath9k_ani_default *iniDef;
1070 int index;
1071 u32 val; 1068 u32 val;
1072 1069
1073 index = ath9k_hw_get_ani_channel_idx(ah, chan); 1070 aniState = &ah->curchan->ani;
1074 aniState = &ah->ani[index];
1075 ah->curani = aniState;
1076 iniDef = &aniState->iniDef; 1071 iniDef = &aniState->iniDef;
1077 1072
1078 ath_print(common, ATH_DBG_ANI, 1073 ath_print(common, ATH_DBG_ANI,
@@ -1116,8 +1111,6 @@ static void ar9003_hw_ani_cache_ini_regs(struct ath_hw *ah)
1116 aniState->firstepLevel = ATH9K_ANI_FIRSTEP_LVL_NEW; 1111 aniState->firstepLevel = ATH9K_ANI_FIRSTEP_LVL_NEW;
1117 aniState->ofdmWeakSigDetectOff = !ATH9K_ANI_USE_OFDM_WEAK_SIG; 1112 aniState->ofdmWeakSigDetectOff = !ATH9K_ANI_USE_OFDM_WEAK_SIG;
1118 aniState->mrcCCKOff = !ATH9K_ANI_ENABLE_MRC_CCK; 1113 aniState->mrcCCKOff = !ATH9K_ANI_ENABLE_MRC_CCK;
1119
1120 aniState->cycleCount = 0;
1121} 1114}
1122 1115
1123void ar9003_hw_attach_phy_ops(struct ath_hw *ah) 1116void ar9003_hw_attach_phy_ops(struct ath_hw *ah)
@@ -1232,7 +1225,7 @@ void ar9003_hw_bb_watchdog_read(struct ath_hw *ah)
1232void ar9003_hw_bb_watchdog_dbg_info(struct ath_hw *ah) 1225void ar9003_hw_bb_watchdog_dbg_info(struct ath_hw *ah)
1233{ 1226{
1234 struct ath_common *common = ath9k_hw_common(ah); 1227 struct ath_common *common = ath9k_hw_common(ah);
1235 u32 rxc_pcnt = 0, rxf_pcnt = 0, txf_pcnt = 0, status; 1228 u32 status;
1236 1229
1237 if (likely(!(common->debug_mask & ATH_DBG_RESET))) 1230 if (likely(!(common->debug_mask & ATH_DBG_RESET)))
1238 return; 1231 return;
@@ -1261,11 +1254,13 @@ void ar9003_hw_bb_watchdog_dbg_info(struct ath_hw *ah)
1261 "** BB mode: BB_gen_controls=0x%08x **\n", 1254 "** BB mode: BB_gen_controls=0x%08x **\n",
1262 REG_READ(ah, AR_PHY_GEN_CTRL)); 1255 REG_READ(ah, AR_PHY_GEN_CTRL));
1263 1256
1264 if (ath9k_hw_GetMibCycleCountsPct(ah, &rxc_pcnt, &rxf_pcnt, &txf_pcnt)) 1257 ath9k_hw_update_cycle_counters(ah);
1258#define PCT(_field) (ah->cc_delta._field * 100 / ah->cc_delta.cycles)
1259 if (ah->cc_delta.cycles)
1265 ath_print(common, ATH_DBG_RESET, 1260 ath_print(common, ATH_DBG_RESET,
1266 "** BB busy times: rx_clear=%d%%, " 1261 "** BB busy times: rx_clear=%d%%, "
1267 "rx_frame=%d%%, tx_frame=%d%% **\n", 1262 "rx_frame=%d%%, tx_frame=%d%% **\n",
1268 rxc_pcnt, rxf_pcnt, txf_pcnt); 1263 PCT(rx_clear), PCT(rx_frame), PCT(tx_frame));
1269 1264
1270 ath_print(common, ATH_DBG_RESET, 1265 ath_print(common, ATH_DBG_RESET,
1271 "==== BB update: done ====\n\n"); 1266 "==== BB update: done ====\n\n");
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index 9f8e542ef47..de2b18ee7f7 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -241,7 +241,6 @@ struct ath_buf {
241 dma_addr_t bf_daddr; /* physical addr of desc */ 241 dma_addr_t bf_daddr; /* physical addr of desc */
242 dma_addr_t bf_buf_addr; /* physical addr of data buffer */ 242 dma_addr_t bf_buf_addr; /* physical addr of data buffer */
243 bool bf_stale; 243 bool bf_stale;
244 bool bf_isnullfunc;
245 bool bf_tx_aborted; 244 bool bf_tx_aborted;
246 u16 bf_flags; 245 u16 bf_flags;
247 struct ath_buf_state bf_state; 246 struct ath_buf_state bf_state;
@@ -349,7 +348,6 @@ int ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta,
349 u16 tid, u16 *ssn); 348 u16 tid, u16 *ssn);
350void ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid); 349void ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid);
351void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid); 350void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid);
352void ath9k_enable_ps(struct ath_softc *sc);
353 351
354/********/ 352/********/
355/* VIFs */ 353/* VIFs */
@@ -573,8 +571,6 @@ struct ath_ant_comb {
573#define PS_WAIT_FOR_PSPOLL_DATA BIT(2) 571#define PS_WAIT_FOR_PSPOLL_DATA BIT(2)
574#define PS_WAIT_FOR_TX_ACK BIT(3) 572#define PS_WAIT_FOR_TX_ACK BIT(3)
575#define PS_BEACON_SYNC BIT(4) 573#define PS_BEACON_SYNC BIT(4)
576#define PS_NULLFUNC_COMPLETED BIT(5)
577#define PS_ENABLED BIT(6)
578 574
579struct ath_wiphy; 575struct ath_wiphy;
580struct ath_rate_table; 576struct ath_rate_table;
diff --git a/drivers/net/wireless/ath/ath9k/calib.c b/drivers/net/wireless/ath/ath9k/calib.c
index 67ee5d735cc..6d509484b5f 100644
--- a/drivers/net/wireless/ath/ath9k/calib.c
+++ b/drivers/net/wireless/ath/ath9k/calib.c
@@ -186,7 +186,7 @@ bool ath9k_hw_reset_calvalid(struct ath_hw *ah)
186 return true; 186 return true;
187 } 187 }
188 188
189 if (!ath9k_hw_iscal_supported(ah, currCal->calData->calType)) 189 if (!(ah->supp_cals & currCal->calData->calType))
190 return true; 190 return true;
191 191
192 ath_print(common, ATH_DBG_CALIBRATE, 192 ath_print(common, ATH_DBG_CALIBRATE,
@@ -300,7 +300,6 @@ void ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan)
300 } 300 }
301 } 301 }
302 REGWRITE_BUFFER_FLUSH(ah); 302 REGWRITE_BUFFER_FLUSH(ah);
303 DISABLE_REGWRITE_BUFFER(ah);
304} 303}
305 304
306 305
@@ -346,34 +345,34 @@ bool ath9k_hw_getnf(struct ath_hw *ah, struct ath9k_channel *chan)
346 struct ieee80211_channel *c = chan->chan; 345 struct ieee80211_channel *c = chan->chan;
347 struct ath9k_hw_cal_data *caldata = ah->caldata; 346 struct ath9k_hw_cal_data *caldata = ah->caldata;
348 347
349 if (!caldata)
350 return false;
351
352 chan->channelFlags &= (~CHANNEL_CW_INT); 348 chan->channelFlags &= (~CHANNEL_CW_INT);
353 if (REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF) { 349 if (REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF) {
354 ath_print(common, ATH_DBG_CALIBRATE, 350 ath_print(common, ATH_DBG_CALIBRATE,
355 "NF did not complete in calibration window\n"); 351 "NF did not complete in calibration window\n");
356 nf = 0;
357 caldata->rawNoiseFloor = nf;
358 return false; 352 return false;
359 } else { 353 }
360 ath9k_hw_do_getnf(ah, nfarray); 354
361 ath9k_hw_nf_sanitize(ah, nfarray); 355 ath9k_hw_do_getnf(ah, nfarray);
362 nf = nfarray[0]; 356 ath9k_hw_nf_sanitize(ah, nfarray);
363 if (ath9k_hw_get_nf_thresh(ah, c->band, &nfThresh) 357 nf = nfarray[0];
364 && nf > nfThresh) { 358 if (ath9k_hw_get_nf_thresh(ah, c->band, &nfThresh)
365 ath_print(common, ATH_DBG_CALIBRATE, 359 && nf > nfThresh) {
366 "noise floor failed detected; " 360 ath_print(common, ATH_DBG_CALIBRATE,
367 "detected %d, threshold %d\n", 361 "noise floor failed detected; "
368 nf, nfThresh); 362 "detected %d, threshold %d\n",
369 chan->channelFlags |= CHANNEL_CW_INT; 363 nf, nfThresh);
370 } 364 chan->channelFlags |= CHANNEL_CW_INT;
365 }
366
367 if (!caldata) {
368 chan->noisefloor = nf;
369 return false;
371 } 370 }
372 371
373 h = caldata->nfCalHist; 372 h = caldata->nfCalHist;
374 caldata->nfcal_pending = false; 373 caldata->nfcal_pending = false;
375 ath9k_hw_update_nfcal_hist_buffer(ah, caldata, nfarray); 374 ath9k_hw_update_nfcal_hist_buffer(ah, caldata, nfarray);
376 caldata->rawNoiseFloor = h[0].privNF; 375 chan->noisefloor = h[0].privNF;
377 return true; 376 return true;
378} 377}
379 378
@@ -401,10 +400,10 @@ void ath9k_init_nfcal_hist_buffer(struct ath_hw *ah,
401 400
402s16 ath9k_hw_getchan_noise(struct ath_hw *ah, struct ath9k_channel *chan) 401s16 ath9k_hw_getchan_noise(struct ath_hw *ah, struct ath9k_channel *chan)
403{ 402{
404 if (!ah->caldata || !ah->caldata->rawNoiseFloor) 403 if (!ah->curchan || !ah->curchan->noisefloor)
405 return ath9k_hw_get_default_nf(ah, chan); 404 return ath9k_hw_get_default_nf(ah, chan);
406 405
407 return ah->caldata->rawNoiseFloor; 406 return ah->curchan->noisefloor;
408} 407}
409EXPORT_SYMBOL(ath9k_hw_getchan_noise); 408EXPORT_SYMBOL(ath9k_hw_getchan_noise);
410 409
diff --git a/drivers/net/wireless/ath/ath9k/calib.h b/drivers/net/wireless/ath/ath9k/calib.h
index 5b053a6260b..b8973eb8d85 100644
--- a/drivers/net/wireless/ath/ath9k/calib.h
+++ b/drivers/net/wireless/ath/ath9k/calib.h
@@ -58,14 +58,6 @@ struct ar5416IniArray {
58 } \ 58 } \
59 } while (0) 59 } while (0)
60 60
61enum ath9k_cal_types {
62 ADC_DC_INIT_CAL = 0x1,
63 ADC_GAIN_CAL = 0x2,
64 ADC_DC_CAL = 0x4,
65 IQ_MISMATCH_CAL = 0x8,
66 TEMP_COMP_CAL = 0x10,
67};
68
69enum ath9k_cal_state { 61enum ath9k_cal_state {
70 CAL_INACTIVE, 62 CAL_INACTIVE,
71 CAL_WAITING, 63 CAL_WAITING,
@@ -80,7 +72,7 @@ enum ath9k_cal_state {
80#define PER_MAX_LOG_COUNT 10 72#define PER_MAX_LOG_COUNT 10
81 73
82struct ath9k_percal_data { 74struct ath9k_percal_data {
83 enum ath9k_cal_types calType; 75 u32 calType;
84 u32 calNumSamples; 76 u32 calNumSamples;
85 u32 calCountMax; 77 u32 calCountMax;
86 void (*calCollect) (struct ath_hw *); 78 void (*calCollect) (struct ath_hw *);
diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c
index d65a896a421..74a4570dc87 100644
--- a/drivers/net/wireless/ath/ath9k/debug.c
+++ b/drivers/net/wireless/ath/ath9k/debug.c
@@ -488,6 +488,8 @@ static ssize_t read_file_wiphy(struct file *file, char __user *user_buf,
488 size_t count, loff_t *ppos) 488 size_t count, loff_t *ppos)
489{ 489{
490 struct ath_softc *sc = file->private_data; 490 struct ath_softc *sc = file->private_data;
491 struct ath_wiphy *aphy = sc->pri_wiphy;
492 struct ieee80211_channel *chan = aphy->hw->conf.channel;
491 char buf[512]; 493 char buf[512];
492 unsigned int len = 0; 494 unsigned int len = 0;
493 int i; 495 int i;
@@ -498,7 +500,8 @@ static ssize_t read_file_wiphy(struct file *file, char __user *user_buf,
498 "primary: %s (%s chan=%d ht=%d)\n", 500 "primary: %s (%s chan=%d ht=%d)\n",
499 wiphy_name(sc->pri_wiphy->hw->wiphy), 501 wiphy_name(sc->pri_wiphy->hw->wiphy),
500 ath_wiphy_state_str(sc->pri_wiphy->state), 502 ath_wiphy_state_str(sc->pri_wiphy->state),
501 sc->pri_wiphy->chan_idx, sc->pri_wiphy->chan_is_ht); 503 ieee80211_frequency_to_channel(chan->center_freq),
504 aphy->chan_is_ht);
502 505
503 put_unaligned_le32(REG_READ_D(sc->sc_ah, AR_STA_ID0), addr); 506 put_unaligned_le32(REG_READ_D(sc->sc_ah, AR_STA_ID0), addr);
504 put_unaligned_le16(REG_READ_D(sc->sc_ah, AR_STA_ID1) & 0xffff, addr + 4); 507 put_unaligned_le16(REG_READ_D(sc->sc_ah, AR_STA_ID1) & 0xffff, addr + 4);
@@ -545,11 +548,13 @@ static ssize_t read_file_wiphy(struct file *file, char __user *user_buf,
545 struct ath_wiphy *aphy = sc->sec_wiphy[i]; 548 struct ath_wiphy *aphy = sc->sec_wiphy[i];
546 if (aphy == NULL) 549 if (aphy == NULL)
547 continue; 550 continue;
551 chan = aphy->hw->conf.channel;
548 len += snprintf(buf + len, sizeof(buf) - len, 552 len += snprintf(buf + len, sizeof(buf) - len,
549 "secondary: %s (%s chan=%d ht=%d)\n", 553 "secondary: %s (%s chan=%d ht=%d)\n",
550 wiphy_name(aphy->hw->wiphy), 554 wiphy_name(aphy->hw->wiphy),
551 ath_wiphy_state_str(aphy->state), 555 ath_wiphy_state_str(aphy->state),
552 aphy->chan_idx, aphy->chan_is_ht); 556 ieee80211_frequency_to_channel(chan->center_freq),
557 aphy->chan_is_ht);
553 } 558 }
554 if (len > sizeof(buf)) 559 if (len > sizeof(buf))
555 len = sizeof(buf); 560 len = sizeof(buf);
@@ -696,6 +701,8 @@ static ssize_t read_file_xmit(struct file *file, char __user *user_buf,
696 PR("DESC CFG Error: ", desc_cfg_err); 701 PR("DESC CFG Error: ", desc_cfg_err);
697 PR("DATA Underrun: ", data_underrun); 702 PR("DATA Underrun: ", data_underrun);
698 PR("DELIM Underrun: ", delim_underrun); 703 PR("DELIM Underrun: ", delim_underrun);
704 PR("TX-Pkts-All: ", tx_pkts_all);
705 PR("TX-Bytes-All: ", tx_bytes_all);
699 706
700 if (len > size) 707 if (len > size)
701 len = size; 708 len = size;
@@ -709,6 +716,9 @@ static ssize_t read_file_xmit(struct file *file, char __user *user_buf,
709void ath_debug_stat_tx(struct ath_softc *sc, struct ath_txq *txq, 716void ath_debug_stat_tx(struct ath_softc *sc, struct ath_txq *txq,
710 struct ath_buf *bf, struct ath_tx_status *ts) 717 struct ath_buf *bf, struct ath_tx_status *ts)
711{ 718{
719 TX_STAT_INC(txq->axq_qnum, tx_pkts_all);
720 sc->debug.stats.txstats[txq->axq_qnum].tx_bytes_all += bf->bf_mpdu->len;
721
712 if (bf_isampdu(bf)) { 722 if (bf_isampdu(bf)) {
713 if (bf_isxretried(bf)) 723 if (bf_isxretried(bf))
714 TX_STAT_INC(txq->axq_qnum, a_xretries); 724 TX_STAT_INC(txq->axq_qnum, a_xretries);
@@ -803,6 +813,13 @@ static ssize_t read_file_recv(struct file *file, char __user *user_buf,
803 PHY_ERR("HT-LENGTH", ATH9K_PHYERR_HT_LENGTH_ILLEGAL); 813 PHY_ERR("HT-LENGTH", ATH9K_PHYERR_HT_LENGTH_ILLEGAL);
804 PHY_ERR("HT-RATE", ATH9K_PHYERR_HT_RATE_ILLEGAL); 814 PHY_ERR("HT-RATE", ATH9K_PHYERR_HT_RATE_ILLEGAL);
805 815
816 len += snprintf(buf + len, size - len,
817 "%18s : %10u\n", "RX-Pkts-All",
818 sc->debug.stats.rxstats.rx_pkts_all);
819 len += snprintf(buf + len, size - len,
820 "%18s : %10u\n", "RX-Bytes-All",
821 sc->debug.stats.rxstats.rx_bytes_all);
822
806 if (len > size) 823 if (len > size)
807 len = size; 824 len = size;
808 825
@@ -821,6 +838,9 @@ void ath_debug_stat_rx(struct ath_softc *sc, struct ath_rx_status *rs)
821 838
822 u32 phyerr; 839 u32 phyerr;
823 840
841 RX_STAT_INC(rx_pkts_all);
842 sc->debug.stats.rxstats.rx_bytes_all += rs->rs_datalen;
843
824 if (rs->rs_status & ATH9K_RXERR_CRC) 844 if (rs->rs_status & ATH9K_RXERR_CRC)
825 RX_STAT_INC(crc_err); 845 RX_STAT_INC(crc_err);
826 if (rs->rs_status & ATH9K_RXERR_DECRYPT) 846 if (rs->rs_status & ATH9K_RXERR_DECRYPT)
diff --git a/drivers/net/wireless/ath/ath9k/debug.h b/drivers/net/wireless/ath/ath9k/debug.h
index 5d21704e87f..822b6f3f23c 100644
--- a/drivers/net/wireless/ath/ath9k/debug.h
+++ b/drivers/net/wireless/ath/ath9k/debug.h
@@ -89,6 +89,10 @@ struct ath_rc_stats {
89 89
90/** 90/**
91 * struct ath_tx_stats - Statistics about TX 91 * struct ath_tx_stats - Statistics about TX
92 * @tx_pkts_all: No. of total frames transmitted, including ones that
93 may have had errors.
94 * @tx_bytes_all: No. of total bytes transmitted, including ones that
95 may have had errors.
92 * @queued: Total MPDUs (non-aggr) queued 96 * @queued: Total MPDUs (non-aggr) queued
93 * @completed: Total MPDUs (non-aggr) completed 97 * @completed: Total MPDUs (non-aggr) completed
94 * @a_aggr: Total no. of aggregates queued 98 * @a_aggr: Total no. of aggregates queued
@@ -107,6 +111,8 @@ struct ath_rc_stats {
107 * @delim_urn: TX delimiter underrun errors 111 * @delim_urn: TX delimiter underrun errors
108 */ 112 */
109struct ath_tx_stats { 113struct ath_tx_stats {
114 u32 tx_pkts_all;
115 u32 tx_bytes_all;
110 u32 queued; 116 u32 queued;
111 u32 completed; 117 u32 completed;
112 u32 a_aggr; 118 u32 a_aggr;
@@ -124,6 +130,10 @@ struct ath_tx_stats {
124 130
125/** 131/**
126 * struct ath_rx_stats - RX Statistics 132 * struct ath_rx_stats - RX Statistics
133 * @rx_pkts_all: No. of total frames received, including ones that
134 may have had errors.
135 * @rx_bytes_all: No. of total bytes received, including ones that
136 may have had errors.
127 * @crc_err: No. of frames with incorrect CRC value 137 * @crc_err: No. of frames with incorrect CRC value
128 * @decrypt_crc_err: No. of frames whose CRC check failed after 138 * @decrypt_crc_err: No. of frames whose CRC check failed after
129 decryption process completed 139 decryption process completed
@@ -136,6 +146,8 @@ struct ath_tx_stats {
136 * @phy_err_stats: Individual PHY error statistics 146 * @phy_err_stats: Individual PHY error statistics
137 */ 147 */
138struct ath_rx_stats { 148struct ath_rx_stats {
149 u32 rx_pkts_all;
150 u32 rx_bytes_all;
139 u32 crc_err; 151 u32 crc_err;
140 u32 decrypt_crc_err; 152 u32 decrypt_crc_err;
141 u32 phy_err; 153 u32 phy_err;
diff --git a/drivers/net/wireless/ath/ath9k/eeprom_4k.c b/drivers/net/wireless/ath/ath9k/eeprom_4k.c
index d6eed1f02e8..4fa4d8e28c6 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom_4k.c
+++ b/drivers/net/wireless/ath/ath9k/eeprom_4k.c
@@ -179,6 +179,9 @@ static u32 ath9k_hw_4k_get_eeprom(struct ath_hw *ah,
179 struct ar5416_eeprom_4k *eep = &ah->eeprom.map4k; 179 struct ar5416_eeprom_4k *eep = &ah->eeprom.map4k;
180 struct modal_eep_4k_header *pModal = &eep->modalHeader; 180 struct modal_eep_4k_header *pModal = &eep->modalHeader;
181 struct base_eep_header_4k *pBase = &eep->baseEepHeader; 181 struct base_eep_header_4k *pBase = &eep->baseEepHeader;
182 u16 ver_minor;
183
184 ver_minor = pBase->version & AR5416_EEP_VER_MINOR_MASK;
182 185
183 switch (param) { 186 switch (param) {
184 case EEP_NFTHRESH_2: 187 case EEP_NFTHRESH_2:
@@ -204,7 +207,7 @@ static u32 ath9k_hw_4k_get_eeprom(struct ath_hw *ah,
204 case EEP_DB_2: 207 case EEP_DB_2:
205 return pModal->db1_1; 208 return pModal->db1_1;
206 case EEP_MINOR_REV: 209 case EEP_MINOR_REV:
207 return pBase->version & AR5416_EEP_VER_MINOR_MASK; 210 return ver_minor;
208 case EEP_TX_MASK: 211 case EEP_TX_MASK:
209 return pBase->txMask; 212 return pBase->txMask;
210 case EEP_RX_MASK: 213 case EEP_RX_MASK:
@@ -217,6 +220,11 @@ static u32 ath9k_hw_4k_get_eeprom(struct ath_hw *ah,
217 return pModal->version; 220 return pModal->version;
218 case EEP_ANT_DIV_CTL1: 221 case EEP_ANT_DIV_CTL1:
219 return pModal->antdiv_ctl1; 222 return pModal->antdiv_ctl1;
223 case EEP_TXGAIN_TYPE:
224 if (ver_minor >= AR5416_EEP_MINOR_VER_19)
225 return pBase->txGainType;
226 else
227 return AR5416_EEP_TXGAIN_ORIGINAL;
220 default: 228 default:
221 return 0; 229 return 0;
222 } 230 }
@@ -500,7 +508,6 @@ static void ath9k_hw_set_4k_power_cal_table(struct ath_hw *ah,
500 } 508 }
501 509
502 REGWRITE_BUFFER_FLUSH(ah); 510 REGWRITE_BUFFER_FLUSH(ah);
503 DISABLE_REGWRITE_BUFFER(ah);
504 } 511 }
505 } 512 }
506 513
@@ -832,7 +839,6 @@ static void ath9k_hw_4k_set_txpower(struct ath_hw *ah,
832 } 839 }
833 840
834 REGWRITE_BUFFER_FLUSH(ah); 841 REGWRITE_BUFFER_FLUSH(ah);
835 DISABLE_REGWRITE_BUFFER(ah);
836} 842}
837 843
838static void ath9k_hw_4k_set_addac(struct ath_hw *ah, 844static void ath9k_hw_4k_set_addac(struct ath_hw *ah,
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c
index b100db2766c..bbb54bc28a4 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c
@@ -380,15 +380,6 @@ static void ath9k_enable_regwrite_buffer(void *hw_priv)
380 atomic_inc(&priv->wmi->mwrite_cnt); 380 atomic_inc(&priv->wmi->mwrite_cnt);
381} 381}
382 382
383static void ath9k_disable_regwrite_buffer(void *hw_priv)
384{
385 struct ath_hw *ah = (struct ath_hw *) hw_priv;
386 struct ath_common *common = ath9k_hw_common(ah);
387 struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv;
388
389 atomic_dec(&priv->wmi->mwrite_cnt);
390}
391
392static void ath9k_regwrite_flush(void *hw_priv) 383static void ath9k_regwrite_flush(void *hw_priv)
393{ 384{
394 struct ath_hw *ah = (struct ath_hw *) hw_priv; 385 struct ath_hw *ah = (struct ath_hw *) hw_priv;
@@ -397,6 +388,8 @@ static void ath9k_regwrite_flush(void *hw_priv)
397 u32 rsp_status; 388 u32 rsp_status;
398 int r; 389 int r;
399 390
391 atomic_dec(&priv->wmi->mwrite_cnt);
392
400 mutex_lock(&priv->wmi->multi_write_mutex); 393 mutex_lock(&priv->wmi->multi_write_mutex);
401 394
402 if (priv->wmi->multi_write_idx) { 395 if (priv->wmi->multi_write_idx) {
@@ -420,7 +413,6 @@ static const struct ath_ops ath9k_common_ops = {
420 .read = ath9k_regread, 413 .read = ath9k_regread,
421 .write = ath9k_regwrite, 414 .write = ath9k_regwrite,
422 .enable_write_buffer = ath9k_enable_regwrite_buffer, 415 .enable_write_buffer = ath9k_enable_regwrite_buffer,
423 .disable_write_buffer = ath9k_disable_regwrite_buffer,
424 .write_flush = ath9k_regwrite_flush, 416 .write_flush = ath9k_regwrite_flush,
425}; 417};
426 418
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
index 5124d04b240..f12591f5d02 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
@@ -760,23 +760,12 @@ void ath9k_ani_work(struct work_struct *work)
760 ath9k_hw_ani_monitor(ah, ah->curchan); 760 ath9k_hw_ani_monitor(ah, ah->curchan);
761 761
762 /* Perform calibration if necessary */ 762 /* Perform calibration if necessary */
763 if (longcal || shortcal) { 763 if (longcal || shortcal)
764 common->ani.caldone = 764 common->ani.caldone =
765 ath9k_hw_calibrate(ah, ah->curchan, 765 ath9k_hw_calibrate(ah, ah->curchan,
766 common->rx_chainmask, 766 common->rx_chainmask,
767 longcal); 767 longcal);
768 768
769 if (longcal)
770 common->ani.noise_floor =
771 ath9k_hw_getchan_noise(ah, ah->curchan);
772
773 ath_print(common, ATH_DBG_ANI,
774 " calibrate chan %u/%x nf: %d\n",
775 ah->curchan->channel,
776 ah->curchan->channelFlags,
777 common->ani.noise_floor);
778 }
779
780 ath9k_htc_ps_restore(priv); 769 ath9k_htc_ps_restore(priv);
781 } 770 }
782 771
diff --git a/drivers/net/wireless/ath/ath9k/hw-ops.h b/drivers/net/wireless/ath/ath9k/hw-ops.h
index ffecbadaea4..0a4ad348b69 100644
--- a/drivers/net/wireless/ath/ath9k/hw-ops.h
+++ b/drivers/net/wireless/ath/ath9k/hw-ops.h
@@ -128,17 +128,6 @@ static inline void ath9k_hw_set11n_virtualmorefrag(struct ath_hw *ah, void *ds,
128 ath9k_hw_ops(ah)->set11n_virtualmorefrag(ah, ds, vmf); 128 ath9k_hw_ops(ah)->set11n_virtualmorefrag(ah, ds, vmf);
129} 129}
130 130
131static inline void ath9k_hw_procmibevent(struct ath_hw *ah)
132{
133 ath9k_hw_ops(ah)->ani_proc_mib_event(ah);
134}
135
136static inline void ath9k_hw_ani_monitor(struct ath_hw *ah,
137 struct ath9k_channel *chan)
138{
139 ath9k_hw_ops(ah)->ani_monitor(ah, chan);
140}
141
142/* Private hardware call ops */ 131/* Private hardware call ops */
143 132
144/* PHY ops */ 133/* PHY ops */
@@ -276,15 +265,4 @@ static inline void ath9k_hw_setup_calibration(struct ath_hw *ah,
276 ath9k_hw_private_ops(ah)->setup_calibration(ah, currCal); 265 ath9k_hw_private_ops(ah)->setup_calibration(ah, currCal);
277} 266}
278 267
279static inline bool ath9k_hw_iscal_supported(struct ath_hw *ah,
280 enum ath9k_cal_types calType)
281{
282 return ath9k_hw_private_ops(ah)->iscal_supported(ah, calType);
283}
284
285static inline void ath9k_ani_reset(struct ath_hw *ah, bool is_scanning)
286{
287 ath9k_hw_private_ops(ah)->ani_reset(ah, is_scanning);
288}
289
290#endif /* ATH9K_HW_OPS_H */ 268#endif /* ATH9K_HW_OPS_H */
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 25ed65ac992..05e9935ef16 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -299,7 +299,6 @@ static void ath9k_hw_disablepcie(struct ath_hw *ah)
299 REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000); 299 REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000);
300 300
301 REGWRITE_BUFFER_FLUSH(ah); 301 REGWRITE_BUFFER_FLUSH(ah);
302 DISABLE_REGWRITE_BUFFER(ah);
303} 302}
304 303
305/* This should work for all families including legacy */ 304/* This should work for all families including legacy */
@@ -371,10 +370,6 @@ static void ath9k_hw_init_config(struct ath_hw *ah)
371 ah->config.pcie_clock_req = 0; 370 ah->config.pcie_clock_req = 0;
372 ah->config.pcie_waen = 0; 371 ah->config.pcie_waen = 0;
373 ah->config.analog_shiftreg = 1; 372 ah->config.analog_shiftreg = 1;
374 ah->config.ofdm_trig_low = 200;
375 ah->config.ofdm_trig_high = 500;
376 ah->config.cck_trig_high = 200;
377 ah->config.cck_trig_low = 100;
378 ah->config.enable_ani = true; 373 ah->config.enable_ani = true;
379 374
380 for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) { 375 for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
@@ -676,7 +671,6 @@ static void ath9k_hw_init_qos(struct ath_hw *ah)
676 REG_WRITE(ah, AR_TXOP_12_15, 0xFFFFFFFF); 671 REG_WRITE(ah, AR_TXOP_12_15, 0xFFFFFFFF);
677 672
678 REGWRITE_BUFFER_FLUSH(ah); 673 REGWRITE_BUFFER_FLUSH(ah);
679 DISABLE_REGWRITE_BUFFER(ah);
680} 674}
681 675
682static void ath9k_hw_init_pll(struct ath_hw *ah, 676static void ath9k_hw_init_pll(struct ath_hw *ah,
@@ -741,7 +735,6 @@ static void ath9k_hw_init_interrupt_masks(struct ath_hw *ah,
741 } 735 }
742 736
743 REGWRITE_BUFFER_FLUSH(ah); 737 REGWRITE_BUFFER_FLUSH(ah);
744 DISABLE_REGWRITE_BUFFER(ah);
745 738
746 if (AR_SREV_9300_20_OR_LATER(ah)) { 739 if (AR_SREV_9300_20_OR_LATER(ah)) {
747 REG_WRITE(ah, AR_INTR_PRIO_ASYNC_ENABLE, 0); 740 REG_WRITE(ah, AR_INTR_PRIO_ASYNC_ENABLE, 0);
@@ -885,7 +878,6 @@ static inline void ath9k_hw_set_dma(struct ath_hw *ah)
885 REG_WRITE(ah, AR_TXCFG, regval | AR_TXCFG_DMASZ_128B); 878 REG_WRITE(ah, AR_TXCFG, regval | AR_TXCFG_DMASZ_128B);
886 879
887 REGWRITE_BUFFER_FLUSH(ah); 880 REGWRITE_BUFFER_FLUSH(ah);
888 DISABLE_REGWRITE_BUFFER(ah);
889 881
890 /* 882 /*
891 * Restore TX Trigger Level to its pre-reset value. 883 * Restore TX Trigger Level to its pre-reset value.
@@ -933,7 +925,6 @@ static inline void ath9k_hw_set_dma(struct ath_hw *ah)
933 } 925 }
934 926
935 REGWRITE_BUFFER_FLUSH(ah); 927 REGWRITE_BUFFER_FLUSH(ah);
936 DISABLE_REGWRITE_BUFFER(ah);
937 928
938 if (AR_SREV_9300_20_OR_LATER(ah)) 929 if (AR_SREV_9300_20_OR_LATER(ah))
939 ath9k_hw_reset_txstatus_ring(ah); 930 ath9k_hw_reset_txstatus_ring(ah);
@@ -1031,7 +1022,6 @@ static bool ath9k_hw_set_reset(struct ath_hw *ah, int type)
1031 REG_WRITE(ah, AR_RTC_RC, rst_flags); 1022 REG_WRITE(ah, AR_RTC_RC, rst_flags);
1032 1023
1033 REGWRITE_BUFFER_FLUSH(ah); 1024 REGWRITE_BUFFER_FLUSH(ah);
1034 DISABLE_REGWRITE_BUFFER(ah);
1035 1025
1036 udelay(50); 1026 udelay(50);
1037 1027
@@ -1070,7 +1060,6 @@ static bool ath9k_hw_set_reset_power_on(struct ath_hw *ah)
1070 udelay(2); 1060 udelay(2);
1071 1061
1072 REGWRITE_BUFFER_FLUSH(ah); 1062 REGWRITE_BUFFER_FLUSH(ah);
1073 DISABLE_REGWRITE_BUFFER(ah);
1074 1063
1075 if (!AR_SREV_9300_20_OR_LATER(ah)) 1064 if (!AR_SREV_9300_20_OR_LATER(ah))
1076 udelay(2); 1065 udelay(2);
@@ -1239,7 +1228,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
1239 if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE)) 1228 if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE))
1240 return -EIO; 1229 return -EIO;
1241 1230
1242 if (curchan && !ah->chip_fullsleep && ah->caldata) 1231 if (curchan && !ah->chip_fullsleep)
1243 ath9k_hw_getnf(ah, curchan); 1232 ath9k_hw_getnf(ah, curchan);
1244 1233
1245 ah->caldata = caldata; 1234 ah->caldata = caldata;
@@ -1374,7 +1363,6 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
1374 REG_WRITE(ah, AR_RSSI_THR, INIT_RSSI_THR); 1363 REG_WRITE(ah, AR_RSSI_THR, INIT_RSSI_THR);
1375 1364
1376 REGWRITE_BUFFER_FLUSH(ah); 1365 REGWRITE_BUFFER_FLUSH(ah);
1377 DISABLE_REGWRITE_BUFFER(ah);
1378 1366
1379 r = ath9k_hw_rf_set_freq(ah, chan); 1367 r = ath9k_hw_rf_set_freq(ah, chan);
1380 if (r) 1368 if (r)
@@ -1386,7 +1374,6 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
1386 REG_WRITE(ah, AR_DQCUMASK(i), 1 << i); 1374 REG_WRITE(ah, AR_DQCUMASK(i), 1 << i);
1387 1375
1388 REGWRITE_BUFFER_FLUSH(ah); 1376 REGWRITE_BUFFER_FLUSH(ah);
1389 DISABLE_REGWRITE_BUFFER(ah);
1390 1377
1391 ah->intr_txqs = 0; 1378 ah->intr_txqs = 0;
1392 for (i = 0; i < ah->caps.total_queues; i++) 1379 for (i = 0; i < ah->caps.total_queues; i++)
@@ -1434,7 +1421,6 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
1434 REG_WRITE(ah, AR_CFG_LED, saveLedState | AR_CFG_SCLK_32KHZ); 1421 REG_WRITE(ah, AR_CFG_LED, saveLedState | AR_CFG_SCLK_32KHZ);
1435 1422
1436 REGWRITE_BUFFER_FLUSH(ah); 1423 REGWRITE_BUFFER_FLUSH(ah);
1437 DISABLE_REGWRITE_BUFFER(ah);
1438 1424
1439 /* 1425 /*
1440 * For big endian systems turn on swapping for descriptors 1426 * For big endian systems turn on swapping for descriptors
@@ -1684,7 +1670,6 @@ void ath9k_hw_beaconinit(struct ath_hw *ah, u32 next_beacon, u32 beacon_period)
1684 REG_WRITE(ah, AR_NDP_PERIOD, TU_TO_USEC(beacon_period)); 1670 REG_WRITE(ah, AR_NDP_PERIOD, TU_TO_USEC(beacon_period));
1685 1671
1686 REGWRITE_BUFFER_FLUSH(ah); 1672 REGWRITE_BUFFER_FLUSH(ah);
1687 DISABLE_REGWRITE_BUFFER(ah);
1688 1673
1689 beacon_period &= ~ATH9K_BEACON_ENA; 1674 beacon_period &= ~ATH9K_BEACON_ENA;
1690 if (beacon_period & ATH9K_BEACON_RESET_TSF) { 1675 if (beacon_period & ATH9K_BEACON_RESET_TSF) {
@@ -1712,7 +1697,6 @@ void ath9k_hw_set_sta_beacon_timers(struct ath_hw *ah,
1712 TU_TO_USEC(bs->bs_intval & ATH9K_BEACON_PERIOD)); 1697 TU_TO_USEC(bs->bs_intval & ATH9K_BEACON_PERIOD));
1713 1698
1714 REGWRITE_BUFFER_FLUSH(ah); 1699 REGWRITE_BUFFER_FLUSH(ah);
1715 DISABLE_REGWRITE_BUFFER(ah);
1716 1700
1717 REG_RMW_FIELD(ah, AR_RSSI_THR, 1701 REG_RMW_FIELD(ah, AR_RSSI_THR,
1718 AR_RSSI_THR_BM_THR, bs->bs_bmissthreshold); 1702 AR_RSSI_THR_BM_THR, bs->bs_bmissthreshold);
@@ -1758,7 +1742,6 @@ void ath9k_hw_set_sta_beacon_timers(struct ath_hw *ah,
1758 REG_WRITE(ah, AR_DTIM_PERIOD, TU_TO_USEC(dtimperiod)); 1742 REG_WRITE(ah, AR_DTIM_PERIOD, TU_TO_USEC(dtimperiod));
1759 1743
1760 REGWRITE_BUFFER_FLUSH(ah); 1744 REGWRITE_BUFFER_FLUSH(ah);
1761 DISABLE_REGWRITE_BUFFER(ah);
1762 1745
1763 REG_SET_BIT(ah, AR_TIMER_MODE, 1746 REG_SET_BIT(ah, AR_TIMER_MODE,
1764 AR_TBTT_TIMER_EN | AR_TIM_TIMER_EN | 1747 AR_TBTT_TIMER_EN | AR_TIM_TIMER_EN |
@@ -2176,7 +2159,6 @@ void ath9k_hw_setrxfilter(struct ath_hw *ah, u32 bits)
2176 REG_READ(ah, AR_RXCFG) & ~AR_RXCFG_ZLFDMA); 2159 REG_READ(ah, AR_RXCFG) & ~AR_RXCFG_ZLFDMA);
2177 2160
2178 REGWRITE_BUFFER_FLUSH(ah); 2161 REGWRITE_BUFFER_FLUSH(ah);
2179 DISABLE_REGWRITE_BUFFER(ah);
2180} 2162}
2181EXPORT_SYMBOL(ath9k_hw_setrxfilter); 2163EXPORT_SYMBOL(ath9k_hw_setrxfilter);
2182 2164
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index df47f792cf4..87627dd6346 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -70,19 +70,13 @@
70 70
71#define ENABLE_REGWRITE_BUFFER(_ah) \ 71#define ENABLE_REGWRITE_BUFFER(_ah) \
72 do { \ 72 do { \
73 if (AR_SREV_9271(_ah)) \ 73 if (ath9k_hw_common(_ah)->ops->enable_write_buffer) \
74 ath9k_hw_common(_ah)->ops->enable_write_buffer((_ah)); \ 74 ath9k_hw_common(_ah)->ops->enable_write_buffer((_ah)); \
75 } while (0) 75 } while (0)
76 76
77#define DISABLE_REGWRITE_BUFFER(_ah) \
78 do { \
79 if (AR_SREV_9271(_ah)) \
80 ath9k_hw_common(_ah)->ops->disable_write_buffer((_ah)); \
81 } while (0)
82
83#define REGWRITE_BUFFER_FLUSH(_ah) \ 77#define REGWRITE_BUFFER_FLUSH(_ah) \
84 do { \ 78 do { \
85 if (AR_SREV_9271(_ah)) \ 79 if (ath9k_hw_common(_ah)->ops->write_flush) \
86 ath9k_hw_common(_ah)->ops->write_flush((_ah)); \ 80 ath9k_hw_common(_ah)->ops->write_flush((_ah)); \
87 } while (0) 81 } while (0)
88 82
@@ -342,7 +336,6 @@ struct ath9k_hw_cal_data {
342 int32_t CalValid; 336 int32_t CalValid;
343 int8_t iCoff; 337 int8_t iCoff;
344 int8_t qCoff; 338 int8_t qCoff;
345 int16_t rawNoiseFloor;
346 bool paprd_done; 339 bool paprd_done;
347 bool nfcal_pending; 340 bool nfcal_pending;
348 bool nfcal_interference; 341 bool nfcal_interference;
@@ -353,9 +346,11 @@ struct ath9k_hw_cal_data {
353 346
354struct ath9k_channel { 347struct ath9k_channel {
355 struct ieee80211_channel *chan; 348 struct ieee80211_channel *chan;
349 struct ar5416AniState ani;
356 u16 channel; 350 u16 channel;
357 u32 channelFlags; 351 u32 channelFlags;
358 u32 chanmode; 352 u32 chanmode;
353 s16 noisefloor;
359}; 354};
360 355
361#define IS_CHAN_G(_c) ((((_c)->channelFlags & (CHANNEL_G)) == CHANNEL_G) || \ 356#define IS_CHAN_G(_c) ((((_c)->channelFlags & (CHANNEL_G)) == CHANNEL_G) || \
@@ -514,14 +509,6 @@ struct ath_hw_antcomb_conf {
514 * @setup_calibration: set up calibration 509 * @setup_calibration: set up calibration
515 * @iscal_supported: used to query if a type of calibration is supported 510 * @iscal_supported: used to query if a type of calibration is supported
516 * 511 *
517 * @ani_reset: reset ANI parameters to default values
518 * @ani_lower_immunity: lower the noise immunity level. The level controls
519 * the power-based packet detection on hardware. If a power jump is
520 * detected the adapter takes it as an indication that a packet has
521 * arrived. The level ranges from 0-5. Each level corresponds to a
522 * few dB more of noise immunity. If you have a strong time-varying
523 * interference that is causing false detections (OFDM timing errors or
524 * CCK timing errors) the level can be increased.
525 * @ani_cache_ini_regs: cache the values for ANI from the initial 512 * @ani_cache_ini_regs: cache the values for ANI from the initial
526 * register settings through the register initialization. 513 * register settings through the register initialization.
527 */ 514 */
@@ -535,8 +522,6 @@ struct ath_hw_private_ops {
535 bool (*macversion_supported)(u32 macversion); 522 bool (*macversion_supported)(u32 macversion);
536 void (*setup_calibration)(struct ath_hw *ah, 523 void (*setup_calibration)(struct ath_hw *ah,
537 struct ath9k_cal_list *currCal); 524 struct ath9k_cal_list *currCal);
538 bool (*iscal_supported)(struct ath_hw *ah,
539 enum ath9k_cal_types calType);
540 525
541 /* PHY ops */ 526 /* PHY ops */
542 int (*rf_set_freq)(struct ath_hw *ah, 527 int (*rf_set_freq)(struct ath_hw *ah,
@@ -568,8 +553,6 @@ struct ath_hw_private_ops {
568 void (*do_getnf)(struct ath_hw *ah, int16_t nfarray[NUM_NF_READINGS]); 553 void (*do_getnf)(struct ath_hw *ah, int16_t nfarray[NUM_NF_READINGS]);
569 554
570 /* ANI */ 555 /* ANI */
571 void (*ani_reset)(struct ath_hw *ah, bool is_scanning);
572 void (*ani_lower_immunity)(struct ath_hw *ah);
573 void (*ani_cache_ini_regs)(struct ath_hw *ah); 556 void (*ani_cache_ini_regs)(struct ath_hw *ah);
574}; 557};
575 558
@@ -581,11 +564,6 @@ struct ath_hw_private_ops {
581 * 564 *
582 * @config_pci_powersave: 565 * @config_pci_powersave:
583 * @calibrate: periodic calibration for NF, ANI, IQ, ADC gain, ADC-DC 566 * @calibrate: periodic calibration for NF, ANI, IQ, ADC gain, ADC-DC
584 *
585 * @ani_proc_mib_event: process MIB events, this would happen upon specific ANI
586 * thresholds being reached or having overflowed.
587 * @ani_monitor: called periodically by the core driver to collect
588 * MIB stats and adjust ANI if specific thresholds have been reached.
589 */ 567 */
590struct ath_hw_ops { 568struct ath_hw_ops {
591 void (*config_pci_powersave)(struct ath_hw *ah, 569 void (*config_pci_powersave)(struct ath_hw *ah,
@@ -626,9 +604,6 @@ struct ath_hw_ops {
626 u32 burstDuration); 604 u32 burstDuration);
627 void (*set11n_virtualmorefrag)(struct ath_hw *ah, void *ds, 605 void (*set11n_virtualmorefrag)(struct ath_hw *ah, void *ds,
628 u32 vmf); 606 u32 vmf);
629
630 void (*ani_proc_mib_event)(struct ath_hw *ah);
631 void (*ani_monitor)(struct ath_hw *ah, struct ath9k_channel *chan);
632}; 607};
633 608
634struct ath_nf_limits { 609struct ath_nf_limits {
@@ -689,10 +664,9 @@ struct ath_hw {
689 u32 atim_window; 664 u32 atim_window;
690 665
691 /* Calibration */ 666 /* Calibration */
692 enum ath9k_cal_types supp_cals; 667 u32 supp_cals;
693 struct ath9k_cal_list iq_caldata; 668 struct ath9k_cal_list iq_caldata;
694 struct ath9k_cal_list adcgain_caldata; 669 struct ath9k_cal_list adcgain_caldata;
695 struct ath9k_cal_list adcdc_calinitdata;
696 struct ath9k_cal_list adcdc_caldata; 670 struct ath9k_cal_list adcdc_caldata;
697 struct ath9k_cal_list tempCompCalData; 671 struct ath9k_cal_list tempCompCalData;
698 struct ath9k_cal_list *cal_list; 672 struct ath9k_cal_list *cal_list;
@@ -761,13 +735,13 @@ struct ath_hw {
761 /* ANI */ 735 /* ANI */
762 u32 proc_phyerr; 736 u32 proc_phyerr;
763 u32 aniperiod; 737 u32 aniperiod;
764 struct ar5416AniState *curani;
765 struct ar5416AniState ani[255];
766 int totalSizeDesired[5]; 738 int totalSizeDesired[5];
767 int coarse_high[5]; 739 int coarse_high[5];
768 int coarse_low[5]; 740 int coarse_low[5];
769 int firpwr[5]; 741 int firpwr[5];
770 enum ath9k_ani_cmd ani_function; 742 enum ath9k_ani_cmd ani_function;
743 struct ath_cycle_counters cc, cc_delta;
744 int32_t listen_time;
771 745
772 /* Bluetooth coexistance */ 746 /* Bluetooth coexistance */
773 struct ath_btcoex_hw btcoex_hw; 747 struct ath_btcoex_hw btcoex_hw;
@@ -988,8 +962,9 @@ void ar9002_hw_load_ani_reg(struct ath_hw *ah, struct ath9k_channel *chan);
988 * older families (AR5008, AR9001, AR9002) by using modparam_force_new_ani. 962 * older families (AR5008, AR9001, AR9002) by using modparam_force_new_ani.
989 */ 963 */
990extern int modparam_force_new_ani; 964extern int modparam_force_new_ani;
991void ath9k_hw_attach_ani_ops_old(struct ath_hw *ah); 965void ath9k_ani_reset(struct ath_hw *ah, bool is_scanning);
992void ath9k_hw_attach_ani_ops_new(struct ath_hw *ah); 966void ath9k_hw_proc_mib_event(struct ath_hw *ah);
967void ath9k_hw_ani_monitor(struct ath_hw *ah, struct ath9k_channel *chan);
993 968
994#define ATH_PCIE_CAP_LINK_CTRL 0x70 969#define ATH_PCIE_CAP_LINK_CTRL 0x70
995#define ATH_PCIE_CAP_LINK_L0S 1 970#define ATH_PCIE_CAP_LINK_L0S 1
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c
index de3393867e3..d76003c06fe 100644
--- a/drivers/net/wireless/ath/ath9k/init.c
+++ b/drivers/net/wireless/ath/ath9k/init.c
@@ -56,7 +56,7 @@ MODULE_PARM_DESC(blink, "Enable LED blink on activity");
56 * on 5 MHz steps, we support the channels which we know 56 * on 5 MHz steps, we support the channels which we know
57 * we have calibration data for all cards though to make 57 * we have calibration data for all cards though to make
58 * this static */ 58 * this static */
59static struct ieee80211_channel ath9k_2ghz_chantable[] = { 59static const struct ieee80211_channel ath9k_2ghz_chantable[] = {
60 CHAN2G(2412, 0), /* Channel 1 */ 60 CHAN2G(2412, 0), /* Channel 1 */
61 CHAN2G(2417, 1), /* Channel 2 */ 61 CHAN2G(2417, 1), /* Channel 2 */
62 CHAN2G(2422, 2), /* Channel 3 */ 62 CHAN2G(2422, 2), /* Channel 3 */
@@ -77,7 +77,7 @@ static struct ieee80211_channel ath9k_2ghz_chantable[] = {
77 * on 5 MHz steps, we support the channels which we know 77 * on 5 MHz steps, we support the channels which we know
78 * we have calibration data for all cards though to make 78 * we have calibration data for all cards though to make
79 * this static */ 79 * this static */
80static struct ieee80211_channel ath9k_5ghz_chantable[] = { 80static const struct ieee80211_channel ath9k_5ghz_chantable[] = {
81 /* _We_ call this UNII 1 */ 81 /* _We_ call this UNII 1 */
82 CHAN5G(5180, 14), /* Channel 36 */ 82 CHAN5G(5180, 14), /* Channel 36 */
83 CHAN5G(5200, 15), /* Channel 40 */ 83 CHAN5G(5200, 15), /* Channel 40 */
@@ -477,10 +477,17 @@ err:
477 return -EIO; 477 return -EIO;
478} 478}
479 479
480static void ath9k_init_channels_rates(struct ath_softc *sc) 480static int ath9k_init_channels_rates(struct ath_softc *sc)
481{ 481{
482 void *channels;
483
482 if (test_bit(ATH9K_MODE_11G, sc->sc_ah->caps.wireless_modes)) { 484 if (test_bit(ATH9K_MODE_11G, sc->sc_ah->caps.wireless_modes)) {
483 sc->sbands[IEEE80211_BAND_2GHZ].channels = ath9k_2ghz_chantable; 485 channels = kmemdup(ath9k_2ghz_chantable,
486 sizeof(ath9k_2ghz_chantable), GFP_KERNEL);
487 if (!channels)
488 return -ENOMEM;
489
490 sc->sbands[IEEE80211_BAND_2GHZ].channels = channels;
484 sc->sbands[IEEE80211_BAND_2GHZ].band = IEEE80211_BAND_2GHZ; 491 sc->sbands[IEEE80211_BAND_2GHZ].band = IEEE80211_BAND_2GHZ;
485 sc->sbands[IEEE80211_BAND_2GHZ].n_channels = 492 sc->sbands[IEEE80211_BAND_2GHZ].n_channels =
486 ARRAY_SIZE(ath9k_2ghz_chantable); 493 ARRAY_SIZE(ath9k_2ghz_chantable);
@@ -490,7 +497,15 @@ static void ath9k_init_channels_rates(struct ath_softc *sc)
490 } 497 }
491 498
492 if (test_bit(ATH9K_MODE_11A, sc->sc_ah->caps.wireless_modes)) { 499 if (test_bit(ATH9K_MODE_11A, sc->sc_ah->caps.wireless_modes)) {
493 sc->sbands[IEEE80211_BAND_5GHZ].channels = ath9k_5ghz_chantable; 500 channels = kmemdup(ath9k_5ghz_chantable,
501 sizeof(ath9k_5ghz_chantable), GFP_KERNEL);
502 if (!channels) {
503 if (sc->sbands[IEEE80211_BAND_2GHZ].channels)
504 kfree(sc->sbands[IEEE80211_BAND_2GHZ].channels);
505 return -ENOMEM;
506 }
507
508 sc->sbands[IEEE80211_BAND_5GHZ].channels = channels;
494 sc->sbands[IEEE80211_BAND_5GHZ].band = IEEE80211_BAND_5GHZ; 509 sc->sbands[IEEE80211_BAND_5GHZ].band = IEEE80211_BAND_5GHZ;
495 sc->sbands[IEEE80211_BAND_5GHZ].n_channels = 510 sc->sbands[IEEE80211_BAND_5GHZ].n_channels =
496 ARRAY_SIZE(ath9k_5ghz_chantable); 511 ARRAY_SIZE(ath9k_5ghz_chantable);
@@ -499,6 +514,7 @@ static void ath9k_init_channels_rates(struct ath_softc *sc)
499 sc->sbands[IEEE80211_BAND_5GHZ].n_bitrates = 514 sc->sbands[IEEE80211_BAND_5GHZ].n_bitrates =
500 ARRAY_SIZE(ath9k_legacy_rates) - 4; 515 ARRAY_SIZE(ath9k_legacy_rates) - 4;
501 } 516 }
517 return 0;
502} 518}
503 519
504static void ath9k_init_misc(struct ath_softc *sc) 520static void ath9k_init_misc(struct ath_softc *sc)
@@ -506,7 +522,6 @@ static void ath9k_init_misc(struct ath_softc *sc)
506 struct ath_common *common = ath9k_hw_common(sc->sc_ah); 522 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
507 int i = 0; 523 int i = 0;
508 524
509 common->ani.noise_floor = ATH_DEFAULT_NOISE_FLOOR;
510 setup_timer(&common->ani.timer, ath_ani_calibrate, (unsigned long)sc); 525 setup_timer(&common->ani.timer, ath_ani_calibrate, (unsigned long)sc);
511 526
512 sc->config.txpowlimit = ATH_TXPOWER_MAX; 527 sc->config.txpowlimit = ATH_TXPOWER_MAX;
@@ -595,8 +610,11 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid,
595 if (ret) 610 if (ret)
596 goto err_btcoex; 611 goto err_btcoex;
597 612
613 ret = ath9k_init_channels_rates(sc);
614 if (ret)
615 goto err_btcoex;
616
598 ath9k_init_crypto(sc); 617 ath9k_init_crypto(sc);
599 ath9k_init_channels_rates(sc);
600 ath9k_init_misc(sc); 618 ath9k_init_misc(sc);
601 619
602 return 0; 620 return 0;
@@ -639,6 +657,7 @@ void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
639 657
640 hw->wiphy->interface_modes = 658 hw->wiphy->interface_modes =
641 BIT(NL80211_IFTYPE_AP) | 659 BIT(NL80211_IFTYPE_AP) |
660 BIT(NL80211_IFTYPE_WDS) |
642 BIT(NL80211_IFTYPE_STATION) | 661 BIT(NL80211_IFTYPE_STATION) |
643 BIT(NL80211_IFTYPE_ADHOC) | 662 BIT(NL80211_IFTYPE_ADHOC) |
644 BIT(NL80211_IFTYPE_MESH_POINT); 663 BIT(NL80211_IFTYPE_MESH_POINT);
@@ -756,6 +775,12 @@ static void ath9k_deinit_softc(struct ath_softc *sc)
756{ 775{
757 int i = 0; 776 int i = 0;
758 777
778 if (sc->sbands[IEEE80211_BAND_2GHZ].channels)
779 kfree(sc->sbands[IEEE80211_BAND_2GHZ].channels);
780
781 if (sc->sbands[IEEE80211_BAND_5GHZ].channels)
782 kfree(sc->sbands[IEEE80211_BAND_5GHZ].channels);
783
759 if ((sc->btcoex.no_stomp_timer) && 784 if ((sc->btcoex.no_stomp_timer) &&
760 sc->sc_ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE) 785 sc->sc_ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE)
761 ath_gen_timer_free(sc->sc_ah, sc->btcoex.no_stomp_timer); 786 ath_gen_timer_free(sc->sc_ah, sc->btcoex.no_stomp_timer);
diff --git a/drivers/net/wireless/ath/ath9k/mac.c b/drivers/net/wireless/ath/ath9k/mac.c
index 3efda8a8a3c..8c13479b17c 100644
--- a/drivers/net/wireless/ath/ath9k/mac.c
+++ b/drivers/net/wireless/ath/ath9k/mac.c
@@ -40,7 +40,6 @@ static void ath9k_hw_set_txq_interrupts(struct ath_hw *ah,
40 REG_WRITE(ah, AR_IMR_S2, ah->imrs2_reg); 40 REG_WRITE(ah, AR_IMR_S2, ah->imrs2_reg);
41 41
42 REGWRITE_BUFFER_FLUSH(ah); 42 REGWRITE_BUFFER_FLUSH(ah);
43 DISABLE_REGWRITE_BUFFER(ah);
44} 43}
45 44
46u32 ath9k_hw_gettxbuf(struct ath_hw *ah, u32 q) 45u32 ath9k_hw_gettxbuf(struct ath_hw *ah, u32 q)
@@ -492,8 +491,6 @@ bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q)
492 REG_WRITE(ah, AR_DMISC(q), 491 REG_WRITE(ah, AR_DMISC(q),
493 AR_D_MISC_CW_BKOFF_EN | AR_D_MISC_FRAG_WAIT_EN | 0x2); 492 AR_D_MISC_CW_BKOFF_EN | AR_D_MISC_FRAG_WAIT_EN | 0x2);
494 493
495 REGWRITE_BUFFER_FLUSH(ah);
496
497 if (qi->tqi_cbrPeriod) { 494 if (qi->tqi_cbrPeriod) {
498 REG_WRITE(ah, AR_QCBRCFG(q), 495 REG_WRITE(ah, AR_QCBRCFG(q),
499 SM(qi->tqi_cbrPeriod, AR_Q_CBRCFG_INTERVAL) | 496 SM(qi->tqi_cbrPeriod, AR_Q_CBRCFG_INTERVAL) |
@@ -509,8 +506,6 @@ bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q)
509 AR_Q_RDYTIMECFG_EN); 506 AR_Q_RDYTIMECFG_EN);
510 } 507 }
511 508
512 REGWRITE_BUFFER_FLUSH(ah);
513
514 REG_WRITE(ah, AR_DCHNTIME(q), 509 REG_WRITE(ah, AR_DCHNTIME(q),
515 SM(qi->tqi_burstTime, AR_D_CHNTIME_DUR) | 510 SM(qi->tqi_burstTime, AR_D_CHNTIME_DUR) |
516 (qi->tqi_burstTime ? AR_D_CHNTIME_EN : 0)); 511 (qi->tqi_burstTime ? AR_D_CHNTIME_EN : 0));
@@ -530,7 +525,6 @@ bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q)
530 } 525 }
531 526
532 REGWRITE_BUFFER_FLUSH(ah); 527 REGWRITE_BUFFER_FLUSH(ah);
533 DISABLE_REGWRITE_BUFFER(ah);
534 528
535 if (qi->tqi_qflags & TXQ_FLAG_FRAG_BURST_BACKOFF_ENABLE) { 529 if (qi->tqi_qflags & TXQ_FLAG_FRAG_BURST_BACKOFF_ENABLE) {
536 REG_WRITE(ah, AR_DMISC(q), 530 REG_WRITE(ah, AR_DMISC(q),
@@ -553,7 +547,6 @@ bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q)
553 | AR_D_MISC_POST_FR_BKOFF_DIS); 547 | AR_D_MISC_POST_FR_BKOFF_DIS);
554 548
555 REGWRITE_BUFFER_FLUSH(ah); 549 REGWRITE_BUFFER_FLUSH(ah);
556 DISABLE_REGWRITE_BUFFER(ah);
557 550
558 /* 551 /*
559 * cwmin and cwmax should be 0 for beacon queue 552 * cwmin and cwmax should be 0 for beacon queue
@@ -585,7 +578,6 @@ bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q)
585 AR_D_MISC_ARB_LOCKOUT_CNTRL_S)); 578 AR_D_MISC_ARB_LOCKOUT_CNTRL_S));
586 579
587 REGWRITE_BUFFER_FLUSH(ah); 580 REGWRITE_BUFFER_FLUSH(ah);
588 DISABLE_REGWRITE_BUFFER(ah);
589 581
590 break; 582 break;
591 case ATH9K_TX_QUEUE_PSPOLL: 583 case ATH9K_TX_QUEUE_PSPOLL:
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index a1338788263..74c2dc8a8b8 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -459,16 +459,6 @@ void ath_ani_calibrate(unsigned long data)
459 ah->curchan, 459 ah->curchan,
460 common->rx_chainmask, 460 common->rx_chainmask,
461 longcal); 461 longcal);
462
463 if (longcal)
464 common->ani.noise_floor = ath9k_hw_getchan_noise(ah,
465 ah->curchan);
466
467 ath_print(common, ATH_DBG_ANI,
468 " calibrate chan %u/%x nf: %d\n",
469 ah->curchan->channel,
470 ah->curchan->channelFlags,
471 common->ani.noise_floor);
472 } 462 }
473 } 463 }
474 464
@@ -723,7 +713,7 @@ irqreturn_t ath_isr(int irq, void *dev)
723 * it will clear whatever condition caused 713 * it will clear whatever condition caused
724 * the interrupt. 714 * the interrupt.
725 */ 715 */
726 ath9k_hw_procmibevent(ah); 716 ath9k_hw_proc_mib_event(ah);
727 ath9k_hw_set_interrupts(ah, ah->imask); 717 ath9k_hw_set_interrupts(ah, ah->imask);
728 } 718 }
729 719
@@ -1384,6 +1374,9 @@ static int ath9k_add_interface(struct ieee80211_hw *hw,
1384 case NL80211_IFTYPE_STATION: 1374 case NL80211_IFTYPE_STATION:
1385 ic_opmode = NL80211_IFTYPE_STATION; 1375 ic_opmode = NL80211_IFTYPE_STATION;
1386 break; 1376 break;
1377 case NL80211_IFTYPE_WDS:
1378 ic_opmode = NL80211_IFTYPE_WDS;
1379 break;
1387 case NL80211_IFTYPE_ADHOC: 1380 case NL80211_IFTYPE_ADHOC:
1388 case NL80211_IFTYPE_AP: 1381 case NL80211_IFTYPE_AP:
1389 case NL80211_IFTYPE_MESH_POINT: 1382 case NL80211_IFTYPE_MESH_POINT:
@@ -1491,7 +1484,7 @@ static void ath9k_remove_interface(struct ieee80211_hw *hw,
1491 mutex_unlock(&sc->mutex); 1484 mutex_unlock(&sc->mutex);
1492} 1485}
1493 1486
1494void ath9k_enable_ps(struct ath_softc *sc) 1487static void ath9k_enable_ps(struct ath_softc *sc)
1495{ 1488{
1496 struct ath_hw *ah = sc->sc_ah; 1489 struct ath_hw *ah = sc->sc_ah;
1497 1490
@@ -1505,13 +1498,32 @@ void ath9k_enable_ps(struct ath_softc *sc)
1505 } 1498 }
1506} 1499}
1507 1500
1501static void ath9k_disable_ps(struct ath_softc *sc)
1502{
1503 struct ath_hw *ah = sc->sc_ah;
1504
1505 sc->ps_enabled = false;
1506 ath9k_hw_setpower(ah, ATH9K_PM_AWAKE);
1507 if (!(ah->caps.hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) {
1508 ath9k_hw_setrxabort(ah, 0);
1509 sc->ps_flags &= ~(PS_WAIT_FOR_BEACON |
1510 PS_WAIT_FOR_CAB |
1511 PS_WAIT_FOR_PSPOLL_DATA |
1512 PS_WAIT_FOR_TX_ACK);
1513 if (ah->imask & ATH9K_INT_TIM_TIMER) {
1514 ah->imask &= ~ATH9K_INT_TIM_TIMER;
1515 ath9k_hw_set_interrupts(ah, ah->imask);
1516 }
1517 }
1518
1519}
1520
1508static int ath9k_config(struct ieee80211_hw *hw, u32 changed) 1521static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
1509{ 1522{
1510 struct ath_wiphy *aphy = hw->priv; 1523 struct ath_wiphy *aphy = hw->priv;
1511 struct ath_softc *sc = aphy->sc; 1524 struct ath_softc *sc = aphy->sc;
1512 struct ath_common *common = ath9k_hw_common(sc->sc_ah); 1525 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
1513 struct ieee80211_conf *conf = &hw->conf; 1526 struct ieee80211_conf *conf = &hw->conf;
1514 struct ath_hw *ah = sc->sc_ah;
1515 bool disable_radio; 1527 bool disable_radio;
1516 1528
1517 mutex_lock(&sc->mutex); 1529 mutex_lock(&sc->mutex);
@@ -1558,35 +1570,10 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
1558 if (changed & IEEE80211_CONF_CHANGE_PS) { 1570 if (changed & IEEE80211_CONF_CHANGE_PS) {
1559 unsigned long flags; 1571 unsigned long flags;
1560 spin_lock_irqsave(&sc->sc_pm_lock, flags); 1572 spin_lock_irqsave(&sc->sc_pm_lock, flags);
1561 if (conf->flags & IEEE80211_CONF_PS) { 1573 if (conf->flags & IEEE80211_CONF_PS)
1562 sc->ps_flags |= PS_ENABLED; 1574 ath9k_enable_ps(sc);
1563 /* 1575 else
1564 * At this point we know hardware has received an ACK 1576 ath9k_disable_ps(sc);
1565 * of a previously sent null data frame.
1566 */
1567 if ((sc->ps_flags & PS_NULLFUNC_COMPLETED)) {
1568 sc->ps_flags &= ~PS_NULLFUNC_COMPLETED;
1569 ath9k_enable_ps(sc);
1570 }
1571 } else {
1572 sc->ps_enabled = false;
1573 sc->ps_flags &= ~(PS_ENABLED |
1574 PS_NULLFUNC_COMPLETED);
1575 ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_AWAKE);
1576 if (!(ah->caps.hw_caps &
1577 ATH9K_HW_CAP_AUTOSLEEP)) {
1578 ath9k_hw_setrxabort(sc->sc_ah, 0);
1579 sc->ps_flags &= ~(PS_WAIT_FOR_BEACON |
1580 PS_WAIT_FOR_CAB |
1581 PS_WAIT_FOR_PSPOLL_DATA |
1582 PS_WAIT_FOR_TX_ACK);
1583 if (ah->imask & ATH9K_INT_TIM_TIMER) {
1584 ah->imask &= ~ATH9K_INT_TIM_TIMER;
1585 ath9k_hw_set_interrupts(sc->sc_ah,
1586 ah->imask);
1587 }
1588 }
1589 }
1590 spin_unlock_irqrestore(&sc->sc_pm_lock, flags); 1577 spin_unlock_irqrestore(&sc->sc_pm_lock, flags);
1591 } 1578 }
1592 1579
@@ -2004,15 +1991,32 @@ static int ath9k_get_survey(struct ieee80211_hw *hw, int idx,
2004 struct ath_wiphy *aphy = hw->priv; 1991 struct ath_wiphy *aphy = hw->priv;
2005 struct ath_softc *sc = aphy->sc; 1992 struct ath_softc *sc = aphy->sc;
2006 struct ath_hw *ah = sc->sc_ah; 1993 struct ath_hw *ah = sc->sc_ah;
2007 struct ath_common *common = ath9k_hw_common(ah); 1994 struct ieee80211_supported_band *sband;
2008 struct ieee80211_conf *conf = &hw->conf; 1995 struct ath9k_channel *chan;
1996
1997 sband = hw->wiphy->bands[IEEE80211_BAND_2GHZ];
1998 if (sband && idx >= sband->n_channels) {
1999 idx -= sband->n_channels;
2000 sband = NULL;
2001 }
2002
2003 if (!sband)
2004 sband = hw->wiphy->bands[IEEE80211_BAND_5GHZ];
2009 2005
2010 if (idx != 0) 2006 if (!sband || idx >= sband->n_channels)
2011 return -ENOENT; 2007 return -ENOENT;
2012 2008
2013 survey->channel = conf->channel; 2009 survey->channel = &sband->channels[idx];
2014 survey->filled = SURVEY_INFO_NOISE_DBM; 2010 chan = &ah->channels[survey->channel->hw_value];
2015 survey->noise = common->ani.noise_floor; 2011 survey->filled = 0;
2012
2013 if (chan == ah->curchan)
2014 survey->filled |= SURVEY_INFO_IN_USE;
2015
2016 if (chan->noisefloor) {
2017 survey->filled |= SURVEY_INFO_NOISE_DBM;
2018 survey->noise = chan->noisefloor;
2019 }
2016 2020
2017 return 0; 2021 return 0;
2018} 2022}
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index f7da6b20a92..aa447770eb2 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -1648,13 +1648,6 @@ static int ath_tx_setup_buffer(struct ieee80211_hw *hw, struct ath_buf *bf,
1648 1648
1649 bf->bf_buf_addr = bf->bf_dmacontext; 1649 bf->bf_buf_addr = bf->bf_dmacontext;
1650 1650
1651 /* tag if this is a nullfunc frame to enable PS when AP acks it */
1652 if (ieee80211_is_nullfunc(fc) && ieee80211_has_pm(fc)) {
1653 bf->bf_isnullfunc = true;
1654 sc->ps_flags &= ~PS_NULLFUNC_COMPLETED;
1655 } else
1656 bf->bf_isnullfunc = false;
1657
1658 bf->bf_tx_aborted = false; 1651 bf->bf_tx_aborted = false;
1659 1652
1660 return 0; 1653 return 0;
@@ -2082,18 +2075,6 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
2082 } 2075 }
2083 2076
2084 /* 2077 /*
2085 * We now know the nullfunc frame has been ACKed so we
2086 * can disable RX.
2087 */
2088 if (bf->bf_isnullfunc &&
2089 (ts.ts_status & ATH9K_TX_ACKED)) {
2090 if ((sc->ps_flags & PS_ENABLED))
2091 ath9k_enable_ps(sc);
2092 else
2093 sc->ps_flags |= PS_NULLFUNC_COMPLETED;
2094 }
2095
2096 /*
2097 * Remove ath_buf's of the same transmit unit from txq, 2078 * Remove ath_buf's of the same transmit unit from txq,
2098 * however leave the last descriptor back as the holding 2079 * however leave the last descriptor back as the holding
2099 * descriptor for hw. 2080 * descriptor for hw.
@@ -2236,17 +2217,6 @@ void ath_tx_edma_tasklet(struct ath_softc *sc)
2236 2217
2237 txok = !(txs.ts_status & ATH9K_TXERR_MASK); 2218 txok = !(txs.ts_status & ATH9K_TXERR_MASK);
2238 2219
2239 /*
2240 * Make sure null func frame is acked before configuring
2241 * hw into ps mode.
2242 */
2243 if (bf->bf_isnullfunc && txok) {
2244 if ((sc->ps_flags & PS_ENABLED))
2245 ath9k_enable_ps(sc);
2246 else
2247 sc->ps_flags |= PS_NULLFUNC_COMPLETED;
2248 }
2249
2250 if (!bf_isampdu(bf)) { 2220 if (!bf_isampdu(bf)) {
2251 if (txs.ts_status & ATH9K_TXERR_XRETRY) 2221 if (txs.ts_status & ATH9K_TXERR_XRETRY)
2252 bf->bf_state.bf_type |= BUF_XRETRY; 2222 bf->bf_state.bf_type |= BUF_XRETRY;
diff --git a/drivers/net/wireless/ath/carl9170/carl9170.h b/drivers/net/wireless/ath/carl9170/carl9170.h
index 20f2a77e54d..6cf0c9ef47a 100644
--- a/drivers/net/wireless/ath/carl9170/carl9170.h
+++ b/drivers/net/wireless/ath/carl9170/carl9170.h
@@ -279,6 +279,7 @@ struct ar9170 {
279 unsigned int beacon_max_len; 279 unsigned int beacon_max_len;
280 bool rx_stream; 280 bool rx_stream;
281 bool tx_stream; 281 bool tx_stream;
282 bool rx_filter;
282 unsigned int mem_blocks; 283 unsigned int mem_blocks;
283 unsigned int mem_block_size; 284 unsigned int mem_block_size;
284 unsigned int rx_size; 285 unsigned int rx_size;
@@ -314,6 +315,7 @@ struct ar9170 {
314 u64 cur_mc_hash; 315 u64 cur_mc_hash;
315 u32 cur_filter; 316 u32 cur_filter;
316 unsigned int filter_state; 317 unsigned int filter_state;
318 unsigned int rx_filter_caps;
317 bool sniffer_enabled; 319 bool sniffer_enabled;
318 320
319 /* MAC */ 321 /* MAC */
diff --git a/drivers/net/wireless/ath/carl9170/cmd.h b/drivers/net/wireless/ath/carl9170/cmd.h
index 0fc83d2336f..f78728c3829 100644
--- a/drivers/net/wireless/ath/carl9170/cmd.h
+++ b/drivers/net/wireless/ath/carl9170/cmd.h
@@ -59,6 +59,16 @@ static inline int carl9170_flush_cab(struct ar9170 *ar,
59 return carl9170_bcn_ctrl(ar, vif_id, CARL9170_BCN_CTRL_DRAIN, 0, 0); 59 return carl9170_bcn_ctrl(ar, vif_id, CARL9170_BCN_CTRL_DRAIN, 0, 0);
60} 60}
61 61
62static inline int carl9170_rx_filter(struct ar9170 *ar,
63 const unsigned int _rx_filter)
64{
65 __le32 rx_filter = cpu_to_le32(_rx_filter);
66
67 return carl9170_exec_cmd(ar, CARL9170_CMD_RX_FILTER,
68 sizeof(rx_filter), (u8 *)&rx_filter,
69 0, NULL);
70}
71
62struct carl9170_cmd *carl9170_cmd_buf(struct ar9170 *ar, 72struct carl9170_cmd *carl9170_cmd_buf(struct ar9170 *ar,
63 const enum carl9170_cmd_oids cmd, const unsigned int len); 73 const enum carl9170_cmd_oids cmd, const unsigned int len);
64 74
diff --git a/drivers/net/wireless/ath/carl9170/fw.c b/drivers/net/wireless/ath/carl9170/fw.c
index 36615462b87..ae6c006bbc5 100644
--- a/drivers/net/wireless/ath/carl9170/fw.c
+++ b/drivers/net/wireless/ath/carl9170/fw.c
@@ -257,6 +257,13 @@ static int carl9170_fw(struct ar9170 *ar, const __u8 *data, size_t len)
257 if (SUPP(CARL9170FW_USB_UP_STREAM)) 257 if (SUPP(CARL9170FW_USB_UP_STREAM))
258 ar->fw.rx_stream = true; 258 ar->fw.rx_stream = true;
259 259
260 if (SUPP(CARL9170FW_RX_FILTER)) {
261 ar->fw.rx_filter = true;
262 ar->rx_filter_caps = FIF_FCSFAIL | FIF_PLCPFAIL |
263 FIF_CONTROL | FIF_PSPOLL | FIF_OTHER_BSS |
264 FIF_PROMISC_IN_BSS;
265 }
266
260 ar->fw.vif_num = otus_desc->vif_num; 267 ar->fw.vif_num = otus_desc->vif_num;
261 ar->fw.cmd_bufs = otus_desc->cmd_bufs; 268 ar->fw.cmd_bufs = otus_desc->cmd_bufs;
262 ar->fw.address = le32_to_cpu(otus_desc->fw_address); 269 ar->fw.address = le32_to_cpu(otus_desc->fw_address);
diff --git a/drivers/net/wireless/ath/carl9170/fwcmd.h b/drivers/net/wireless/ath/carl9170/fwcmd.h
index d4a4e1dbef0..d552166db50 100644
--- a/drivers/net/wireless/ath/carl9170/fwcmd.h
+++ b/drivers/net/wireless/ath/carl9170/fwcmd.h
@@ -53,6 +53,7 @@ enum carl9170_cmd_oids {
53 CARL9170_CMD_REBOOT = 0x04, 53 CARL9170_CMD_REBOOT = 0x04,
54 CARL9170_CMD_BCN_CTRL = 0x05, 54 CARL9170_CMD_BCN_CTRL = 0x05,
55 CARL9170_CMD_READ_TSF = 0x06, 55 CARL9170_CMD_READ_TSF = 0x06,
56 CARL9170_CMD_RX_FILTER = 0x07,
56 57
57 /* CAM */ 58 /* CAM */
58 CARL9170_CMD_EKEY = 0x10, 59 CARL9170_CMD_EKEY = 0x10,
@@ -153,6 +154,20 @@ struct carl9170_psm {
153} __packed; 154} __packed;
154#define CARL9170_PSM_SIZE 4 155#define CARL9170_PSM_SIZE 4
155 156
157struct carl9170_rx_filter_cmd {
158 __le32 rx_filter;
159} __packed;
160#define CARL9170_RX_FILTER_CMD_SIZE 4
161
162#define CARL9170_RX_FILTER_BAD 0x01
163#define CARL9170_RX_FILTER_OTHER_RA 0x02
164#define CARL9170_RX_FILTER_DECRY_FAIL 0x04
165#define CARL9170_RX_FILTER_CTL_OTHER 0x08
166#define CARL9170_RX_FILTER_CTL_PSPOLL 0x10
167#define CARL9170_RX_FILTER_CTL_BACKR 0x20
168#define CARL9170_RX_FILTER_MGMT 0x40
169#define CARL9170_RX_FILTER_DATA 0x80
170
156struct carl9170_bcn_ctrl_cmd { 171struct carl9170_bcn_ctrl_cmd {
157 __le32 vif_id; 172 __le32 vif_id;
158 __le32 mode; 173 __le32 mode;
@@ -188,6 +203,7 @@ struct carl9170_cmd {
188 struct carl9170_rf_init rf_init; 203 struct carl9170_rf_init rf_init;
189 struct carl9170_psm psm; 204 struct carl9170_psm psm;
190 struct carl9170_bcn_ctrl_cmd bcn_ctrl; 205 struct carl9170_bcn_ctrl_cmd bcn_ctrl;
206 struct carl9170_rx_filter_cmd rx_filter;
191 u8 data[CARL9170_MAX_CMD_PAYLOAD_LEN]; 207 u8 data[CARL9170_MAX_CMD_PAYLOAD_LEN];
192 } __packed; 208 } __packed;
193} __packed; 209} __packed;
diff --git a/drivers/net/wireless/ath/carl9170/fwdesc.h b/drivers/net/wireless/ath/carl9170/fwdesc.h
index 7cd811708fe..71f3821f605 100644
--- a/drivers/net/wireless/ath/carl9170/fwdesc.h
+++ b/drivers/net/wireless/ath/carl9170/fwdesc.h
@@ -66,6 +66,9 @@ enum carl9170fw_feature_list {
66 /* Firmware PSM support | CARL9170_CMD_PSM */ 66 /* Firmware PSM support | CARL9170_CMD_PSM */
67 CARL9170FW_PSM, 67 CARL9170FW_PSM,
68 68
69 /* Firmware RX filter | CARL9170_CMD_RX_FILTER */
70 CARL9170FW_RX_FILTER,
71
69 /* KEEP LAST */ 72 /* KEEP LAST */
70 __CARL9170FW_FEATURE_NUM 73 __CARL9170FW_FEATURE_NUM
71}; 74};
@@ -142,7 +145,7 @@ struct carl9170fw_fix_desc {
142 (sizeof(struct carl9170fw_fix_desc)) 145 (sizeof(struct carl9170fw_fix_desc))
143 146
144#define CARL9170FW_DBG_DESC_MIN_VER 1 147#define CARL9170FW_DBG_DESC_MIN_VER 1
145#define CARL9170FW_DBG_DESC_CUR_VER 2 148#define CARL9170FW_DBG_DESC_CUR_VER 3
146struct carl9170fw_dbg_desc { 149struct carl9170fw_dbg_desc {
147 struct carl9170fw_desc_head head; 150 struct carl9170fw_desc_head head;
148 151
@@ -150,6 +153,7 @@ struct carl9170fw_dbg_desc {
150 __le32 counter_addr; 153 __le32 counter_addr;
151 __le32 rx_total_addr; 154 __le32 rx_total_addr;
152 __le32 rx_overrun_addr; 155 __le32 rx_overrun_addr;
156 __le32 rx_filter;
153 157
154 /* Put your debugging definitions here */ 158 /* Put your debugging definitions here */
155} __packed; 159} __packed;
diff --git a/drivers/net/wireless/ath/carl9170/hw.h b/drivers/net/wireless/ath/carl9170/hw.h
index b1292ac5b70..2f471b3f05a 100644
--- a/drivers/net/wireless/ath/carl9170/hw.h
+++ b/drivers/net/wireless/ath/carl9170/hw.h
@@ -731,6 +731,9 @@ struct ar9170_stream {
731#define SET_VAL(reg, value, newvalue) \ 731#define SET_VAL(reg, value, newvalue) \
732 (value = ((value) & ~reg) | (((newvalue) << reg##_S) & reg)) 732 (value = ((value) & ~reg) | (((newvalue) << reg##_S) & reg))
733 733
734#define SET_CONSTVAL(reg, newvalue) \
735 (((newvalue) << reg##_S) & reg)
736
734#define MOD_VAL(reg, value, newvalue) \ 737#define MOD_VAL(reg, value, newvalue) \
735 (((value) & ~reg) | (((newvalue) << reg##_S) & reg)) 738 (((value) & ~reg) | (((newvalue) << reg##_S) & reg))
736#endif /* __CARL9170_SHARED_HW_H */ 739#endif /* __CARL9170_SHARED_HW_H */
diff --git a/drivers/net/wireless/ath/carl9170/main.c b/drivers/net/wireless/ath/carl9170/main.c
index 84bd38e9961..3cc99f3f7ab 100644
--- a/drivers/net/wireless/ath/carl9170/main.c
+++ b/drivers/net/wireless/ath/carl9170/main.c
@@ -380,6 +380,13 @@ static int carl9170_op_start(struct ieee80211_hw *hw)
380 if (err) 380 if (err)
381 goto out; 381 goto out;
382 382
383 if (ar->fw.rx_filter) {
384 err = carl9170_rx_filter(ar, CARL9170_RX_FILTER_OTHER_RA |
385 CARL9170_RX_FILTER_CTL_OTHER | CARL9170_RX_FILTER_BAD);
386 if (err)
387 goto out;
388 }
389
383 err = carl9170_write_reg(ar, AR9170_MAC_REG_DMA_TRIGGER, 390 err = carl9170_write_reg(ar, AR9170_MAC_REG_DMA_TRIGGER,
384 AR9170_DMA_TRIGGER_RXQ); 391 AR9170_DMA_TRIGGER_RXQ);
385 if (err) 392 if (err)
@@ -840,8 +847,7 @@ static void carl9170_op_configure_filter(struct ieee80211_hw *hw,
840 struct ar9170 *ar = hw->priv; 847 struct ar9170 *ar = hw->priv;
841 848
842 /* mask supported flags */ 849 /* mask supported flags */
843 *new_flags &= FIF_ALLMULTI | FIF_FCSFAIL | FIF_PLCPFAIL | 850 *new_flags &= FIF_ALLMULTI | ar->rx_filter_caps;
844 FIF_OTHER_BSS | FIF_PROMISC_IN_BSS;
845 851
846 if (!IS_ACCEPTING_CMD(ar)) 852 if (!IS_ACCEPTING_CMD(ar))
847 return; 853 return;
@@ -867,6 +873,26 @@ static void carl9170_op_configure_filter(struct ieee80211_hw *hw,
867 WARN_ON(carl9170_set_operating_mode(ar)); 873 WARN_ON(carl9170_set_operating_mode(ar));
868 } 874 }
869 875
876 if (ar->fw.rx_filter && changed_flags & ar->rx_filter_caps) {
877 u32 rx_filter = 0;
878
879 if (!(*new_flags & (FIF_FCSFAIL | FIF_PLCPFAIL)))
880 rx_filter |= CARL9170_RX_FILTER_BAD;
881
882 if (!(*new_flags & FIF_CONTROL))
883 rx_filter |= CARL9170_RX_FILTER_CTL_OTHER;
884
885 if (!(*new_flags & FIF_PSPOLL))
886 rx_filter |= CARL9170_RX_FILTER_CTL_PSPOLL;
887
888 if (!(*new_flags & (FIF_OTHER_BSS | FIF_PROMISC_IN_BSS))) {
889 rx_filter |= CARL9170_RX_FILTER_OTHER_RA;
890 rx_filter |= CARL9170_RX_FILTER_DECRY_FAIL;
891 }
892
893 WARN_ON(carl9170_rx_filter(ar, rx_filter));
894 }
895
870 mutex_unlock(&ar->mutex); 896 mutex_unlock(&ar->mutex);
871} 897}
872 898
diff --git a/drivers/net/wireless/ath/carl9170/phy.h b/drivers/net/wireless/ath/carl9170/phy.h
index 53c18d34ffc..02c34eb4ebd 100644
--- a/drivers/net/wireless/ath/carl9170/phy.h
+++ b/drivers/net/wireless/ath/carl9170/phy.h
@@ -423,8 +423,8 @@
423#define AR9170_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV 0x2000 423#define AR9170_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV 0x2000
424#define AR9170_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV_S 13 424#define AR9170_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV_S 13
425 425
426#define AR9170_PHY_REG_GAIN_2GHZ_CHAIN_2 (AR9170_PHY_REG_BASE + 0x2a0c)
427#define AR9170_PHY_REG_GAIN_2GHZ (AR9170_PHY_REG_BASE + 0x0a0c) 426#define AR9170_PHY_REG_GAIN_2GHZ (AR9170_PHY_REG_BASE + 0x0a0c)
427#define AR9170_PHY_REG_GAIN_2GHZ_CHAIN_2 (AR9170_PHY_REG_BASE + 0x2a0c)
428#define AR9170_PHY_GAIN_2GHZ_RXTX_MARGIN 0x00fc0000 428#define AR9170_PHY_GAIN_2GHZ_RXTX_MARGIN 0x00fc0000
429#define AR9170_PHY_GAIN_2GHZ_RXTX_MARGIN_S 18 429#define AR9170_PHY_GAIN_2GHZ_RXTX_MARGIN_S 18
430#define AR9170_PHY_GAIN_2GHZ_BSW_MARGIN 0x00003c00 430#define AR9170_PHY_GAIN_2GHZ_BSW_MARGIN 0x00003c00
@@ -561,7 +561,4 @@
561#define AR9170_PHY_CH2_EXT_MINCCA_PWR 0xff800000 561#define AR9170_PHY_CH2_EXT_MINCCA_PWR 0xff800000
562#define AR9170_PHY_CH2_EXT_MINCCA_PWR_S 23 562#define AR9170_PHY_CH2_EXT_MINCCA_PWR_S 23
563 563
564#define REDUCE_CHAIN_0 0x00000050
565#define REDUCE_CHAIN_1 0x00000051
566
567#endif /* __CARL9170_SHARED_PHY_H */ 564#endif /* __CARL9170_SHARED_PHY_H */
diff --git a/drivers/net/wireless/ath/carl9170/version.h b/drivers/net/wireless/ath/carl9170/version.h
index 0e917f80eab..ff53f078a0b 100644
--- a/drivers/net/wireless/ath/carl9170/version.h
+++ b/drivers/net/wireless/ath/carl9170/version.h
@@ -1,7 +1,7 @@
1#ifndef __CARL9170_SHARED_VERSION_H 1#ifndef __CARL9170_SHARED_VERSION_H
2#define __CARL9170_SHARED_VERSION_H 2#define __CARL9170_SHARED_VERSION_H
3#define CARL9170FW_VERSION_YEAR 10 3#define CARL9170FW_VERSION_YEAR 10
4#define CARL9170FW_VERSION_MONTH 8 4#define CARL9170FW_VERSION_MONTH 9
5#define CARL9170FW_VERSION_DAY 30 5#define CARL9170FW_VERSION_DAY 28
6#define CARL9170FW_VERSION_GIT "1.8.8.1" 6#define CARL9170FW_VERSION_GIT "1.8.8.3"
7#endif /* __CARL9170_SHARED_VERSION_H */ 7#endif /* __CARL9170_SHARED_VERSION_H */
diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h
index 8674a99356a..72821c456b0 100644
--- a/drivers/net/wireless/b43/b43.h
+++ b/drivers/net/wireless/b43/b43.h
@@ -186,7 +186,8 @@ enum {
186#define B43_SHM_SH_PHYTXNOI 0x006E /* PHY noise directly after TX (lower 8bit only) */ 186#define B43_SHM_SH_PHYTXNOI 0x006E /* PHY noise directly after TX (lower 8bit only) */
187#define B43_SHM_SH_RFRXSP1 0x0072 /* RF RX SP Register 1 */ 187#define B43_SHM_SH_RFRXSP1 0x0072 /* RF RX SP Register 1 */
188#define B43_SHM_SH_CHAN 0x00A0 /* Current channel (low 8bit only) */ 188#define B43_SHM_SH_CHAN 0x00A0 /* Current channel (low 8bit only) */
189#define B43_SHM_SH_CHAN_5GHZ 0x0100 /* Bit set, if 5Ghz channel */ 189#define B43_SHM_SH_CHAN_5GHZ 0x0100 /* Bit set, if 5 Ghz channel */
190#define B43_SHM_SH_CHAN_40MHZ 0x0200 /* Bit set, if 40 Mhz channel width */
190#define B43_SHM_SH_BCMCFIFOID 0x0108 /* Last posted cookie to the bcast/mcast FIFO */ 191#define B43_SHM_SH_BCMCFIFOID 0x0108 /* Last posted cookie to the bcast/mcast FIFO */
191/* TSSI information */ 192/* TSSI information */
192#define B43_SHM_SH_TSSI_CCK 0x0058 /* TSSI for last 4 CCK frames (32bit) */ 193#define B43_SHM_SH_TSSI_CCK 0x0058 /* TSSI for last 4 CCK frames (32bit) */
diff --git a/drivers/net/wireless/b43/phy_common.c b/drivers/net/wireless/b43/phy_common.c
index 8f7d7eff2d8..7b2ea678145 100644
--- a/drivers/net/wireless/b43/phy_common.c
+++ b/drivers/net/wireless/b43/phy_common.c
@@ -294,8 +294,10 @@ int b43_switch_channel(struct b43_wldev *dev, unsigned int new_channel)
294 */ 294 */
295 channelcookie = new_channel; 295 channelcookie = new_channel;
296 if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) 296 if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ)
297 channelcookie |= 0x100; 297 channelcookie |= B43_SHM_SH_CHAN_5GHZ;
298 //FIXME set 40Mhz flag if required 298 /* FIXME: set 40Mhz flag if required */
299 if (0)
300 channelcookie |= B43_SHM_SH_CHAN_40MHZ;
299 savedcookie = b43_shm_read16(dev, B43_SHM_SHARED, B43_SHM_SH_CHAN); 301 savedcookie = b43_shm_read16(dev, B43_SHM_SHARED, B43_SHM_SH_CHAN);
300 b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_CHAN, channelcookie); 302 b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_CHAN, channelcookie);
301 303
diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c
index 2466c0a52e5..f575e757cae 100644
--- a/drivers/net/wireless/b43/phy_n.c
+++ b/drivers/net/wireless/b43/phy_n.c
@@ -73,7 +73,6 @@ static void b43_nphy_rf_control_override(struct b43_wldev *dev, u16 field,
73 u16 value, u8 core, bool off); 73 u16 value, u8 core, bool off);
74static void b43_nphy_rf_control_intc_override(struct b43_wldev *dev, u8 field, 74static void b43_nphy_rf_control_intc_override(struct b43_wldev *dev, u8 field,
75 u16 value, u8 core); 75 u16 value, u8 core);
76static int nphy_channel_switch(struct b43_wldev *dev, unsigned int channel);
77 76
78static inline bool b43_empty_chanspec(struct b43_chanspec *chanspec) 77static inline bool b43_empty_chanspec(struct b43_chanspec *chanspec)
79{ 78{
@@ -223,7 +222,7 @@ static void b43_radio_init2055_post(struct b43_wldev *dev)
223 if (i) 222 if (i)
224 b43err(dev->wl, "radio post init timeout\n"); 223 b43err(dev->wl, "radio post init timeout\n");
225 b43_radio_mask(dev, B2055_CAL_LPOCTL, 0xFF7F); 224 b43_radio_mask(dev, B2055_CAL_LPOCTL, 0xFF7F);
226 nphy_channel_switch(dev, dev->phy.channel); 225 b43_switch_channel(dev, dev->phy.channel);
227 b43_radio_write(dev, B2055_C1_RX_BB_LPF, 0x9); 226 b43_radio_write(dev, B2055_C1_RX_BB_LPF, 0x9);
228 b43_radio_write(dev, B2055_C2_RX_BB_LPF, 0x9); 227 b43_radio_write(dev, B2055_C2_RX_BB_LPF, 0x9);
229 b43_radio_write(dev, B2055_C1_RX_BB_MIDACHP, 0x83); 228 b43_radio_write(dev, B2055_C1_RX_BB_MIDACHP, 0x83);
@@ -3351,12 +3350,6 @@ static void b43_nphy_chanspec_setup(struct b43_wldev *dev,
3351 3350
3352 b43_chantab_phy_upload(dev, e); 3351 b43_chantab_phy_upload(dev, e);
3353 3352
3354 tmp = chanspec.channel;
3355 if (chanspec.b_freq == 1)
3356 tmp |= 0x0100;
3357 if (chanspec.b_width == 3)
3358 tmp |= 0x0200;
3359 b43_shm_write16(dev, B43_SHM_SHARED, 0xA0, tmp);
3360 3353
3361 if (nphy->radio_chanspec.channel == 14) { 3354 if (nphy->radio_chanspec.channel == 14) {
3362 b43_nphy_classifier(dev, 2, 0); 3355 b43_nphy_classifier(dev, 2, 0);
@@ -3438,18 +3431,6 @@ static int b43_nphy_set_chanspec(struct b43_wldev *dev,
3438 return 0; 3431 return 0;
3439} 3432}
3440 3433
3441/* Tune the hardware to a new channel */
3442static int nphy_channel_switch(struct b43_wldev *dev, unsigned int channel)
3443{
3444 struct b43_phy_n *nphy = dev->phy.n;
3445
3446 struct b43_chanspec chanspec;
3447 chanspec = nphy->radio_chanspec;
3448 chanspec.channel = channel;
3449
3450 return b43_nphy_set_chanspec(dev, chanspec);
3451}
3452
3453static int b43_nphy_op_allocate(struct b43_wldev *dev) 3434static int b43_nphy_op_allocate(struct b43_wldev *dev)
3454{ 3435{
3455 struct b43_phy_n *nphy; 3436 struct b43_phy_n *nphy;
@@ -3570,7 +3551,7 @@ static void b43_nphy_op_software_rfkill(struct b43_wldev *dev,
3570 } else { 3551 } else {
3571 if (dev->phy.rev >= 3) { 3552 if (dev->phy.rev >= 3) {
3572 b43_radio_init2056(dev); 3553 b43_radio_init2056(dev);
3573 b43_nphy_set_chanspec(dev, nphy->radio_chanspec); 3554 b43_switch_channel(dev, dev->phy.channel);
3574 } else { 3555 } else {
3575 b43_radio_init2055(dev); 3556 b43_radio_init2055(dev);
3576 } 3557 }
@@ -3586,6 +3567,9 @@ static void b43_nphy_op_switch_analog(struct b43_wldev *dev, bool on)
3586static int b43_nphy_op_switch_channel(struct b43_wldev *dev, 3567static int b43_nphy_op_switch_channel(struct b43_wldev *dev,
3587 unsigned int new_channel) 3568 unsigned int new_channel)
3588{ 3569{
3570 struct b43_phy_n *nphy = dev->phy.n;
3571 struct b43_chanspec chanspec;
3572
3589 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) { 3573 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
3590 if ((new_channel < 1) || (new_channel > 14)) 3574 if ((new_channel < 1) || (new_channel > 14))
3591 return -EINVAL; 3575 return -EINVAL;
@@ -3594,7 +3578,10 @@ static int b43_nphy_op_switch_channel(struct b43_wldev *dev,
3594 return -EINVAL; 3578 return -EINVAL;
3595 } 3579 }
3596 3580
3597 return nphy_channel_switch(dev, new_channel); 3581 chanspec = nphy->radio_chanspec;
3582 chanspec.channel = new_channel;
3583
3584 return b43_nphy_set_chanspec(dev, chanspec);
3598} 3585}
3599 3586
3600static unsigned int b43_nphy_op_get_default_chan(struct b43_wldev *dev) 3587static unsigned int b43_nphy_op_get_default_chan(struct b43_wldev *dev)
diff --git a/drivers/net/wireless/ipw2x00/ipw2200.c b/drivers/net/wireless/ipw2x00/ipw2200.c
index 0f2508384c7..8d6ed5f6f46 100644
--- a/drivers/net/wireless/ipw2x00/ipw2200.c
+++ b/drivers/net/wireless/ipw2x00/ipw2200.c
@@ -11470,6 +11470,10 @@ static int ipw_net_init(struct net_device *dev)
11470 bg_band->channels = kcalloc(geo->bg_channels, 11470 bg_band->channels = kcalloc(geo->bg_channels,
11471 sizeof(struct ieee80211_channel), 11471 sizeof(struct ieee80211_channel),
11472 GFP_KERNEL); 11472 GFP_KERNEL);
11473 if (!bg_band->channels) {
11474 rc = -ENOMEM;
11475 goto out;
11476 }
11473 /* translate geo->bg to bg_band.channels */ 11477 /* translate geo->bg to bg_band.channels */
11474 for (i = 0; i < geo->bg_channels; i++) { 11478 for (i = 0; i < geo->bg_channels; i++) {
11475 bg_band->channels[i].band = IEEE80211_BAND_2GHZ; 11479 bg_band->channels[i].band = IEEE80211_BAND_2GHZ;
@@ -11505,6 +11509,10 @@ static int ipw_net_init(struct net_device *dev)
11505 a_band->channels = kcalloc(geo->a_channels, 11509 a_band->channels = kcalloc(geo->a_channels,
11506 sizeof(struct ieee80211_channel), 11510 sizeof(struct ieee80211_channel),
11507 GFP_KERNEL); 11511 GFP_KERNEL);
11512 if (!a_band->channels) {
11513 rc = -ENOMEM;
11514 goto out;
11515 }
11508 /* translate geo->bg to a_band.channels */ 11516 /* translate geo->bg to a_band.channels */
11509 for (i = 0; i < geo->a_channels; i++) { 11517 for (i = 0; i < geo->a_channels; i++) {
11510 a_band->channels[i].band = IEEE80211_BAND_2GHZ; 11518 a_band->channels[i].band = IEEE80211_BAND_2GHZ;
diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c
index 56ef4ed0db4..134f5454133 100644
--- a/drivers/net/wireless/iwlwifi/iwl-1000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-1000.c
@@ -50,14 +50,20 @@
50 50
51/* Highest firmware API version supported */ 51/* Highest firmware API version supported */
52#define IWL1000_UCODE_API_MAX 3 52#define IWL1000_UCODE_API_MAX 3
53#define IWL100_UCODE_API_MAX 5
53 54
54/* Lowest firmware API version supported */ 55/* Lowest firmware API version supported */
55#define IWL1000_UCODE_API_MIN 1 56#define IWL1000_UCODE_API_MIN 1
57#define IWL100_UCODE_API_MIN 5
56 58
57#define IWL1000_FW_PRE "iwlwifi-1000-" 59#define IWL1000_FW_PRE "iwlwifi-1000-"
58#define _IWL1000_MODULE_FIRMWARE(api) IWL1000_FW_PRE #api ".ucode" 60#define _IWL1000_MODULE_FIRMWARE(api) IWL1000_FW_PRE #api ".ucode"
59#define IWL1000_MODULE_FIRMWARE(api) _IWL1000_MODULE_FIRMWARE(api) 61#define IWL1000_MODULE_FIRMWARE(api) _IWL1000_MODULE_FIRMWARE(api)
60 62
63#define IWL100_FW_PRE "iwlwifi-100-"
64#define _IWL100_MODULE_FIRMWARE(api) IWL100_FW_PRE #api ".ucode"
65#define IWL100_MODULE_FIRMWARE(api) _IWL100_MODULE_FIRMWARE(api)
66
61 67
62/* 68/*
63 * For 1000, use advance thermal throttling critical temperature threshold, 69 * For 1000, use advance thermal throttling critical temperature threshold,
@@ -120,13 +126,13 @@ static int iwl1000_hw_set_hw_params(struct iwl_priv *priv)
120{ 126{
121 if (priv->cfg->mod_params->num_of_queues >= IWL_MIN_NUM_QUEUES && 127 if (priv->cfg->mod_params->num_of_queues >= IWL_MIN_NUM_QUEUES &&
122 priv->cfg->mod_params->num_of_queues <= IWLAGN_NUM_QUEUES) 128 priv->cfg->mod_params->num_of_queues <= IWLAGN_NUM_QUEUES)
123 priv->cfg->num_of_queues = 129 priv->cfg->base_params->num_of_queues =
124 priv->cfg->mod_params->num_of_queues; 130 priv->cfg->mod_params->num_of_queues;
125 131
126 priv->hw_params.max_txq_num = priv->cfg->num_of_queues; 132 priv->hw_params.max_txq_num = priv->cfg->base_params->num_of_queues;
127 priv->hw_params.dma_chnl_num = FH50_TCSR_CHNL_NUM; 133 priv->hw_params.dma_chnl_num = FH50_TCSR_CHNL_NUM;
128 priv->hw_params.scd_bc_tbls_size = 134 priv->hw_params.scd_bc_tbls_size =
129 priv->cfg->num_of_queues * 135 priv->cfg->base_params->num_of_queues *
130 sizeof(struct iwlagn_scd_bc_tbl); 136 sizeof(struct iwlagn_scd_bc_tbl);
131 priv->hw_params.tfd_size = sizeof(struct iwl_tfd); 137 priv->hw_params.tfd_size = sizeof(struct iwl_tfd);
132 priv->hw_params.max_stations = IWLAGN_STATION_COUNT; 138 priv->hw_params.max_stations = IWLAGN_STATION_COUNT;
@@ -244,29 +250,16 @@ static const struct iwl_ops iwl1000_ops = {
244 .led = &iwlagn_led_ops, 250 .led = &iwlagn_led_ops,
245}; 251};
246 252
247struct iwl_cfg iwl1000_bgn_cfg = { 253static struct iwl_base_params iwl1000_base_params = {
248 .name = "Intel(R) Centrino(R) Wireless-N 1000 BGN",
249 .fw_name_pre = IWL1000_FW_PRE,
250 .ucode_api_max = IWL1000_UCODE_API_MAX,
251 .ucode_api_min = IWL1000_UCODE_API_MIN,
252 .sku = IWL_SKU_G|IWL_SKU_N,
253 .ops = &iwl1000_ops,
254 .eeprom_size = OTP_LOW_IMAGE_SIZE,
255 .eeprom_ver = EEPROM_1000_EEPROM_VERSION,
256 .eeprom_calib_ver = EEPROM_1000_TX_POWER_VERSION,
257 .num_of_queues = IWLAGN_NUM_QUEUES, 254 .num_of_queues = IWLAGN_NUM_QUEUES,
258 .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, 255 .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
259 .mod_params = &iwlagn_mod_params, 256 .eeprom_size = OTP_LOW_IMAGE_SIZE,
260 .valid_tx_ant = ANT_A,
261 .valid_rx_ant = ANT_AB,
262 .pll_cfg_val = CSR50_ANA_PLL_CFG_VAL, 257 .pll_cfg_val = CSR50_ANA_PLL_CFG_VAL,
263 .set_l0s = true, 258 .set_l0s = true,
264 .use_bsm = false, 259 .use_bsm = false,
265 .max_ll_items = OTP_MAX_LL_ITEMS_1000, 260 .max_ll_items = OTP_MAX_LL_ITEMS_1000,
266 .shadow_ram_support = false, 261 .shadow_ram_support = false,
267 .ht_greenfield_support = true,
268 .led_compensation = 51, 262 .led_compensation = 51,
269 .use_rts_for_aggregation = true, /* use rts/cts protection */
270 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, 263 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
271 .support_ct_kill_exit = true, 264 .support_ct_kill_exit = true,
272 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_EXT_LONG_THRESHOLD_DEF, 265 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_EXT_LONG_THRESHOLD_DEF,
@@ -277,6 +270,26 @@ struct iwl_cfg iwl1000_bgn_cfg = {
277 .sensitivity_calib_by_driver = true, 270 .sensitivity_calib_by_driver = true,
278 .chain_noise_calib_by_driver = true, 271 .chain_noise_calib_by_driver = true,
279}; 272};
273static struct iwl_ht_params iwl1000_ht_params = {
274 .ht_greenfield_support = true,
275 .use_rts_for_aggregation = true, /* use rts/cts protection */
276};
277
278struct iwl_cfg iwl1000_bgn_cfg = {
279 .name = "Intel(R) Centrino(R) Wireless-N 1000 BGN",
280 .fw_name_pre = IWL1000_FW_PRE,
281 .ucode_api_max = IWL1000_UCODE_API_MAX,
282 .ucode_api_min = IWL1000_UCODE_API_MIN,
283 .sku = IWL_SKU_G|IWL_SKU_N,
284 .valid_tx_ant = ANT_A,
285 .valid_rx_ant = ANT_AB,
286 .eeprom_ver = EEPROM_1000_EEPROM_VERSION,
287 .eeprom_calib_ver = EEPROM_1000_TX_POWER_VERSION,
288 .ops = &iwl1000_ops,
289 .mod_params = &iwlagn_mod_params,
290 .base_params = &iwl1000_base_params,
291 .ht_params = &iwl1000_ht_params,
292};
280 293
281struct iwl_cfg iwl1000_bg_cfg = { 294struct iwl_cfg iwl1000_bg_cfg = {
282 .name = "Intel(R) Centrino(R) Wireless-N 1000 BG", 295 .name = "Intel(R) Centrino(R) Wireless-N 1000 BG",
@@ -284,30 +297,45 @@ struct iwl_cfg iwl1000_bg_cfg = {
284 .ucode_api_max = IWL1000_UCODE_API_MAX, 297 .ucode_api_max = IWL1000_UCODE_API_MAX,
285 .ucode_api_min = IWL1000_UCODE_API_MIN, 298 .ucode_api_min = IWL1000_UCODE_API_MIN,
286 .sku = IWL_SKU_G, 299 .sku = IWL_SKU_G,
300 .valid_tx_ant = ANT_A,
301 .valid_rx_ant = ANT_AB,
302 .eeprom_ver = EEPROM_1000_EEPROM_VERSION,
303 .eeprom_calib_ver = EEPROM_1000_TX_POWER_VERSION,
287 .ops = &iwl1000_ops, 304 .ops = &iwl1000_ops,
288 .eeprom_size = OTP_LOW_IMAGE_SIZE, 305 .mod_params = &iwlagn_mod_params,
306 .base_params = &iwl1000_base_params,
307};
308
309struct iwl_cfg iwl100_bgn_cfg = {
310 .name = "Intel(R) 100 Series 1x1 BGN",
311 .fw_name_pre = IWL100_FW_PRE,
312 .ucode_api_max = IWL100_UCODE_API_MAX,
313 .ucode_api_min = IWL100_UCODE_API_MIN,
314 .sku = IWL_SKU_G|IWL_SKU_N,
315 .valid_tx_ant = ANT_A,
316 .valid_rx_ant = ANT_A,
289 .eeprom_ver = EEPROM_1000_EEPROM_VERSION, 317 .eeprom_ver = EEPROM_1000_EEPROM_VERSION,
290 .eeprom_calib_ver = EEPROM_1000_TX_POWER_VERSION, 318 .eeprom_calib_ver = EEPROM_1000_TX_POWER_VERSION,
291 .num_of_queues = IWLAGN_NUM_QUEUES, 319 .ops = &iwl1000_ops,
292 .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
293 .mod_params = &iwlagn_mod_params, 320 .mod_params = &iwlagn_mod_params,
321 .base_params = &iwl1000_base_params,
322 .ht_params = &iwl1000_ht_params,
323};
324
325struct iwl_cfg iwl100_bg_cfg = {
326 .name = "Intel(R) 100 Series 1x1 BG",
327 .fw_name_pre = IWL100_FW_PRE,
328 .ucode_api_max = IWL100_UCODE_API_MAX,
329 .ucode_api_min = IWL100_UCODE_API_MIN,
330 .sku = IWL_SKU_G,
294 .valid_tx_ant = ANT_A, 331 .valid_tx_ant = ANT_A,
295 .valid_rx_ant = ANT_AB, 332 .valid_rx_ant = ANT_A,
296 .pll_cfg_val = CSR50_ANA_PLL_CFG_VAL, 333 .eeprom_ver = EEPROM_1000_EEPROM_VERSION,
297 .set_l0s = true, 334 .eeprom_calib_ver = EEPROM_1000_TX_POWER_VERSION,
298 .use_bsm = false, 335 .ops = &iwl1000_ops,
299 .max_ll_items = OTP_MAX_LL_ITEMS_1000, 336 .mod_params = &iwlagn_mod_params,
300 .shadow_ram_support = false, 337 .base_params = &iwl1000_base_params,
301 .led_compensation = 51,
302 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
303 .support_ct_kill_exit = true,
304 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_EXT_LONG_THRESHOLD_DEF,
305 .chain_noise_scale = 1000,
306 .monitor_recover_period = IWL_DEF_MONITORING_PERIOD,
307 .max_event_log_size = 128,
308 .ucode_tracing = true,
309 .sensitivity_calib_by_driver = true,
310 .chain_noise_calib_by_driver = true,
311}; 338};
312 339
313MODULE_FIRMWARE(IWL1000_MODULE_FIRMWARE(IWL1000_UCODE_API_MAX)); 340MODULE_FIRMWARE(IWL1000_MODULE_FIRMWARE(IWL1000_UCODE_API_MAX));
341MODULE_FIRMWARE(IWL100_MODULE_FIRMWARE(IWL100_UCODE_API_MAX));
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c
index 5d09686c338..cfdff5487e3 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.c
@@ -406,7 +406,7 @@ static bool iwl3945_good_plcp_health(struct iwl_priv *priv,
406 unsigned int plcp_msec; 406 unsigned int plcp_msec;
407 unsigned long plcp_received_jiffies; 407 unsigned long plcp_received_jiffies;
408 408
409 if (priv->cfg->plcp_delta_threshold == 409 if (priv->cfg->base_params->plcp_delta_threshold ==
410 IWL_MAX_PLCP_ERR_THRESHOLD_DISABLE) { 410 IWL_MAX_PLCP_ERR_THRESHOLD_DISABLE) {
411 IWL_DEBUG_RADIO(priv, "plcp_err check disabled\n"); 411 IWL_DEBUG_RADIO(priv, "plcp_err check disabled\n");
412 return rc; 412 return rc;
@@ -432,7 +432,7 @@ static bool iwl3945_good_plcp_health(struct iwl_priv *priv,
432 432
433 if ((combined_plcp_delta > 0) && 433 if ((combined_plcp_delta > 0) &&
434 ((combined_plcp_delta * 100) / plcp_msec) > 434 ((combined_plcp_delta * 100) / plcp_msec) >
435 priv->cfg->plcp_delta_threshold) { 435 priv->cfg->base_params->plcp_delta_threshold) {
436 /* 436 /*
437 * if plcp_err exceed the threshold, the following 437 * if plcp_err exceed the threshold, the following
438 * data is printed in csv format: 438 * data is printed in csv format:
@@ -444,7 +444,7 @@ static bool iwl3945_good_plcp_health(struct iwl_priv *priv,
444 */ 444 */
445 IWL_DEBUG_RADIO(priv, "plcp_err exceeded %u, " 445 IWL_DEBUG_RADIO(priv, "plcp_err exceeded %u, "
446 "%u, %d, %u mSecs\n", 446 "%u, %d, %u mSecs\n",
447 priv->cfg->plcp_delta_threshold, 447 priv->cfg->base_params->plcp_delta_threshold,
448 le32_to_cpu(current_stat.rx.ofdm.plcp_err), 448 le32_to_cpu(current_stat.rx.ofdm.plcp_err),
449 combined_plcp_delta, plcp_msec); 449 combined_plcp_delta, plcp_msec);
450 /* 450 /*
@@ -2421,7 +2421,7 @@ int iwl3945_hw_set_hw_params(struct iwl_priv *priv)
2421 } 2421 }
2422 2422
2423 /* Assign number of Usable TX queues */ 2423 /* Assign number of Usable TX queues */
2424 priv->hw_params.max_txq_num = priv->cfg->num_of_queues; 2424 priv->hw_params.max_txq_num = priv->cfg->base_params->num_of_queues;
2425 2425
2426 priv->hw_params.tfd_size = sizeof(struct iwl3945_tfd); 2426 priv->hw_params.tfd_size = sizeof(struct iwl3945_tfd);
2427 priv->hw_params.rx_page_order = get_order(IWL_RX_BUF_SIZE_3K); 2427 priv->hw_params.rx_page_order = get_order(IWL_RX_BUF_SIZE_3K);
@@ -2722,22 +2722,12 @@ static const struct iwl_ops iwl3945_ops = {
2722 .led = &iwl3945_led_ops, 2722 .led = &iwl3945_led_ops,
2723}; 2723};
2724 2724
2725static struct iwl_cfg iwl3945_bg_cfg = { 2725static struct iwl_base_params iwl3945_base_params = {
2726 .name = "3945BG",
2727 .fw_name_pre = IWL3945_FW_PRE,
2728 .ucode_api_max = IWL3945_UCODE_API_MAX,
2729 .ucode_api_min = IWL3945_UCODE_API_MIN,
2730 .sku = IWL_SKU_G,
2731 .eeprom_size = IWL3945_EEPROM_IMG_SIZE, 2726 .eeprom_size = IWL3945_EEPROM_IMG_SIZE,
2732 .eeprom_ver = EEPROM_3945_EEPROM_VERSION,
2733 .ops = &iwl3945_ops,
2734 .num_of_queues = IWL39_NUM_QUEUES,
2735 .mod_params = &iwl3945_mod_params,
2736 .pll_cfg_val = CSR39_ANA_PLL_CFG_VAL, 2727 .pll_cfg_val = CSR39_ANA_PLL_CFG_VAL,
2737 .set_l0s = false, 2728 .set_l0s = false,
2738 .use_bsm = true, 2729 .use_bsm = true,
2739 .use_isr_legacy = true, 2730 .use_isr_legacy = true,
2740 .ht_greenfield_support = false,
2741 .led_compensation = 64, 2731 .led_compensation = 64,
2742 .broken_powersave = true, 2732 .broken_powersave = true,
2743 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF, 2733 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
@@ -2746,25 +2736,28 @@ static struct iwl_cfg iwl3945_bg_cfg = {
2746 .tx_power_by_driver = true, 2736 .tx_power_by_driver = true,
2747}; 2737};
2748 2738
2739static struct iwl_cfg iwl3945_bg_cfg = {
2740 .name = "3945BG",
2741 .fw_name_pre = IWL3945_FW_PRE,
2742 .ucode_api_max = IWL3945_UCODE_API_MAX,
2743 .ucode_api_min = IWL3945_UCODE_API_MIN,
2744 .sku = IWL_SKU_G,
2745 .eeprom_ver = EEPROM_3945_EEPROM_VERSION,
2746 .ops = &iwl3945_ops,
2747 .mod_params = &iwl3945_mod_params,
2748 .base_params = &iwl3945_base_params,
2749};
2750
2749static struct iwl_cfg iwl3945_abg_cfg = { 2751static struct iwl_cfg iwl3945_abg_cfg = {
2750 .name = "3945ABG", 2752 .name = "3945ABG",
2751 .fw_name_pre = IWL3945_FW_PRE, 2753 .fw_name_pre = IWL3945_FW_PRE,
2752 .ucode_api_max = IWL3945_UCODE_API_MAX, 2754 .ucode_api_max = IWL3945_UCODE_API_MAX,
2753 .ucode_api_min = IWL3945_UCODE_API_MIN, 2755 .ucode_api_min = IWL3945_UCODE_API_MIN,
2754 .sku = IWL_SKU_A|IWL_SKU_G, 2756 .sku = IWL_SKU_A|IWL_SKU_G,
2755 .eeprom_size = IWL3945_EEPROM_IMG_SIZE,
2756 .eeprom_ver = EEPROM_3945_EEPROM_VERSION, 2757 .eeprom_ver = EEPROM_3945_EEPROM_VERSION,
2757 .ops = &iwl3945_ops, 2758 .ops = &iwl3945_ops,
2758 .num_of_queues = IWL39_NUM_QUEUES,
2759 .mod_params = &iwl3945_mod_params, 2759 .mod_params = &iwl3945_mod_params,
2760 .use_isr_legacy = true, 2760 .base_params = &iwl3945_base_params,
2761 .ht_greenfield_support = false,
2762 .led_compensation = 64,
2763 .broken_powersave = true,
2764 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
2765 .monitor_recover_period = IWL_DEF_MONITORING_PERIOD,
2766 .max_event_log_size = 512,
2767 .tx_power_by_driver = true,
2768}; 2761};
2769 2762
2770DEFINE_PCI_DEVICE_TABLE(iwl3945_hw_card_ids) = { 2763DEFINE_PCI_DEVICE_TABLE(iwl3945_hw_card_ids) = {
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c
index 943a9c7bfa7..834c2f9c15d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965.c
@@ -647,13 +647,13 @@ static int iwl4965_hw_set_hw_params(struct iwl_priv *priv)
647{ 647{
648 if (priv->cfg->mod_params->num_of_queues >= IWL_MIN_NUM_QUEUES && 648 if (priv->cfg->mod_params->num_of_queues >= IWL_MIN_NUM_QUEUES &&
649 priv->cfg->mod_params->num_of_queues <= IWL49_NUM_QUEUES) 649 priv->cfg->mod_params->num_of_queues <= IWL49_NUM_QUEUES)
650 priv->cfg->num_of_queues = 650 priv->cfg->base_params->num_of_queues =
651 priv->cfg->mod_params->num_of_queues; 651 priv->cfg->mod_params->num_of_queues;
652 652
653 priv->hw_params.max_txq_num = priv->cfg->num_of_queues; 653 priv->hw_params.max_txq_num = priv->cfg->base_params->num_of_queues;
654 priv->hw_params.dma_chnl_num = FH49_TCSR_CHNL_NUM; 654 priv->hw_params.dma_chnl_num = FH49_TCSR_CHNL_NUM;
655 priv->hw_params.scd_bc_tbls_size = 655 priv->hw_params.scd_bc_tbls_size =
656 priv->cfg->num_of_queues * 656 priv->cfg->base_params->num_of_queues *
657 sizeof(struct iwl4965_scd_bc_tbl); 657 sizeof(struct iwl4965_scd_bc_tbl);
658 priv->hw_params.tfd_size = sizeof(struct iwl_tfd); 658 priv->hw_params.tfd_size = sizeof(struct iwl_tfd);
659 priv->hw_params.max_stations = IWL4965_STATION_COUNT; 659 priv->hw_params.max_stations = IWL4965_STATION_COUNT;
@@ -1724,13 +1724,13 @@ static int iwl4965_txq_agg_disable(struct iwl_priv *priv, u16 txq_id,
1724 u16 ssn_idx, u8 tx_fifo) 1724 u16 ssn_idx, u8 tx_fifo)
1725{ 1725{
1726 if ((IWL49_FIRST_AMPDU_QUEUE > txq_id) || 1726 if ((IWL49_FIRST_AMPDU_QUEUE > txq_id) ||
1727 (IWL49_FIRST_AMPDU_QUEUE + priv->cfg->num_of_ampdu_queues 1727 (IWL49_FIRST_AMPDU_QUEUE +
1728 <= txq_id)) { 1728 priv->cfg->base_params->num_of_ampdu_queues <= txq_id)) {
1729 IWL_WARN(priv, 1729 IWL_WARN(priv,
1730 "queue number out of range: %d, must be %d to %d\n", 1730 "queue number out of range: %d, must be %d to %d\n",
1731 txq_id, IWL49_FIRST_AMPDU_QUEUE, 1731 txq_id, IWL49_FIRST_AMPDU_QUEUE,
1732 IWL49_FIRST_AMPDU_QUEUE + 1732 IWL49_FIRST_AMPDU_QUEUE +
1733 priv->cfg->num_of_ampdu_queues - 1); 1733 priv->cfg->base_params->num_of_ampdu_queues - 1);
1734 return -EINVAL; 1734 return -EINVAL;
1735 } 1735 }
1736 1736
@@ -1792,13 +1792,13 @@ static int iwl4965_txq_agg_enable(struct iwl_priv *priv, int txq_id,
1792 int ret; 1792 int ret;
1793 1793
1794 if ((IWL49_FIRST_AMPDU_QUEUE > txq_id) || 1794 if ((IWL49_FIRST_AMPDU_QUEUE > txq_id) ||
1795 (IWL49_FIRST_AMPDU_QUEUE + priv->cfg->num_of_ampdu_queues 1795 (IWL49_FIRST_AMPDU_QUEUE +
1796 <= txq_id)) { 1796 priv->cfg->base_params->num_of_ampdu_queues <= txq_id)) {
1797 IWL_WARN(priv, 1797 IWL_WARN(priv,
1798 "queue number out of range: %d, must be %d to %d\n", 1798 "queue number out of range: %d, must be %d to %d\n",
1799 txq_id, IWL49_FIRST_AMPDU_QUEUE, 1799 txq_id, IWL49_FIRST_AMPDU_QUEUE,
1800 IWL49_FIRST_AMPDU_QUEUE + 1800 IWL49_FIRST_AMPDU_QUEUE +
1801 priv->cfg->num_of_ampdu_queues - 1); 1801 priv->cfg->base_params->num_of_ampdu_queues - 1);
1802 return -EINVAL; 1802 return -EINVAL;
1803 } 1803 }
1804 1804
@@ -2302,26 +2302,14 @@ static const struct iwl_ops iwl4965_ops = {
2302 .led = &iwlagn_led_ops, 2302 .led = &iwlagn_led_ops,
2303}; 2303};
2304 2304
2305struct iwl_cfg iwl4965_agn_cfg = { 2305static struct iwl_base_params iwl4965_base_params = {
2306 .name = "Intel(R) Wireless WiFi Link 4965AGN",
2307 .fw_name_pre = IWL4965_FW_PRE,
2308 .ucode_api_max = IWL4965_UCODE_API_MAX,
2309 .ucode_api_min = IWL4965_UCODE_API_MIN,
2310 .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
2311 .eeprom_size = IWL4965_EEPROM_IMG_SIZE, 2306 .eeprom_size = IWL4965_EEPROM_IMG_SIZE,
2312 .eeprom_ver = EEPROM_4965_EEPROM_VERSION,
2313 .eeprom_calib_ver = EEPROM_4965_TX_POWER_VERSION,
2314 .ops = &iwl4965_ops,
2315 .num_of_queues = IWL49_NUM_QUEUES, 2307 .num_of_queues = IWL49_NUM_QUEUES,
2316 .num_of_ampdu_queues = IWL49_NUM_AMPDU_QUEUES, 2308 .num_of_ampdu_queues = IWL49_NUM_AMPDU_QUEUES,
2317 .mod_params = &iwlagn_mod_params,
2318 .valid_tx_ant = ANT_AB,
2319 .valid_rx_ant = ANT_ABC,
2320 .pll_cfg_val = 0, 2309 .pll_cfg_val = 0,
2321 .set_l0s = true, 2310 .set_l0s = true,
2322 .use_bsm = true, 2311 .use_bsm = true,
2323 .use_isr_legacy = true, 2312 .use_isr_legacy = true,
2324 .ht_greenfield_support = false,
2325 .broken_powersave = true, 2313 .broken_powersave = true,
2326 .led_compensation = 61, 2314 .led_compensation = 61,
2327 .chain_noise_num_beacons = IWL4965_CAL_NUM_BEACONS, 2315 .chain_noise_num_beacons = IWL4965_CAL_NUM_BEACONS,
@@ -2333,6 +2321,21 @@ struct iwl_cfg iwl4965_agn_cfg = {
2333 .ucode_tracing = true, 2321 .ucode_tracing = true,
2334 .sensitivity_calib_by_driver = true, 2322 .sensitivity_calib_by_driver = true,
2335 .chain_noise_calib_by_driver = true, 2323 .chain_noise_calib_by_driver = true,
2324};
2325
2326struct iwl_cfg iwl4965_agn_cfg = {
2327 .name = "Intel(R) Wireless WiFi Link 4965AGN",
2328 .fw_name_pre = IWL4965_FW_PRE,
2329 .ucode_api_max = IWL4965_UCODE_API_MAX,
2330 .ucode_api_min = IWL4965_UCODE_API_MIN,
2331 .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
2332 .valid_tx_ant = ANT_AB,
2333 .valid_rx_ant = ANT_ABC,
2334 .eeprom_ver = EEPROM_4965_EEPROM_VERSION,
2335 .eeprom_calib_ver = EEPROM_4965_TX_POWER_VERSION,
2336 .ops = &iwl4965_ops,
2337 .mod_params = &iwlagn_mod_params,
2338 .base_params = &iwl4965_base_params,
2336 /* 2339 /*
2337 * Force use of chains B and C for scan RX on 5 GHz band 2340 * Force use of chains B and C for scan RX on 5 GHz band
2338 * because the device has off-channel reception on chain A. 2341 * because the device has off-channel reception on chain A.
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c
index 21b4b23368e..1b25ad63b5c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
@@ -170,13 +170,13 @@ static int iwl5000_hw_set_hw_params(struct iwl_priv *priv)
170{ 170{
171 if (priv->cfg->mod_params->num_of_queues >= IWL_MIN_NUM_QUEUES && 171 if (priv->cfg->mod_params->num_of_queues >= IWL_MIN_NUM_QUEUES &&
172 priv->cfg->mod_params->num_of_queues <= IWLAGN_NUM_QUEUES) 172 priv->cfg->mod_params->num_of_queues <= IWLAGN_NUM_QUEUES)
173 priv->cfg->num_of_queues = 173 priv->cfg->base_params->num_of_queues =
174 priv->cfg->mod_params->num_of_queues; 174 priv->cfg->mod_params->num_of_queues;
175 175
176 priv->hw_params.max_txq_num = priv->cfg->num_of_queues; 176 priv->hw_params.max_txq_num = priv->cfg->base_params->num_of_queues;
177 priv->hw_params.dma_chnl_num = FH50_TCSR_CHNL_NUM; 177 priv->hw_params.dma_chnl_num = FH50_TCSR_CHNL_NUM;
178 priv->hw_params.scd_bc_tbls_size = 178 priv->hw_params.scd_bc_tbls_size =
179 priv->cfg->num_of_queues * 179 priv->cfg->base_params->num_of_queues *
180 sizeof(struct iwlagn_scd_bc_tbl); 180 sizeof(struct iwlagn_scd_bc_tbl);
181 priv->hw_params.tfd_size = sizeof(struct iwl_tfd); 181 priv->hw_params.tfd_size = sizeof(struct iwl_tfd);
182 priv->hw_params.max_stations = IWLAGN_STATION_COUNT; 182 priv->hw_params.max_stations = IWLAGN_STATION_COUNT;
@@ -217,13 +217,13 @@ static int iwl5150_hw_set_hw_params(struct iwl_priv *priv)
217{ 217{
218 if (priv->cfg->mod_params->num_of_queues >= IWL_MIN_NUM_QUEUES && 218 if (priv->cfg->mod_params->num_of_queues >= IWL_MIN_NUM_QUEUES &&
219 priv->cfg->mod_params->num_of_queues <= IWLAGN_NUM_QUEUES) 219 priv->cfg->mod_params->num_of_queues <= IWLAGN_NUM_QUEUES)
220 priv->cfg->num_of_queues = 220 priv->cfg->base_params->num_of_queues =
221 priv->cfg->mod_params->num_of_queues; 221 priv->cfg->mod_params->num_of_queues;
222 222
223 priv->hw_params.max_txq_num = priv->cfg->num_of_queues; 223 priv->hw_params.max_txq_num = priv->cfg->base_params->num_of_queues;
224 priv->hw_params.dma_chnl_num = FH50_TCSR_CHNL_NUM; 224 priv->hw_params.dma_chnl_num = FH50_TCSR_CHNL_NUM;
225 priv->hw_params.scd_bc_tbls_size = 225 priv->hw_params.scd_bc_tbls_size =
226 priv->cfg->num_of_queues * 226 priv->cfg->base_params->num_of_queues *
227 sizeof(struct iwlagn_scd_bc_tbl); 227 sizeof(struct iwlagn_scd_bc_tbl);
228 priv->hw_params.tfd_size = sizeof(struct iwl_tfd); 228 priv->hw_params.tfd_size = sizeof(struct iwl_tfd);
229 priv->hw_params.max_stations = IWLAGN_STATION_COUNT; 229 priv->hw_params.max_stations = IWLAGN_STATION_COUNT;
@@ -504,27 +504,14 @@ static const struct iwl_ops iwl5150_ops = {
504 .led = &iwlagn_led_ops, 504 .led = &iwlagn_led_ops,
505}; 505};
506 506
507struct iwl_cfg iwl5300_agn_cfg = { 507static struct iwl_base_params iwl5000_base_params = {
508 .name = "Intel(R) Ultimate N WiFi Link 5300 AGN",
509 .fw_name_pre = IWL5000_FW_PRE,
510 .ucode_api_max = IWL5000_UCODE_API_MAX,
511 .ucode_api_min = IWL5000_UCODE_API_MIN,
512 .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
513 .ops = &iwl5000_ops,
514 .eeprom_size = IWLAGN_EEPROM_IMG_SIZE, 508 .eeprom_size = IWLAGN_EEPROM_IMG_SIZE,
515 .eeprom_ver = EEPROM_5000_EEPROM_VERSION,
516 .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
517 .num_of_queues = IWLAGN_NUM_QUEUES, 509 .num_of_queues = IWLAGN_NUM_QUEUES,
518 .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, 510 .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
519 .mod_params = &iwlagn_mod_params,
520 .valid_tx_ant = ANT_ABC,
521 .valid_rx_ant = ANT_ABC,
522 .pll_cfg_val = CSR50_ANA_PLL_CFG_VAL, 511 .pll_cfg_val = CSR50_ANA_PLL_CFG_VAL,
523 .set_l0s = true, 512 .set_l0s = true,
524 .use_bsm = false, 513 .use_bsm = false,
525 .ht_greenfield_support = true,
526 .led_compensation = 51, 514 .led_compensation = 51,
527 .use_rts_for_aggregation = true, /* use rts/cts protection */
528 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, 515 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
529 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF, 516 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
530 .chain_noise_scale = 1000, 517 .chain_noise_scale = 1000,
@@ -534,6 +521,26 @@ struct iwl_cfg iwl5300_agn_cfg = {
534 .sensitivity_calib_by_driver = true, 521 .sensitivity_calib_by_driver = true,
535 .chain_noise_calib_by_driver = true, 522 .chain_noise_calib_by_driver = true,
536}; 523};
524static struct iwl_ht_params iwl5000_ht_params = {
525 .ht_greenfield_support = true,
526 .use_rts_for_aggregation = true, /* use rts/cts protection */
527};
528
529struct iwl_cfg iwl5300_agn_cfg = {
530 .name = "Intel(R) Ultimate N WiFi Link 5300 AGN",
531 .fw_name_pre = IWL5000_FW_PRE,
532 .ucode_api_max = IWL5000_UCODE_API_MAX,
533 .ucode_api_min = IWL5000_UCODE_API_MIN,
534 .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
535 .valid_tx_ant = ANT_ABC,
536 .valid_rx_ant = ANT_ABC,
537 .eeprom_ver = EEPROM_5000_EEPROM_VERSION,
538 .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
539 .ops = &iwl5000_ops,
540 .mod_params = &iwlagn_mod_params,
541 .base_params = &iwl5000_base_params,
542 .ht_params = &iwl5000_ht_params,
543};
537 544
538struct iwl_cfg iwl5100_bgn_cfg = { 545struct iwl_cfg iwl5100_bgn_cfg = {
539 .name = "Intel(R) WiFi Link 5100 BGN", 546 .name = "Intel(R) WiFi Link 5100 BGN",
@@ -541,29 +548,14 @@ struct iwl_cfg iwl5100_bgn_cfg = {
541 .ucode_api_max = IWL5000_UCODE_API_MAX, 548 .ucode_api_max = IWL5000_UCODE_API_MAX,
542 .ucode_api_min = IWL5000_UCODE_API_MIN, 549 .ucode_api_min = IWL5000_UCODE_API_MIN,
543 .sku = IWL_SKU_G|IWL_SKU_N, 550 .sku = IWL_SKU_G|IWL_SKU_N,
544 .ops = &iwl5000_ops, 551 .valid_tx_ant = ANT_B,
545 .eeprom_size = IWLAGN_EEPROM_IMG_SIZE, 552 .valid_rx_ant = ANT_AB,
546 .eeprom_ver = EEPROM_5000_EEPROM_VERSION, 553 .eeprom_ver = EEPROM_5000_EEPROM_VERSION,
547 .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, 554 .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
548 .num_of_queues = IWLAGN_NUM_QUEUES, 555 .ops = &iwl5000_ops,
549 .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
550 .mod_params = &iwlagn_mod_params, 556 .mod_params = &iwlagn_mod_params,
551 .valid_tx_ant = ANT_B, 557 .base_params = &iwl5000_base_params,
552 .valid_rx_ant = ANT_AB, 558 .ht_params = &iwl5000_ht_params,
553 .pll_cfg_val = CSR50_ANA_PLL_CFG_VAL,
554 .set_l0s = true,
555 .use_bsm = false,
556 .ht_greenfield_support = true,
557 .led_compensation = 51,
558 .use_rts_for_aggregation = true, /* use rts/cts protection */
559 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
560 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
561 .chain_noise_scale = 1000,
562 .monitor_recover_period = IWL_LONG_MONITORING_PERIOD,
563 .max_event_log_size = 512,
564 .ucode_tracing = true,
565 .sensitivity_calib_by_driver = true,
566 .chain_noise_calib_by_driver = true,
567}; 559};
568 560
569struct iwl_cfg iwl5100_abg_cfg = { 561struct iwl_cfg iwl5100_abg_cfg = {
@@ -572,27 +564,13 @@ struct iwl_cfg iwl5100_abg_cfg = {
572 .ucode_api_max = IWL5000_UCODE_API_MAX, 564 .ucode_api_max = IWL5000_UCODE_API_MAX,
573 .ucode_api_min = IWL5000_UCODE_API_MIN, 565 .ucode_api_min = IWL5000_UCODE_API_MIN,
574 .sku = IWL_SKU_A|IWL_SKU_G, 566 .sku = IWL_SKU_A|IWL_SKU_G,
575 .ops = &iwl5000_ops, 567 .valid_tx_ant = ANT_B,
576 .eeprom_size = IWLAGN_EEPROM_IMG_SIZE, 568 .valid_rx_ant = ANT_AB,
577 .eeprom_ver = EEPROM_5000_EEPROM_VERSION, 569 .eeprom_ver = EEPROM_5000_EEPROM_VERSION,
578 .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, 570 .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
579 .num_of_queues = IWLAGN_NUM_QUEUES, 571 .ops = &iwl5000_ops,
580 .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
581 .mod_params = &iwlagn_mod_params, 572 .mod_params = &iwlagn_mod_params,
582 .valid_tx_ant = ANT_B, 573 .base_params = &iwl5000_base_params,
583 .valid_rx_ant = ANT_AB,
584 .pll_cfg_val = CSR50_ANA_PLL_CFG_VAL,
585 .set_l0s = true,
586 .use_bsm = false,
587 .led_compensation = 51,
588 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
589 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
590 .chain_noise_scale = 1000,
591 .monitor_recover_period = IWL_LONG_MONITORING_PERIOD,
592 .max_event_log_size = 512,
593 .ucode_tracing = true,
594 .sensitivity_calib_by_driver = true,
595 .chain_noise_calib_by_driver = true,
596}; 574};
597 575
598struct iwl_cfg iwl5100_agn_cfg = { 576struct iwl_cfg iwl5100_agn_cfg = {
@@ -601,29 +579,14 @@ struct iwl_cfg iwl5100_agn_cfg = {
601 .ucode_api_max = IWL5000_UCODE_API_MAX, 579 .ucode_api_max = IWL5000_UCODE_API_MAX,
602 .ucode_api_min = IWL5000_UCODE_API_MIN, 580 .ucode_api_min = IWL5000_UCODE_API_MIN,
603 .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N, 581 .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
604 .ops = &iwl5000_ops, 582 .valid_tx_ant = ANT_B,
605 .eeprom_size = IWLAGN_EEPROM_IMG_SIZE, 583 .valid_rx_ant = ANT_AB,
606 .eeprom_ver = EEPROM_5000_EEPROM_VERSION, 584 .eeprom_ver = EEPROM_5000_EEPROM_VERSION,
607 .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, 585 .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
608 .num_of_queues = IWLAGN_NUM_QUEUES, 586 .ops = &iwl5000_ops,
609 .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
610 .mod_params = &iwlagn_mod_params, 587 .mod_params = &iwlagn_mod_params,
611 .valid_tx_ant = ANT_B, 588 .base_params = &iwl5000_base_params,
612 .valid_rx_ant = ANT_AB, 589 .ht_params = &iwl5000_ht_params,
613 .pll_cfg_val = CSR50_ANA_PLL_CFG_VAL,
614 .set_l0s = true,
615 .use_bsm = false,
616 .ht_greenfield_support = true,
617 .led_compensation = 51,
618 .use_rts_for_aggregation = true, /* use rts/cts protection */
619 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
620 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
621 .chain_noise_scale = 1000,
622 .monitor_recover_period = IWL_LONG_MONITORING_PERIOD,
623 .max_event_log_size = 512,
624 .ucode_tracing = true,
625 .sensitivity_calib_by_driver = true,
626 .chain_noise_calib_by_driver = true,
627}; 590};
628 591
629struct iwl_cfg iwl5350_agn_cfg = { 592struct iwl_cfg iwl5350_agn_cfg = {
@@ -632,29 +595,14 @@ struct iwl_cfg iwl5350_agn_cfg = {
632 .ucode_api_max = IWL5000_UCODE_API_MAX, 595 .ucode_api_max = IWL5000_UCODE_API_MAX,
633 .ucode_api_min = IWL5000_UCODE_API_MIN, 596 .ucode_api_min = IWL5000_UCODE_API_MIN,
634 .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N, 597 .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
635 .ops = &iwl5000_ops, 598 .valid_tx_ant = ANT_ABC,
636 .eeprom_size = IWLAGN_EEPROM_IMG_SIZE, 599 .valid_rx_ant = ANT_ABC,
637 .eeprom_ver = EEPROM_5050_EEPROM_VERSION, 600 .eeprom_ver = EEPROM_5050_EEPROM_VERSION,
638 .eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION, 601 .eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION,
639 .num_of_queues = IWLAGN_NUM_QUEUES, 602 .ops = &iwl5000_ops,
640 .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
641 .mod_params = &iwlagn_mod_params, 603 .mod_params = &iwlagn_mod_params,
642 .valid_tx_ant = ANT_ABC, 604 .base_params = &iwl5000_base_params,
643 .valid_rx_ant = ANT_ABC, 605 .ht_params = &iwl5000_ht_params,
644 .pll_cfg_val = CSR50_ANA_PLL_CFG_VAL,
645 .set_l0s = true,
646 .use_bsm = false,
647 .ht_greenfield_support = true,
648 .led_compensation = 51,
649 .use_rts_for_aggregation = true, /* use rts/cts protection */
650 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
651 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
652 .chain_noise_scale = 1000,
653 .monitor_recover_period = IWL_LONG_MONITORING_PERIOD,
654 .max_event_log_size = 512,
655 .ucode_tracing = true,
656 .sensitivity_calib_by_driver = true,
657 .chain_noise_calib_by_driver = true,
658}; 606};
659 607
660struct iwl_cfg iwl5150_agn_cfg = { 608struct iwl_cfg iwl5150_agn_cfg = {
@@ -663,29 +611,14 @@ struct iwl_cfg iwl5150_agn_cfg = {
663 .ucode_api_max = IWL5150_UCODE_API_MAX, 611 .ucode_api_max = IWL5150_UCODE_API_MAX,
664 .ucode_api_min = IWL5150_UCODE_API_MIN, 612 .ucode_api_min = IWL5150_UCODE_API_MIN,
665 .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N, 613 .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
666 .ops = &iwl5150_ops, 614 .valid_tx_ant = ANT_A,
667 .eeprom_size = IWLAGN_EEPROM_IMG_SIZE, 615 .valid_rx_ant = ANT_AB,
668 .eeprom_ver = EEPROM_5050_EEPROM_VERSION, 616 .eeprom_ver = EEPROM_5050_EEPROM_VERSION,
669 .eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION, 617 .eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION,
670 .num_of_queues = IWLAGN_NUM_QUEUES, 618 .ops = &iwl5150_ops,
671 .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
672 .mod_params = &iwlagn_mod_params, 619 .mod_params = &iwlagn_mod_params,
673 .valid_tx_ant = ANT_A, 620 .base_params = &iwl5000_base_params,
674 .valid_rx_ant = ANT_AB, 621 .ht_params = &iwl5000_ht_params,
675 .pll_cfg_val = CSR50_ANA_PLL_CFG_VAL,
676 .set_l0s = true,
677 .use_bsm = false,
678 .ht_greenfield_support = true,
679 .led_compensation = 51,
680 .use_rts_for_aggregation = true, /* use rts/cts protection */
681 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
682 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
683 .chain_noise_scale = 1000,
684 .monitor_recover_period = IWL_LONG_MONITORING_PERIOD,
685 .max_event_log_size = 512,
686 .ucode_tracing = true,
687 .sensitivity_calib_by_driver = true,
688 .chain_noise_calib_by_driver = true,
689 .need_dc_calib = true, 622 .need_dc_calib = true,
690}; 623};
691 624
@@ -695,27 +628,13 @@ struct iwl_cfg iwl5150_abg_cfg = {
695 .ucode_api_max = IWL5150_UCODE_API_MAX, 628 .ucode_api_max = IWL5150_UCODE_API_MAX,
696 .ucode_api_min = IWL5150_UCODE_API_MIN, 629 .ucode_api_min = IWL5150_UCODE_API_MIN,
697 .sku = IWL_SKU_A|IWL_SKU_G, 630 .sku = IWL_SKU_A|IWL_SKU_G,
698 .ops = &iwl5150_ops, 631 .valid_tx_ant = ANT_A,
699 .eeprom_size = IWLAGN_EEPROM_IMG_SIZE, 632 .valid_rx_ant = ANT_AB,
700 .eeprom_ver = EEPROM_5050_EEPROM_VERSION, 633 .eeprom_ver = EEPROM_5050_EEPROM_VERSION,
701 .eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION, 634 .eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION,
702 .num_of_queues = IWLAGN_NUM_QUEUES, 635 .ops = &iwl5150_ops,
703 .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
704 .mod_params = &iwlagn_mod_params, 636 .mod_params = &iwlagn_mod_params,
705 .valid_tx_ant = ANT_A, 637 .base_params = &iwl5000_base_params,
706 .valid_rx_ant = ANT_AB,
707 .pll_cfg_val = CSR50_ANA_PLL_CFG_VAL,
708 .set_l0s = true,
709 .use_bsm = false,
710 .led_compensation = 51,
711 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
712 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
713 .chain_noise_scale = 1000,
714 .monitor_recover_period = IWL_LONG_MONITORING_PERIOD,
715 .max_event_log_size = 512,
716 .ucode_tracing = true,
717 .sensitivity_calib_by_driver = true,
718 .chain_noise_calib_by_driver = true,
719 .need_dc_calib = true, 638 .need_dc_calib = true,
720}; 639};
721 640
diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c
index 9f43f2770c9..6261aec5ebd 100644
--- a/drivers/net/wireless/iwlwifi/iwl-6000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-6000.c
@@ -51,13 +51,15 @@
51 51
52/* Highest firmware API version supported */ 52/* Highest firmware API version supported */
53#define IWL6000_UCODE_API_MAX 4 53#define IWL6000_UCODE_API_MAX 4
54#define IWL6050_UCODE_API_MAX 4 54#define IWL6050_UCODE_API_MAX 5
55#define IWL6000G2_UCODE_API_MAX 5 55#define IWL6000G2_UCODE_API_MAX 5
56#define IWL130_UCODE_API_MAX 5
56 57
57/* Lowest firmware API version supported */ 58/* Lowest firmware API version supported */
58#define IWL6000_UCODE_API_MIN 4 59#define IWL6000_UCODE_API_MIN 4
59#define IWL6050_UCODE_API_MIN 4 60#define IWL6050_UCODE_API_MIN 4
60#define IWL6000G2_UCODE_API_MIN 4 61#define IWL6000G2_UCODE_API_MIN 4
62#define IWL130_UCODE_API_MIN 5
61 63
62#define IWL6000_FW_PRE "iwlwifi-6000-" 64#define IWL6000_FW_PRE "iwlwifi-6000-"
63#define _IWL6000_MODULE_FIRMWARE(api) IWL6000_FW_PRE #api ".ucode" 65#define _IWL6000_MODULE_FIRMWARE(api) IWL6000_FW_PRE #api ".ucode"
@@ -75,6 +77,9 @@
75#define _IWL6000G2B_MODULE_FIRMWARE(api) IWL6000G2B_FW_PRE #api ".ucode" 77#define _IWL6000G2B_MODULE_FIRMWARE(api) IWL6000G2B_FW_PRE #api ".ucode"
76#define IWL6000G2B_MODULE_FIRMWARE(api) _IWL6000G2B_MODULE_FIRMWARE(api) 78#define IWL6000G2B_MODULE_FIRMWARE(api) _IWL6000G2B_MODULE_FIRMWARE(api)
77 79
80#define IWL130_FW_PRE "iwlwifi-130-"
81#define _IWL130_MODULE_FIRMWARE(api) IWL130_FW_PRE #api ".ucode"
82#define IWL130_MODULE_FIRMWARE(api) _IWL130_MODULE_FIRMWARE(api)
78 83
79static void iwl6000_set_ct_threshold(struct iwl_priv *priv) 84static void iwl6000_set_ct_threshold(struct iwl_priv *priv)
80{ 85{
@@ -83,15 +88,24 @@ static void iwl6000_set_ct_threshold(struct iwl_priv *priv)
83 priv->hw_params.ct_kill_exit_threshold = CT_KILL_EXIT_THRESHOLD; 88 priv->hw_params.ct_kill_exit_threshold = CT_KILL_EXIT_THRESHOLD;
84} 89}
85 90
86/* Indicate calibration version to uCode. */ 91static void iwl6050_additional_nic_config(struct iwl_priv *priv)
87static void iwl6000_set_calib_version(struct iwl_priv *priv)
88{ 92{
89 if (priv->cfg->need_dc_calib && 93 /* Indicate calibration version to uCode. */
90 (priv->cfg->ops->lib->eeprom_ops.calib_version(priv) >= 6)) 94 if (priv->cfg->ops->lib->eeprom_ops.calib_version(priv) >= 6)
91 iwl_set_bit(priv, CSR_GP_DRIVER_REG, 95 iwl_set_bit(priv, CSR_GP_DRIVER_REG,
92 CSR_GP_DRIVER_REG_BIT_CALIB_VERSION6); 96 CSR_GP_DRIVER_REG_BIT_CALIB_VERSION6);
93} 97}
94 98
99static void iwl6050g2_additional_nic_config(struct iwl_priv *priv)
100{
101 /* Indicate calibration version to uCode. */
102 if (priv->cfg->ops->lib->eeprom_ops.calib_version(priv) >= 6)
103 iwl_set_bit(priv, CSR_GP_DRIVER_REG,
104 CSR_GP_DRIVER_REG_BIT_CALIB_VERSION6);
105 iwl_set_bit(priv, CSR_GP_DRIVER_REG,
106 CSR_GP_DRIVER_REG_BIT_6050_1x2);
107}
108
95/* NIC configuration for 6000 series */ 109/* NIC configuration for 6000 series */
96static void iwl6000_nic_config(struct iwl_priv *priv) 110static void iwl6000_nic_config(struct iwl_priv *priv)
97{ 111{
@@ -117,9 +131,11 @@ static void iwl6000_nic_config(struct iwl_priv *priv)
117 iwl_write32(priv, CSR_GP_DRIVER_REG, 131 iwl_write32(priv, CSR_GP_DRIVER_REG,
118 CSR_GP_DRIVER_REG_BIT_RADIO_SKU_2x2_IPA); 132 CSR_GP_DRIVER_REG_BIT_RADIO_SKU_2x2_IPA);
119 } 133 }
120 /* else do nothing, uCode configured */ 134 /* do additional nic configuration if needed */
121 if (priv->cfg->ops->lib->temp_ops.set_calib_version) 135 if (priv->cfg->ops->nic &&
122 priv->cfg->ops->lib->temp_ops.set_calib_version(priv); 136 priv->cfg->ops->nic->additional_nic_config) {
137 priv->cfg->ops->nic->additional_nic_config(priv);
138 }
123} 139}
124 140
125static struct iwl_sensitivity_ranges iwl6000_sensitivity = { 141static struct iwl_sensitivity_ranges iwl6000_sensitivity = {
@@ -151,13 +167,13 @@ static int iwl6000_hw_set_hw_params(struct iwl_priv *priv)
151{ 167{
152 if (priv->cfg->mod_params->num_of_queues >= IWL_MIN_NUM_QUEUES && 168 if (priv->cfg->mod_params->num_of_queues >= IWL_MIN_NUM_QUEUES &&
153 priv->cfg->mod_params->num_of_queues <= IWLAGN_NUM_QUEUES) 169 priv->cfg->mod_params->num_of_queues <= IWLAGN_NUM_QUEUES)
154 priv->cfg->num_of_queues = 170 priv->cfg->base_params->num_of_queues =
155 priv->cfg->mod_params->num_of_queues; 171 priv->cfg->mod_params->num_of_queues;
156 172
157 priv->hw_params.max_txq_num = priv->cfg->num_of_queues; 173 priv->hw_params.max_txq_num = priv->cfg->base_params->num_of_queues;
158 priv->hw_params.dma_chnl_num = FH50_TCSR_CHNL_NUM; 174 priv->hw_params.dma_chnl_num = FH50_TCSR_CHNL_NUM;
159 priv->hw_params.scd_bc_tbls_size = 175 priv->hw_params.scd_bc_tbls_size =
160 priv->cfg->num_of_queues * 176 priv->cfg->base_params->num_of_queues *
161 sizeof(struct iwlagn_scd_bc_tbl); 177 sizeof(struct iwlagn_scd_bc_tbl);
162 priv->hw_params.tfd_size = sizeof(struct iwl_tfd); 178 priv->hw_params.tfd_size = sizeof(struct iwl_tfd);
163 priv->hw_params.max_stations = IWLAGN_STATION_COUNT; 179 priv->hw_params.max_stations = IWLAGN_STATION_COUNT;
@@ -188,7 +204,7 @@ static int iwl6000_hw_set_hw_params(struct iwl_priv *priv)
188 BIT(IWL_CALIB_TX_IQ) | 204 BIT(IWL_CALIB_TX_IQ) |
189 BIT(IWL_CALIB_BASE_BAND); 205 BIT(IWL_CALIB_BASE_BAND);
190 if (priv->cfg->need_dc_calib) 206 if (priv->cfg->need_dc_calib)
191 priv->hw_params.calib_init_cfg |= BIT(IWL_CALIB_DC); 207 priv->hw_params.calib_rt_cfg |= BIT(IWL_CALIB_CFG_DC_IDX);
192 208
193 priv->hw_params.beacon_time_tsf_bits = IWLAGN_EXT_BEACON_TIME_POS; 209 priv->hw_params.beacon_time_tsf_bits = IWLAGN_EXT_BEACON_TIME_POS;
194 210
@@ -320,7 +336,6 @@ static struct iwl_lib_ops iwl6000_lib = {
320 .temp_ops = { 336 .temp_ops = {
321 .temperature = iwlagn_temperature, 337 .temperature = iwlagn_temperature,
322 .set_ct_kill = iwl6000_set_ct_threshold, 338 .set_ct_kill = iwl6000_set_ct_threshold,
323 .set_calib_version = iwl6000_set_calib_version,
324 }, 339 },
325 .manage_ibss_station = iwlagn_manage_ibss_station, 340 .manage_ibss_station = iwlagn_manage_ibss_station,
326 .update_bcast_stations = iwl_update_bcast_stations, 341 .update_bcast_stations = iwl_update_bcast_stations,
@@ -396,7 +411,6 @@ static struct iwl_lib_ops iwl6000g2b_lib = {
396 .temp_ops = { 411 .temp_ops = {
397 .temperature = iwlagn_temperature, 412 .temperature = iwlagn_temperature,
398 .set_ct_kill = iwl6000_set_ct_threshold, 413 .set_ct_kill = iwl6000_set_ct_threshold,
399 .set_calib_version = iwl6000_set_calib_version,
400 }, 414 },
401 .manage_ibss_station = iwlagn_manage_ibss_station, 415 .manage_ibss_station = iwlagn_manage_ibss_station,
402 .update_bcast_stations = iwl_update_bcast_stations, 416 .update_bcast_stations = iwl_update_bcast_stations,
@@ -419,6 +433,14 @@ static struct iwl_lib_ops iwl6000g2b_lib = {
419 } 433 }
420}; 434};
421 435
436static struct iwl_nic_ops iwl6050_nic_ops = {
437 .additional_nic_config = &iwl6050_additional_nic_config,
438};
439
440static struct iwl_nic_ops iwl6050g2_nic_ops = {
441 .additional_nic_config = &iwl6050g2_additional_nic_config,
442};
443
422static const struct iwl_ops iwl6000_ops = { 444static const struct iwl_ops iwl6000_ops = {
423 .lib = &iwl6000_lib, 445 .lib = &iwl6000_lib,
424 .hcmd = &iwlagn_hcmd, 446 .hcmd = &iwlagn_hcmd,
@@ -426,6 +448,22 @@ static const struct iwl_ops iwl6000_ops = {
426 .led = &iwlagn_led_ops, 448 .led = &iwlagn_led_ops,
427}; 449};
428 450
451static const struct iwl_ops iwl6050_ops = {
452 .lib = &iwl6000_lib,
453 .hcmd = &iwlagn_hcmd,
454 .utils = &iwlagn_hcmd_utils,
455 .led = &iwlagn_led_ops,
456 .nic = &iwl6050_nic_ops,
457};
458
459static const struct iwl_ops iwl6050g2_ops = {
460 .lib = &iwl6000_lib,
461 .hcmd = &iwlagn_hcmd,
462 .utils = &iwlagn_hcmd_utils,
463 .led = &iwlagn_led_ops,
464 .nic = &iwl6050g2_nic_ops,
465};
466
429static const struct iwl_ops iwl6000g2b_ops = { 467static const struct iwl_ops iwl6000g2b_ops = {
430 .lib = &iwl6000g2b_lib, 468 .lib = &iwl6000g2b_lib,
431 .hcmd = &iwlagn_bt_hcmd, 469 .hcmd = &iwlagn_bt_hcmd,
@@ -433,30 +471,16 @@ static const struct iwl_ops iwl6000g2b_ops = {
433 .led = &iwlagn_led_ops, 471 .led = &iwlagn_led_ops,
434}; 472};
435 473
436struct iwl_cfg iwl6000g2a_2agn_cfg = { 474static struct iwl_base_params iwl6000_base_params = {
437 .name = "6000 Series 2x2 AGN Gen2a",
438 .fw_name_pre = IWL6000G2A_FW_PRE,
439 .ucode_api_max = IWL6000G2_UCODE_API_MAX,
440 .ucode_api_min = IWL6000G2_UCODE_API_MIN,
441 .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
442 .ops = &iwl6000_ops,
443 .eeprom_size = OTP_LOW_IMAGE_SIZE, 475 .eeprom_size = OTP_LOW_IMAGE_SIZE,
444 .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION,
445 .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION,
446 .num_of_queues = IWLAGN_NUM_QUEUES, 476 .num_of_queues = IWLAGN_NUM_QUEUES,
447 .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, 477 .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
448 .mod_params = &iwlagn_mod_params,
449 .valid_tx_ant = ANT_AB,
450 .valid_rx_ant = ANT_AB,
451 .pll_cfg_val = 0, 478 .pll_cfg_val = 0,
452 .set_l0s = true, 479 .set_l0s = true,
453 .use_bsm = false, 480 .use_bsm = false,
454 .pa_type = IWL_PA_SYSTEM,
455 .max_ll_items = OTP_MAX_LL_ITEMS_6x00, 481 .max_ll_items = OTP_MAX_LL_ITEMS_6x00,
456 .shadow_ram_support = true, 482 .shadow_ram_support = true,
457 .ht_greenfield_support = true,
458 .led_compensation = 51, 483 .led_compensation = 51,
459 .use_rts_for_aggregation = true, /* use rts/cts protection */
460 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, 484 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
461 .supports_idle = true, 485 .supports_idle = true,
462 .adv_thermal_throttle = true, 486 .adv_thermal_throttle = true,
@@ -468,29 +492,16 @@ struct iwl_cfg iwl6000g2a_2agn_cfg = {
468 .ucode_tracing = true, 492 .ucode_tracing = true,
469 .sensitivity_calib_by_driver = true, 493 .sensitivity_calib_by_driver = true,
470 .chain_noise_calib_by_driver = true, 494 .chain_noise_calib_by_driver = true,
471 .need_dc_calib = true,
472}; 495};
473 496
474struct iwl_cfg iwl6000g2a_2abg_cfg = { 497static struct iwl_base_params iwl6050_base_params = {
475 .name = "6000 Series 2x2 ABG Gen2a",
476 .fw_name_pre = IWL6000G2A_FW_PRE,
477 .ucode_api_max = IWL6000G2_UCODE_API_MAX,
478 .ucode_api_min = IWL6000G2_UCODE_API_MIN,
479 .sku = IWL_SKU_A|IWL_SKU_G,
480 .ops = &iwl6000_ops,
481 .eeprom_size = OTP_LOW_IMAGE_SIZE, 498 .eeprom_size = OTP_LOW_IMAGE_SIZE,
482 .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION,
483 .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION,
484 .num_of_queues = IWLAGN_NUM_QUEUES, 499 .num_of_queues = IWLAGN_NUM_QUEUES,
485 .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, 500 .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
486 .mod_params = &iwlagn_mod_params,
487 .valid_tx_ant = ANT_AB,
488 .valid_rx_ant = ANT_AB,
489 .pll_cfg_val = 0, 501 .pll_cfg_val = 0,
490 .set_l0s = true, 502 .set_l0s = true,
491 .use_bsm = false, 503 .use_bsm = false,
492 .pa_type = IWL_PA_SYSTEM, 504 .max_ll_items = OTP_MAX_LL_ITEMS_6x50,
493 .max_ll_items = OTP_MAX_LL_ITEMS_6x00,
494 .shadow_ram_support = true, 505 .shadow_ram_support = true,
495 .led_compensation = 51, 506 .led_compensation = 51,
496 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, 507 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
@@ -498,11 +509,57 @@ struct iwl_cfg iwl6000g2a_2abg_cfg = {
498 .adv_thermal_throttle = true, 509 .adv_thermal_throttle = true,
499 .support_ct_kill_exit = true, 510 .support_ct_kill_exit = true,
500 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, 511 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
501 .chain_noise_scale = 1000, 512 .chain_noise_scale = 1500,
502 .monitor_recover_period = IWL_DEF_MONITORING_PERIOD, 513 .monitor_recover_period = IWL_DEF_MONITORING_PERIOD,
503 .max_event_log_size = 512, 514 .max_event_log_size = 1024,
515 .ucode_tracing = true,
504 .sensitivity_calib_by_driver = true, 516 .sensitivity_calib_by_driver = true,
505 .chain_noise_calib_by_driver = true, 517 .chain_noise_calib_by_driver = true,
518};
519
520static struct iwl_ht_params iwl6000_ht_params = {
521 .ht_greenfield_support = true,
522 .use_rts_for_aggregation = true, /* use rts/cts protection */
523};
524
525static struct iwl_bt_params iwl6000_bt_params = {
526 .bt_statistics = true,
527 /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */
528 .advanced_bt_coexist = true,
529 .bt_init_traffic_load = IWL_BT_COEX_TRAFFIC_LOAD_NONE,
530 .bt_prio_boost = IWLAGN_BT_PRIO_BOOST_DEFAULT,
531};
532
533struct iwl_cfg iwl6000g2a_2agn_cfg = {
534 .name = "6000 Series 2x2 AGN Gen2a",
535 .fw_name_pre = IWL6000G2A_FW_PRE,
536 .ucode_api_max = IWL6000G2_UCODE_API_MAX,
537 .ucode_api_min = IWL6000G2_UCODE_API_MIN,
538 .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
539 .valid_tx_ant = ANT_AB,
540 .valid_rx_ant = ANT_AB,
541 .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION,
542 .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION,
543 .ops = &iwl6000_ops,
544 .mod_params = &iwlagn_mod_params,
545 .base_params = &iwl6000_base_params,
546 .ht_params = &iwl6000_ht_params,
547 .need_dc_calib = true,
548};
549
550struct iwl_cfg iwl6000g2a_2abg_cfg = {
551 .name = "6000 Series 2x2 ABG Gen2a",
552 .fw_name_pre = IWL6000G2A_FW_PRE,
553 .ucode_api_max = IWL6000G2_UCODE_API_MAX,
554 .ucode_api_min = IWL6000G2_UCODE_API_MIN,
555 .sku = IWL_SKU_A|IWL_SKU_G,
556 .valid_tx_ant = ANT_AB,
557 .valid_rx_ant = ANT_AB,
558 .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION,
559 .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION,
560 .ops = &iwl6000_ops,
561 .mod_params = &iwlagn_mod_params,
562 .base_params = &iwl6000_base_params,
506 .need_dc_calib = true, 563 .need_dc_calib = true,
507}; 564};
508 565
@@ -512,32 +569,13 @@ struct iwl_cfg iwl6000g2a_2bg_cfg = {
512 .ucode_api_max = IWL6000G2_UCODE_API_MAX, 569 .ucode_api_max = IWL6000G2_UCODE_API_MAX,
513 .ucode_api_min = IWL6000G2_UCODE_API_MIN, 570 .ucode_api_min = IWL6000G2_UCODE_API_MIN,
514 .sku = IWL_SKU_G, 571 .sku = IWL_SKU_G,
515 .ops = &iwl6000_ops, 572 .valid_tx_ant = ANT_AB,
516 .eeprom_size = OTP_LOW_IMAGE_SIZE, 573 .valid_rx_ant = ANT_AB,
517 .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION, 574 .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION,
518 .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION, 575 .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION,
519 .num_of_queues = IWLAGN_NUM_QUEUES, 576 .ops = &iwl6000_ops,
520 .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
521 .mod_params = &iwlagn_mod_params, 577 .mod_params = &iwlagn_mod_params,
522 .valid_tx_ant = ANT_AB, 578 .base_params = &iwl6000_base_params,
523 .valid_rx_ant = ANT_AB,
524 .pll_cfg_val = 0,
525 .set_l0s = true,
526 .use_bsm = false,
527 .pa_type = IWL_PA_SYSTEM,
528 .max_ll_items = OTP_MAX_LL_ITEMS_6x00,
529 .shadow_ram_support = true,
530 .led_compensation = 51,
531 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
532 .supports_idle = true,
533 .adv_thermal_throttle = true,
534 .support_ct_kill_exit = true,
535 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
536 .chain_noise_scale = 1000,
537 .monitor_recover_period = IWL_DEF_MONITORING_PERIOD,
538 .max_event_log_size = 512,
539 .sensitivity_calib_by_driver = true,
540 .chain_noise_calib_by_driver = true,
541 .need_dc_calib = true, 579 .need_dc_calib = true,
542}; 580};
543 581
@@ -547,41 +585,18 @@ struct iwl_cfg iwl6000g2b_2agn_cfg = {
547 .ucode_api_max = IWL6000G2_UCODE_API_MAX, 585 .ucode_api_max = IWL6000G2_UCODE_API_MAX,
548 .ucode_api_min = IWL6000G2_UCODE_API_MIN, 586 .ucode_api_min = IWL6000G2_UCODE_API_MIN,
549 .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N, 587 .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
550 .ops = &iwl6000g2b_ops, 588 .valid_tx_ant = ANT_AB,
551 .eeprom_size = OTP_LOW_IMAGE_SIZE, 589 .valid_rx_ant = ANT_AB,
552 .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION, 590 .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION,
553 .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION, 591 .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION,
554 .num_of_queues = IWLAGN_NUM_QUEUES, 592 .ops = &iwl6000g2b_ops,
555 .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
556 .mod_params = &iwlagn_mod_params, 593 .mod_params = &iwlagn_mod_params,
557 .valid_tx_ant = ANT_AB, 594 .base_params = &iwl6000_base_params,
558 .valid_rx_ant = ANT_AB, 595 .bt_params = &iwl6000_bt_params,
559 .pll_cfg_val = 0, 596 .ht_params = &iwl6000_ht_params,
560 .set_l0s = true,
561 .use_bsm = false,
562 .pa_type = IWL_PA_SYSTEM,
563 .max_ll_items = OTP_MAX_LL_ITEMS_6x00,
564 .shadow_ram_support = true,
565 .ht_greenfield_support = true,
566 .led_compensation = 51,
567 .use_rts_for_aggregation = true, /* use rts/cts protection */
568 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
569 .supports_idle = true,
570 .adv_thermal_throttle = true,
571 .support_ct_kill_exit = true,
572 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DISABLE,
573 .chain_noise_scale = 1000,
574 .monitor_recover_period = IWL_LONG_MONITORING_PERIOD,
575 .max_event_log_size = 512,
576 .sensitivity_calib_by_driver = true,
577 .chain_noise_calib_by_driver = true,
578 .need_dc_calib = true, 597 .need_dc_calib = true,
579 .bt_statistics = true,
580 /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ 598 /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */
581 .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, 599 .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A,
582 .advanced_bt_coexist = true,
583 .bt_init_traffic_load = IWL_BT_COEX_TRAFFIC_LOAD_NONE,
584 .bt_prio_boost = IWLAGN_BT_PRIO_BOOST_DEFAULT,
585}; 600};
586 601
587struct iwl_cfg iwl6000g2b_2abg_cfg = { 602struct iwl_cfg iwl6000g2b_2abg_cfg = {
@@ -590,39 +605,17 @@ struct iwl_cfg iwl6000g2b_2abg_cfg = {
590 .ucode_api_max = IWL6000G2_UCODE_API_MAX, 605 .ucode_api_max = IWL6000G2_UCODE_API_MAX,
591 .ucode_api_min = IWL6000G2_UCODE_API_MIN, 606 .ucode_api_min = IWL6000G2_UCODE_API_MIN,
592 .sku = IWL_SKU_A|IWL_SKU_G, 607 .sku = IWL_SKU_A|IWL_SKU_G,
593 .ops = &iwl6000g2b_ops, 608 .valid_tx_ant = ANT_AB,
594 .eeprom_size = OTP_LOW_IMAGE_SIZE, 609 .valid_rx_ant = ANT_AB,
595 .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION, 610 .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION,
596 .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION, 611 .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION,
597 .num_of_queues = IWLAGN_NUM_QUEUES, 612 .ops = &iwl6000g2b_ops,
598 .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
599 .mod_params = &iwlagn_mod_params, 613 .mod_params = &iwlagn_mod_params,
600 .valid_tx_ant = ANT_AB, 614 .base_params = &iwl6000_base_params,
601 .valid_rx_ant = ANT_AB, 615 .bt_params = &iwl6000_bt_params,
602 .pll_cfg_val = 0,
603 .set_l0s = true,
604 .use_bsm = false,
605 .pa_type = IWL_PA_SYSTEM,
606 .max_ll_items = OTP_MAX_LL_ITEMS_6x00,
607 .shadow_ram_support = true,
608 .led_compensation = 51,
609 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
610 .supports_idle = true,
611 .adv_thermal_throttle = true,
612 .support_ct_kill_exit = true,
613 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DISABLE,
614 .chain_noise_scale = 1000,
615 .monitor_recover_period = IWL_LONG_MONITORING_PERIOD,
616 .max_event_log_size = 512,
617 .sensitivity_calib_by_driver = true,
618 .chain_noise_calib_by_driver = true,
619 .need_dc_calib = true, 616 .need_dc_calib = true,
620 .bt_statistics = true,
621 /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ 617 /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */
622 .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, 618 .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A,
623 .advanced_bt_coexist = true,
624 .bt_init_traffic_load = IWL_BT_COEX_TRAFFIC_LOAD_NONE,
625 .bt_prio_boost = IWLAGN_BT_PRIO_BOOST_DEFAULT,
626}; 619};
627 620
628struct iwl_cfg iwl6000g2b_2bgn_cfg = { 621struct iwl_cfg iwl6000g2b_2bgn_cfg = {
@@ -631,41 +624,18 @@ struct iwl_cfg iwl6000g2b_2bgn_cfg = {
631 .ucode_api_max = IWL6000G2_UCODE_API_MAX, 624 .ucode_api_max = IWL6000G2_UCODE_API_MAX,
632 .ucode_api_min = IWL6000G2_UCODE_API_MIN, 625 .ucode_api_min = IWL6000G2_UCODE_API_MIN,
633 .sku = IWL_SKU_G|IWL_SKU_N, 626 .sku = IWL_SKU_G|IWL_SKU_N,
634 .ops = &iwl6000g2b_ops, 627 .valid_tx_ant = ANT_AB,
635 .eeprom_size = OTP_LOW_IMAGE_SIZE, 628 .valid_rx_ant = ANT_AB,
636 .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION, 629 .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION,
637 .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION, 630 .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION,
638 .num_of_queues = IWLAGN_NUM_QUEUES, 631 .ops = &iwl6000g2b_ops,
639 .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
640 .mod_params = &iwlagn_mod_params, 632 .mod_params = &iwlagn_mod_params,
641 .valid_tx_ant = ANT_AB, 633 .base_params = &iwl6000_base_params,
642 .valid_rx_ant = ANT_AB, 634 .bt_params = &iwl6000_bt_params,
643 .pll_cfg_val = 0, 635 .ht_params = &iwl6000_ht_params,
644 .set_l0s = true,
645 .use_bsm = false,
646 .pa_type = IWL_PA_SYSTEM,
647 .max_ll_items = OTP_MAX_LL_ITEMS_6x00,
648 .shadow_ram_support = true,
649 .ht_greenfield_support = true,
650 .led_compensation = 51,
651 .use_rts_for_aggregation = true, /* use rts/cts protection */
652 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
653 .supports_idle = true,
654 .adv_thermal_throttle = true,
655 .support_ct_kill_exit = true,
656 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DISABLE,
657 .chain_noise_scale = 1000,
658 .monitor_recover_period = IWL_LONG_MONITORING_PERIOD,
659 .max_event_log_size = 512,
660 .sensitivity_calib_by_driver = true,
661 .chain_noise_calib_by_driver = true,
662 .need_dc_calib = true, 636 .need_dc_calib = true,
663 .bt_statistics = true,
664 /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ 637 /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */
665 .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, 638 .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A,
666 .advanced_bt_coexist = true,
667 .bt_init_traffic_load = IWL_BT_COEX_TRAFFIC_LOAD_NONE,
668 .bt_prio_boost = IWLAGN_BT_PRIO_BOOST_DEFAULT,
669}; 639};
670 640
671struct iwl_cfg iwl6000g2b_2bg_cfg = { 641struct iwl_cfg iwl6000g2b_2bg_cfg = {
@@ -674,39 +644,17 @@ struct iwl_cfg iwl6000g2b_2bg_cfg = {
674 .ucode_api_max = IWL6000G2_UCODE_API_MAX, 644 .ucode_api_max = IWL6000G2_UCODE_API_MAX,
675 .ucode_api_min = IWL6000G2_UCODE_API_MIN, 645 .ucode_api_min = IWL6000G2_UCODE_API_MIN,
676 .sku = IWL_SKU_G, 646 .sku = IWL_SKU_G,
677 .ops = &iwl6000g2b_ops, 647 .valid_tx_ant = ANT_AB,
678 .eeprom_size = OTP_LOW_IMAGE_SIZE, 648 .valid_rx_ant = ANT_AB,
679 .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION, 649 .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION,
680 .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION, 650 .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION,
681 .num_of_queues = IWLAGN_NUM_QUEUES, 651 .ops = &iwl6000g2b_ops,
682 .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
683 .mod_params = &iwlagn_mod_params, 652 .mod_params = &iwlagn_mod_params,
684 .valid_tx_ant = ANT_AB, 653 .base_params = &iwl6000_base_params,
685 .valid_rx_ant = ANT_AB, 654 .bt_params = &iwl6000_bt_params,
686 .pll_cfg_val = 0,
687 .set_l0s = true,
688 .use_bsm = false,
689 .pa_type = IWL_PA_SYSTEM,
690 .max_ll_items = OTP_MAX_LL_ITEMS_6x00,
691 .shadow_ram_support = true,
692 .led_compensation = 51,
693 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
694 .supports_idle = true,
695 .adv_thermal_throttle = true,
696 .support_ct_kill_exit = true,
697 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DISABLE,
698 .chain_noise_scale = 1000,
699 .monitor_recover_period = IWL_LONG_MONITORING_PERIOD,
700 .max_event_log_size = 512,
701 .sensitivity_calib_by_driver = true,
702 .chain_noise_calib_by_driver = true,
703 .need_dc_calib = true, 655 .need_dc_calib = true,
704 .bt_statistics = true,
705 /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ 656 /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */
706 .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, 657 .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A,
707 .advanced_bt_coexist = true,
708 .bt_init_traffic_load = IWL_BT_COEX_TRAFFIC_LOAD_NONE,
709 .bt_prio_boost = IWLAGN_BT_PRIO_BOOST_DEFAULT,
710}; 658};
711 659
712struct iwl_cfg iwl6000g2b_bgn_cfg = { 660struct iwl_cfg iwl6000g2b_bgn_cfg = {
@@ -715,41 +663,18 @@ struct iwl_cfg iwl6000g2b_bgn_cfg = {
715 .ucode_api_max = IWL6000G2_UCODE_API_MAX, 663 .ucode_api_max = IWL6000G2_UCODE_API_MAX,
716 .ucode_api_min = IWL6000G2_UCODE_API_MIN, 664 .ucode_api_min = IWL6000G2_UCODE_API_MIN,
717 .sku = IWL_SKU_G|IWL_SKU_N, 665 .sku = IWL_SKU_G|IWL_SKU_N,
718 .ops = &iwl6000g2b_ops, 666 .valid_tx_ant = ANT_A,
719 .eeprom_size = OTP_LOW_IMAGE_SIZE, 667 .valid_rx_ant = ANT_AB,
720 .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION, 668 .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION,
721 .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION, 669 .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION,
722 .num_of_queues = IWLAGN_NUM_QUEUES, 670 .ops = &iwl6000g2b_ops,
723 .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
724 .mod_params = &iwlagn_mod_params, 671 .mod_params = &iwlagn_mod_params,
725 .valid_tx_ant = ANT_A, 672 .base_params = &iwl6000_base_params,
726 .valid_rx_ant = ANT_AB, 673 .bt_params = &iwl6000_bt_params,
727 .pll_cfg_val = 0, 674 .ht_params = &iwl6000_ht_params,
728 .set_l0s = true,
729 .use_bsm = false,
730 .pa_type = IWL_PA_SYSTEM,
731 .max_ll_items = OTP_MAX_LL_ITEMS_6x00,
732 .shadow_ram_support = true,
733 .ht_greenfield_support = true,
734 .led_compensation = 51,
735 .use_rts_for_aggregation = true, /* use rts/cts protection */
736 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
737 .supports_idle = true,
738 .adv_thermal_throttle = true,
739 .support_ct_kill_exit = true,
740 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DISABLE,
741 .chain_noise_scale = 1000,
742 .monitor_recover_period = IWL_LONG_MONITORING_PERIOD,
743 .max_event_log_size = 512,
744 .sensitivity_calib_by_driver = true,
745 .chain_noise_calib_by_driver = true,
746 .need_dc_calib = true, 675 .need_dc_calib = true,
747 .bt_statistics = true,
748 /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ 676 /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */
749 .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, 677 .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A,
750 .advanced_bt_coexist = true,
751 .bt_init_traffic_load = IWL_BT_COEX_TRAFFIC_LOAD_NONE,
752 .bt_prio_boost = IWLAGN_BT_PRIO_BOOST_DEFAULT,
753}; 678};
754 679
755struct iwl_cfg iwl6000g2b_bg_cfg = { 680struct iwl_cfg iwl6000g2b_bg_cfg = {
@@ -758,39 +683,17 @@ struct iwl_cfg iwl6000g2b_bg_cfg = {
758 .ucode_api_max = IWL6000G2_UCODE_API_MAX, 683 .ucode_api_max = IWL6000G2_UCODE_API_MAX,
759 .ucode_api_min = IWL6000G2_UCODE_API_MIN, 684 .ucode_api_min = IWL6000G2_UCODE_API_MIN,
760 .sku = IWL_SKU_G, 685 .sku = IWL_SKU_G,
761 .ops = &iwl6000g2b_ops, 686 .valid_tx_ant = ANT_A,
762 .eeprom_size = OTP_LOW_IMAGE_SIZE, 687 .valid_rx_ant = ANT_AB,
763 .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION, 688 .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION,
764 .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION, 689 .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION,
765 .num_of_queues = IWLAGN_NUM_QUEUES, 690 .ops = &iwl6000g2b_ops,
766 .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
767 .mod_params = &iwlagn_mod_params, 691 .mod_params = &iwlagn_mod_params,
768 .valid_tx_ant = ANT_A, 692 .base_params = &iwl6000_base_params,
769 .valid_rx_ant = ANT_AB, 693 .bt_params = &iwl6000_bt_params,
770 .pll_cfg_val = 0,
771 .set_l0s = true,
772 .use_bsm = false,
773 .pa_type = IWL_PA_SYSTEM,
774 .max_ll_items = OTP_MAX_LL_ITEMS_6x00,
775 .shadow_ram_support = true,
776 .led_compensation = 51,
777 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
778 .supports_idle = true,
779 .adv_thermal_throttle = true,
780 .support_ct_kill_exit = true,
781 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DISABLE,
782 .chain_noise_scale = 1000,
783 .monitor_recover_period = IWL_LONG_MONITORING_PERIOD,
784 .max_event_log_size = 512,
785 .sensitivity_calib_by_driver = true,
786 .chain_noise_calib_by_driver = true,
787 .need_dc_calib = true, 694 .need_dc_calib = true,
788 .bt_statistics = true,
789 /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ 695 /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */
790 .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, 696 .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A,
791 .advanced_bt_coexist = true,
792 .bt_init_traffic_load = IWL_BT_COEX_TRAFFIC_LOAD_NONE,
793 .bt_prio_boost = IWLAGN_BT_PRIO_BOOST_DEFAULT,
794}; 697};
795 698
796/* 699/*
@@ -802,35 +705,15 @@ struct iwl_cfg iwl6000i_2agn_cfg = {
802 .ucode_api_max = IWL6000_UCODE_API_MAX, 705 .ucode_api_max = IWL6000_UCODE_API_MAX,
803 .ucode_api_min = IWL6000_UCODE_API_MIN, 706 .ucode_api_min = IWL6000_UCODE_API_MIN,
804 .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N, 707 .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
805 .ops = &iwl6000_ops, 708 .valid_tx_ant = ANT_BC,
806 .eeprom_size = OTP_LOW_IMAGE_SIZE, 709 .valid_rx_ant = ANT_BC,
807 .eeprom_ver = EEPROM_6000_EEPROM_VERSION, 710 .eeprom_ver = EEPROM_6000_EEPROM_VERSION,
808 .eeprom_calib_ver = EEPROM_6000_TX_POWER_VERSION, 711 .eeprom_calib_ver = EEPROM_6000_TX_POWER_VERSION,
809 .num_of_queues = IWLAGN_NUM_QUEUES, 712 .ops = &iwl6000_ops,
810 .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
811 .mod_params = &iwlagn_mod_params, 713 .mod_params = &iwlagn_mod_params,
812 .valid_tx_ant = ANT_BC, 714 .base_params = &iwl6000_base_params,
813 .valid_rx_ant = ANT_BC, 715 .ht_params = &iwl6000_ht_params,
814 .pll_cfg_val = 0,
815 .set_l0s = true,
816 .use_bsm = false,
817 .pa_type = IWL_PA_INTERNAL, 716 .pa_type = IWL_PA_INTERNAL,
818 .max_ll_items = OTP_MAX_LL_ITEMS_6x00,
819 .shadow_ram_support = true,
820 .ht_greenfield_support = true,
821 .led_compensation = 51,
822 .use_rts_for_aggregation = true, /* use rts/cts protection */
823 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
824 .supports_idle = true,
825 .adv_thermal_throttle = true,
826 .support_ct_kill_exit = true,
827 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
828 .chain_noise_scale = 1000,
829 .monitor_recover_period = IWL_DEF_MONITORING_PERIOD,
830 .max_event_log_size = 1024,
831 .ucode_tracing = true,
832 .sensitivity_calib_by_driver = true,
833 .chain_noise_calib_by_driver = true,
834}; 717};
835 718
836struct iwl_cfg iwl6000i_2abg_cfg = { 719struct iwl_cfg iwl6000i_2abg_cfg = {
@@ -839,33 +722,14 @@ struct iwl_cfg iwl6000i_2abg_cfg = {
839 .ucode_api_max = IWL6000_UCODE_API_MAX, 722 .ucode_api_max = IWL6000_UCODE_API_MAX,
840 .ucode_api_min = IWL6000_UCODE_API_MIN, 723 .ucode_api_min = IWL6000_UCODE_API_MIN,
841 .sku = IWL_SKU_A|IWL_SKU_G, 724 .sku = IWL_SKU_A|IWL_SKU_G,
842 .ops = &iwl6000_ops, 725 .valid_tx_ant = ANT_BC,
843 .eeprom_size = OTP_LOW_IMAGE_SIZE, 726 .valid_rx_ant = ANT_BC,
844 .eeprom_ver = EEPROM_6000_EEPROM_VERSION, 727 .eeprom_ver = EEPROM_6000_EEPROM_VERSION,
845 .eeprom_calib_ver = EEPROM_6000_TX_POWER_VERSION, 728 .eeprom_calib_ver = EEPROM_6000_TX_POWER_VERSION,
846 .num_of_queues = IWLAGN_NUM_QUEUES, 729 .ops = &iwl6000_ops,
847 .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
848 .mod_params = &iwlagn_mod_params, 730 .mod_params = &iwlagn_mod_params,
849 .valid_tx_ant = ANT_BC, 731 .base_params = &iwl6000_base_params,
850 .valid_rx_ant = ANT_BC,
851 .pll_cfg_val = 0,
852 .set_l0s = true,
853 .use_bsm = false,
854 .pa_type = IWL_PA_INTERNAL, 732 .pa_type = IWL_PA_INTERNAL,
855 .max_ll_items = OTP_MAX_LL_ITEMS_6x00,
856 .shadow_ram_support = true,
857 .led_compensation = 51,
858 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
859 .supports_idle = true,
860 .adv_thermal_throttle = true,
861 .support_ct_kill_exit = true,
862 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
863 .chain_noise_scale = 1000,
864 .monitor_recover_period = IWL_DEF_MONITORING_PERIOD,
865 .max_event_log_size = 1024,
866 .ucode_tracing = true,
867 .sensitivity_calib_by_driver = true,
868 .chain_noise_calib_by_driver = true,
869}; 733};
870 734
871struct iwl_cfg iwl6000i_2bg_cfg = { 735struct iwl_cfg iwl6000i_2bg_cfg = {
@@ -874,33 +738,14 @@ struct iwl_cfg iwl6000i_2bg_cfg = {
874 .ucode_api_max = IWL6000_UCODE_API_MAX, 738 .ucode_api_max = IWL6000_UCODE_API_MAX,
875 .ucode_api_min = IWL6000_UCODE_API_MIN, 739 .ucode_api_min = IWL6000_UCODE_API_MIN,
876 .sku = IWL_SKU_G, 740 .sku = IWL_SKU_G,
877 .ops = &iwl6000_ops, 741 .valid_tx_ant = ANT_BC,
878 .eeprom_size = OTP_LOW_IMAGE_SIZE, 742 .valid_rx_ant = ANT_BC,
879 .eeprom_ver = EEPROM_6000_EEPROM_VERSION, 743 .eeprom_ver = EEPROM_6000_EEPROM_VERSION,
880 .eeprom_calib_ver = EEPROM_6000_TX_POWER_VERSION, 744 .eeprom_calib_ver = EEPROM_6000_TX_POWER_VERSION,
881 .num_of_queues = IWLAGN_NUM_QUEUES, 745 .ops = &iwl6000_ops,
882 .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
883 .mod_params = &iwlagn_mod_params, 746 .mod_params = &iwlagn_mod_params,
884 .valid_tx_ant = ANT_BC, 747 .base_params = &iwl6000_base_params,
885 .valid_rx_ant = ANT_BC,
886 .pll_cfg_val = 0,
887 .set_l0s = true,
888 .use_bsm = false,
889 .pa_type = IWL_PA_INTERNAL, 748 .pa_type = IWL_PA_INTERNAL,
890 .max_ll_items = OTP_MAX_LL_ITEMS_6x00,
891 .shadow_ram_support = true,
892 .led_compensation = 51,
893 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
894 .supports_idle = true,
895 .adv_thermal_throttle = true,
896 .support_ct_kill_exit = true,
897 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
898 .chain_noise_scale = 1000,
899 .monitor_recover_period = IWL_DEF_MONITORING_PERIOD,
900 .max_event_log_size = 1024,
901 .ucode_tracing = true,
902 .sensitivity_calib_by_driver = true,
903 .chain_noise_calib_by_driver = true,
904}; 749};
905 750
906struct iwl_cfg iwl6050_2agn_cfg = { 751struct iwl_cfg iwl6050_2agn_cfg = {
@@ -909,35 +754,14 @@ struct iwl_cfg iwl6050_2agn_cfg = {
909 .ucode_api_max = IWL6050_UCODE_API_MAX, 754 .ucode_api_max = IWL6050_UCODE_API_MAX,
910 .ucode_api_min = IWL6050_UCODE_API_MIN, 755 .ucode_api_min = IWL6050_UCODE_API_MIN,
911 .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N, 756 .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
757 .valid_tx_ant = ANT_AB,
758 .valid_rx_ant = ANT_AB,
912 .ops = &iwl6000_ops, 759 .ops = &iwl6000_ops,
913 .eeprom_size = OTP_LOW_IMAGE_SIZE,
914 .eeprom_ver = EEPROM_6050_EEPROM_VERSION, 760 .eeprom_ver = EEPROM_6050_EEPROM_VERSION,
915 .eeprom_calib_ver = EEPROM_6050_TX_POWER_VERSION, 761 .eeprom_calib_ver = EEPROM_6050_TX_POWER_VERSION,
916 .num_of_queues = IWLAGN_NUM_QUEUES,
917 .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
918 .mod_params = &iwlagn_mod_params, 762 .mod_params = &iwlagn_mod_params,
919 .valid_tx_ant = ANT_AB, 763 .base_params = &iwl6050_base_params,
920 .valid_rx_ant = ANT_AB, 764 .ht_params = &iwl6000_ht_params,
921 .pll_cfg_val = 0,
922 .set_l0s = true,
923 .use_bsm = false,
924 .pa_type = IWL_PA_SYSTEM,
925 .max_ll_items = OTP_MAX_LL_ITEMS_6x50,
926 .shadow_ram_support = true,
927 .ht_greenfield_support = true,
928 .led_compensation = 51,
929 .use_rts_for_aggregation = true, /* use rts/cts protection */
930 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
931 .supports_idle = true,
932 .adv_thermal_throttle = true,
933 .support_ct_kill_exit = true,
934 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
935 .chain_noise_scale = 1500,
936 .monitor_recover_period = IWL_DEF_MONITORING_PERIOD,
937 .max_event_log_size = 1024,
938 .ucode_tracing = true,
939 .sensitivity_calib_by_driver = true,
940 .chain_noise_calib_by_driver = true,
941 .need_dc_calib = true, 765 .need_dc_calib = true,
942}; 766};
943 767
@@ -947,35 +771,14 @@ struct iwl_cfg iwl6050g2_bgn_cfg = {
947 .ucode_api_max = IWL6050_UCODE_API_MAX, 771 .ucode_api_max = IWL6050_UCODE_API_MAX,
948 .ucode_api_min = IWL6050_UCODE_API_MIN, 772 .ucode_api_min = IWL6050_UCODE_API_MIN,
949 .sku = IWL_SKU_G|IWL_SKU_N, 773 .sku = IWL_SKU_G|IWL_SKU_N,
950 .ops = &iwl6000_ops, 774 .valid_tx_ant = ANT_A,
951 .eeprom_size = OTP_LOW_IMAGE_SIZE, 775 .valid_rx_ant = ANT_AB,
952 .eeprom_ver = EEPROM_6050G2_EEPROM_VERSION, 776 .eeprom_ver = EEPROM_6050G2_EEPROM_VERSION,
953 .eeprom_calib_ver = EEPROM_6050G2_TX_POWER_VERSION, 777 .eeprom_calib_ver = EEPROM_6050G2_TX_POWER_VERSION,
954 .num_of_queues = IWLAGN_NUM_QUEUES, 778 .ops = &iwl6050g2_ops,
955 .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
956 .mod_params = &iwlagn_mod_params, 779 .mod_params = &iwlagn_mod_params,
957 .valid_tx_ant = ANT_A, 780 .base_params = &iwl6050_base_params,
958 .valid_rx_ant = ANT_AB, 781 .ht_params = &iwl6000_ht_params,
959 .pll_cfg_val = 0,
960 .set_l0s = true,
961 .use_bsm = false,
962 .pa_type = IWL_PA_SYSTEM,
963 .max_ll_items = OTP_MAX_LL_ITEMS_6x50,
964 .shadow_ram_support = true,
965 .ht_greenfield_support = true,
966 .led_compensation = 51,
967 .use_rts_for_aggregation = true, /* use rts/cts protection */
968 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
969 .supports_idle = true,
970 .adv_thermal_throttle = true,
971 .support_ct_kill_exit = true,
972 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
973 .chain_noise_scale = 1500,
974 .monitor_recover_period = IWL_DEF_MONITORING_PERIOD,
975 .max_event_log_size = 1024,
976 .ucode_tracing = true,
977 .sensitivity_calib_by_driver = true,
978 .chain_noise_calib_by_driver = true,
979 .need_dc_calib = true, 782 .need_dc_calib = true,
980}; 783};
981 784
@@ -985,33 +788,13 @@ struct iwl_cfg iwl6050_2abg_cfg = {
985 .ucode_api_max = IWL6050_UCODE_API_MAX, 788 .ucode_api_max = IWL6050_UCODE_API_MAX,
986 .ucode_api_min = IWL6050_UCODE_API_MIN, 789 .ucode_api_min = IWL6050_UCODE_API_MIN,
987 .sku = IWL_SKU_A|IWL_SKU_G, 790 .sku = IWL_SKU_A|IWL_SKU_G,
988 .ops = &iwl6000_ops, 791 .valid_tx_ant = ANT_AB,
989 .eeprom_size = OTP_LOW_IMAGE_SIZE, 792 .valid_rx_ant = ANT_AB,
990 .eeprom_ver = EEPROM_6050_EEPROM_VERSION, 793 .eeprom_ver = EEPROM_6050_EEPROM_VERSION,
991 .eeprom_calib_ver = EEPROM_6050_TX_POWER_VERSION, 794 .eeprom_calib_ver = EEPROM_6050_TX_POWER_VERSION,
992 .num_of_queues = IWLAGN_NUM_QUEUES, 795 .ops = &iwl6050_ops,
993 .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
994 .mod_params = &iwlagn_mod_params, 796 .mod_params = &iwlagn_mod_params,
995 .valid_tx_ant = ANT_AB, 797 .base_params = &iwl6050_base_params,
996 .valid_rx_ant = ANT_AB,
997 .pll_cfg_val = 0,
998 .set_l0s = true,
999 .use_bsm = false,
1000 .pa_type = IWL_PA_SYSTEM,
1001 .max_ll_items = OTP_MAX_LL_ITEMS_6x50,
1002 .shadow_ram_support = true,
1003 .led_compensation = 51,
1004 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
1005 .supports_idle = true,
1006 .adv_thermal_throttle = true,
1007 .support_ct_kill_exit = true,
1008 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
1009 .chain_noise_scale = 1500,
1010 .monitor_recover_period = IWL_DEF_MONITORING_PERIOD,
1011 .max_event_log_size = 1024,
1012 .ucode_tracing = true,
1013 .sensitivity_calib_by_driver = true,
1014 .chain_noise_calib_by_driver = true,
1015 .need_dc_calib = true, 798 .need_dc_calib = true,
1016}; 799};
1017 800
@@ -1021,38 +804,58 @@ struct iwl_cfg iwl6000_3agn_cfg = {
1021 .ucode_api_max = IWL6000_UCODE_API_MAX, 804 .ucode_api_max = IWL6000_UCODE_API_MAX,
1022 .ucode_api_min = IWL6000_UCODE_API_MIN, 805 .ucode_api_min = IWL6000_UCODE_API_MIN,
1023 .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N, 806 .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
1024 .ops = &iwl6000_ops, 807 .valid_tx_ant = ANT_ABC,
1025 .eeprom_size = OTP_LOW_IMAGE_SIZE, 808 .valid_rx_ant = ANT_ABC,
1026 .eeprom_ver = EEPROM_6000_EEPROM_VERSION, 809 .eeprom_ver = EEPROM_6000_EEPROM_VERSION,
1027 .eeprom_calib_ver = EEPROM_6000_TX_POWER_VERSION, 810 .eeprom_calib_ver = EEPROM_6000_TX_POWER_VERSION,
1028 .num_of_queues = IWLAGN_NUM_QUEUES, 811 .ops = &iwl6000_ops,
1029 .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
1030 .mod_params = &iwlagn_mod_params, 812 .mod_params = &iwlagn_mod_params,
1031 .valid_tx_ant = ANT_ABC, 813 .base_params = &iwl6000_base_params,
1032 .valid_rx_ant = ANT_ABC, 814 .ht_params = &iwl6000_ht_params,
1033 .pll_cfg_val = 0, 815 .need_dc_calib = true,
1034 .set_l0s = true, 816};
1035 .use_bsm = false, 817
1036 .pa_type = IWL_PA_SYSTEM, 818struct iwl_cfg iwl130_bgn_cfg = {
1037 .max_ll_items = OTP_MAX_LL_ITEMS_6x00, 819 .name = "Intel(R) 130 Series 1x1 BGN",
1038 .shadow_ram_support = true, 820 .fw_name_pre = IWL6000G2B_FW_PRE,
1039 .ht_greenfield_support = true, 821 .ucode_api_max = IWL130_UCODE_API_MAX,
1040 .led_compensation = 51, 822 .ucode_api_min = IWL130_UCODE_API_MIN,
1041 .use_rts_for_aggregation = true, /* use rts/cts protection */ 823 .sku = IWL_SKU_G|IWL_SKU_N,
1042 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, 824 .valid_tx_ant = ANT_A,
1043 .supports_idle = true, 825 .valid_rx_ant = ANT_A,
1044 .adv_thermal_throttle = true, 826 .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION,
1045 .support_ct_kill_exit = true, 827 .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION,
1046 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, 828 .ops = &iwl6000g2b_ops,
1047 .chain_noise_scale = 1000, 829 .mod_params = &iwlagn_mod_params,
1048 .monitor_recover_period = IWL_DEF_MONITORING_PERIOD, 830 .base_params = &iwl6000_base_params,
1049 .max_event_log_size = 1024, 831 .bt_params = &iwl6000_bt_params,
1050 .ucode_tracing = true, 832 .ht_params = &iwl6000_ht_params,
1051 .sensitivity_calib_by_driver = true, 833 .need_dc_calib = true,
1052 .chain_noise_calib_by_driver = true, 834 /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */
835 .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A,
836};
837
838struct iwl_cfg iwl130_bg_cfg = {
839 .name = "Intel(R) 130 Series 1x2 BG",
840 .fw_name_pre = IWL6000G2B_FW_PRE,
841 .ucode_api_max = IWL130_UCODE_API_MAX,
842 .ucode_api_min = IWL130_UCODE_API_MIN,
843 .sku = IWL_SKU_G,
844 .valid_tx_ant = ANT_A,
845 .valid_rx_ant = ANT_A,
846 .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION,
847 .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION,
848 .ops = &iwl6000g2b_ops,
849 .mod_params = &iwlagn_mod_params,
850 .base_params = &iwl6000_base_params,
851 .bt_params = &iwl6000_bt_params,
852 .need_dc_calib = true,
853 /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */
854 .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A,
1053}; 855};
1054 856
1055MODULE_FIRMWARE(IWL6000_MODULE_FIRMWARE(IWL6000_UCODE_API_MAX)); 857MODULE_FIRMWARE(IWL6000_MODULE_FIRMWARE(IWL6000_UCODE_API_MAX));
1056MODULE_FIRMWARE(IWL6050_MODULE_FIRMWARE(IWL6050_UCODE_API_MAX)); 858MODULE_FIRMWARE(IWL6050_MODULE_FIRMWARE(IWL6050_UCODE_API_MAX));
1057MODULE_FIRMWARE(IWL6000G2A_MODULE_FIRMWARE(IWL6000G2_UCODE_API_MAX)); 859MODULE_FIRMWARE(IWL6000G2A_MODULE_FIRMWARE(IWL6000G2_UCODE_API_MAX));
1058MODULE_FIRMWARE(IWL6000G2B_MODULE_FIRMWARE(IWL6000G2_UCODE_API_MAX)); 860MODULE_FIRMWARE(IWL6000G2B_MODULE_FIRMWARE(IWL6000G2_UCODE_API_MAX));
861MODULE_FIRMWARE(IWL130_MODULE_FIRMWARE(IWL130_UCODE_API_MAX));
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-calib.c b/drivers/net/wireless/iwlwifi/iwl-agn-calib.c
index 84ad6295853..4c5ab783737 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-calib.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-calib.c
@@ -631,7 +631,8 @@ void iwl_sensitivity_calibration(struct iwl_priv *priv, void *resp)
631 } 631 }
632 632
633 spin_lock_irqsave(&priv->lock, flags); 633 spin_lock_irqsave(&priv->lock, flags);
634 if (priv->cfg->bt_statistics) { 634 if (priv->cfg->bt_params &&
635 priv->cfg->bt_params->bt_statistics) {
635 rx_info = &(((struct iwl_bt_notif_statistics *)resp)-> 636 rx_info = &(((struct iwl_bt_notif_statistics *)resp)->
636 rx.general.common); 637 rx.general.common);
637 ofdm = &(((struct iwl_bt_notif_statistics *)resp)->rx.ofdm); 638 ofdm = &(((struct iwl_bt_notif_statistics *)resp)->rx.ofdm);
@@ -786,7 +787,8 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv, void *stat_resp)
786 } 787 }
787 788
788 spin_lock_irqsave(&priv->lock, flags); 789 spin_lock_irqsave(&priv->lock, flags);
789 if (priv->cfg->bt_statistics) { 790 if (priv->cfg->bt_params &&
791 priv->cfg->bt_params->bt_statistics) {
790 rx_info = &(((struct iwl_bt_notif_statistics *)stat_resp)-> 792 rx_info = &(((struct iwl_bt_notif_statistics *)stat_resp)->
791 rx.general.common); 793 rx.general.common);
792 } else { 794 } else {
@@ -801,7 +803,8 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv, void *stat_resp)
801 803
802 rxon_band24 = !!(ctx->staging.flags & RXON_FLG_BAND_24G_MSK); 804 rxon_band24 = !!(ctx->staging.flags & RXON_FLG_BAND_24G_MSK);
803 rxon_chnum = le16_to_cpu(ctx->staging.channel); 805 rxon_chnum = le16_to_cpu(ctx->staging.channel);
804 if (priv->cfg->bt_statistics) { 806 if (priv->cfg->bt_params &&
807 priv->cfg->bt_params->bt_statistics) {
805 stat_band24 = !!(((struct iwl_bt_notif_statistics *) 808 stat_band24 = !!(((struct iwl_bt_notif_statistics *)
806 stat_resp)->flag & 809 stat_resp)->flag &
807 STATISTICS_REPLY_FLG_BAND_24G_MSK); 810 STATISTICS_REPLY_FLG_BAND_24G_MSK);
@@ -861,16 +864,17 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv, void *stat_resp)
861 /* If this is the "chain_noise_num_beacons", determine: 864 /* If this is the "chain_noise_num_beacons", determine:
862 * 1) Disconnected antennas (using signal strengths) 865 * 1) Disconnected antennas (using signal strengths)
863 * 2) Differential gain (using silence noise) to balance receivers */ 866 * 2) Differential gain (using silence noise) to balance receivers */
864 if (data->beacon_count != priv->cfg->chain_noise_num_beacons) 867 if (data->beacon_count !=
868 priv->cfg->base_params->chain_noise_num_beacons)
865 return; 869 return;
866 870
867 /* Analyze signal for disconnected antenna */ 871 /* Analyze signal for disconnected antenna */
868 average_sig[0] = 872 average_sig[0] = data->chain_signal_a /
869 (data->chain_signal_a) / priv->cfg->chain_noise_num_beacons; 873 priv->cfg->base_params->chain_noise_num_beacons;
870 average_sig[1] = 874 average_sig[1] = data->chain_signal_b /
871 (data->chain_signal_b) / priv->cfg->chain_noise_num_beacons; 875 priv->cfg->base_params->chain_noise_num_beacons;
872 average_sig[2] = 876 average_sig[2] = data->chain_signal_c /
873 (data->chain_signal_c) / priv->cfg->chain_noise_num_beacons; 877 priv->cfg->base_params->chain_noise_num_beacons;
874 878
875 if (average_sig[0] >= average_sig[1]) { 879 if (average_sig[0] >= average_sig[1]) {
876 max_average_sig = average_sig[0]; 880 max_average_sig = average_sig[0];
@@ -920,7 +924,9 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv, void *stat_resp)
920 * To be safe, simply mask out any chains that we know 924 * To be safe, simply mask out any chains that we know
921 * are not on the device. 925 * are not on the device.
922 */ 926 */
923 if (priv->cfg->advanced_bt_coexist && priv->bt_full_concurrent) { 927 if (priv->cfg->bt_params &&
928 priv->cfg->bt_params->advanced_bt_coexist &&
929 priv->bt_full_concurrent) {
924 /* operated as 1x1 in full concurrency mode */ 930 /* operated as 1x1 in full concurrency mode */
925 active_chains &= first_antenna(priv->hw_params.valid_rx_ant); 931 active_chains &= first_antenna(priv->hw_params.valid_rx_ant);
926 } else 932 } else
@@ -967,12 +973,12 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv, void *stat_resp)
967 active_chains); 973 active_chains);
968 974
969 /* Analyze noise for rx balance */ 975 /* Analyze noise for rx balance */
970 average_noise[0] = 976 average_noise[0] = data->chain_noise_a /
971 ((data->chain_noise_a) / priv->cfg->chain_noise_num_beacons); 977 priv->cfg->base_params->chain_noise_num_beacons;
972 average_noise[1] = 978 average_noise[1] = data->chain_noise_b /
973 ((data->chain_noise_b) / priv->cfg->chain_noise_num_beacons); 979 priv->cfg->base_params->chain_noise_num_beacons;
974 average_noise[2] = 980 average_noise[2] = data->chain_noise_c /
975 ((data->chain_noise_c) / priv->cfg->chain_noise_num_beacons); 981 priv->cfg->base_params->chain_noise_num_beacons;
976 982
977 for (i = 0; i < NUM_RX_CHAINS; i++) { 983 for (i = 0; i < NUM_RX_CHAINS; i++) {
978 if (!(data->disconn_array[i]) && 984 if (!(data->disconn_array[i]) &&
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c
index 5391b462739..a358d4334a1 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c
@@ -39,7 +39,8 @@ static int iwl_statistics_flag(struct iwl_priv *priv, char *buf, int bufsz)
39 int p = 0; 39 int p = 0;
40 u32 flag; 40 u32 flag;
41 41
42 if (priv->cfg->bt_statistics) 42 if (priv->cfg->bt_params &&
43 priv->cfg->bt_params->bt_statistics)
43 flag = le32_to_cpu(priv->_agn.statistics_bt.flag); 44 flag = le32_to_cpu(priv->_agn.statistics_bt.flag);
44 else 45 else
45 flag = le32_to_cpu(priv->_agn.statistics.flag); 46 flag = le32_to_cpu(priv->_agn.statistics.flag);
@@ -88,7 +89,8 @@ ssize_t iwl_ucode_rx_stats_read(struct file *file, char __user *user_buf,
88 * the last statistics notification from uCode 89 * the last statistics notification from uCode
89 * might not reflect the current uCode activity 90 * might not reflect the current uCode activity
90 */ 91 */
91 if (priv->cfg->bt_statistics) { 92 if (priv->cfg->bt_params &&
93 priv->cfg->bt_params->bt_statistics) {
92 ofdm = &priv->_agn.statistics_bt.rx.ofdm; 94 ofdm = &priv->_agn.statistics_bt.rx.ofdm;
93 cck = &priv->_agn.statistics_bt.rx.cck; 95 cck = &priv->_agn.statistics_bt.rx.cck;
94 general = &priv->_agn.statistics_bt.rx.general.common; 96 general = &priv->_agn.statistics_bt.rx.general.common;
@@ -534,7 +536,8 @@ ssize_t iwl_ucode_tx_stats_read(struct file *file,
534 * the last statistics notification from uCode 536 * the last statistics notification from uCode
535 * might not reflect the current uCode activity 537 * might not reflect the current uCode activity
536 */ 538 */
537 if (priv->cfg->bt_statistics) { 539 if (priv->cfg->bt_params &&
540 priv->cfg->bt_params->bt_statistics) {
538 tx = &priv->_agn.statistics_bt.tx; 541 tx = &priv->_agn.statistics_bt.tx;
539 accum_tx = &priv->_agn.accum_statistics_bt.tx; 542 accum_tx = &priv->_agn.accum_statistics_bt.tx;
540 delta_tx = &priv->_agn.delta_statistics_bt.tx; 543 delta_tx = &priv->_agn.delta_statistics_bt.tx;
@@ -734,7 +737,8 @@ ssize_t iwl_ucode_general_stats_read(struct file *file, char __user *user_buf,
734 * the last statistics notification from uCode 737 * the last statistics notification from uCode
735 * might not reflect the current uCode activity 738 * might not reflect the current uCode activity
736 */ 739 */
737 if (priv->cfg->bt_statistics) { 740 if (priv->cfg->bt_params &&
741 priv->cfg->bt_params->bt_statistics) {
738 general = &priv->_agn.statistics_bt.general.common; 742 general = &priv->_agn.statistics_bt.general.common;
739 dbg = &priv->_agn.statistics_bt.general.common.dbg; 743 dbg = &priv->_agn.statistics_bt.general.common.dbg;
740 div = &priv->_agn.statistics_bt.general.common.div; 744 div = &priv->_agn.statistics_bt.general.common.div;
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c b/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c
index d86902b8363..9ca6c91eaae 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c
@@ -137,7 +137,7 @@ static void iwlagn_gain_computation(struct iwl_priv *priv,
137 continue; 137 continue;
138 } 138 }
139 139
140 delta_g = (priv->cfg->chain_noise_scale * 140 delta_g = (priv->cfg->base_params->chain_noise_scale *
141 ((s32)average_noise[default_chain] - 141 ((s32)average_noise[default_chain] -
142 (s32)average_noise[i])) / 1500; 142 (s32)average_noise[i])) / 1500;
143 143
@@ -222,7 +222,8 @@ static void iwlagn_tx_cmd_protection(struct iwl_priv *priv,
222 return; 222 return;
223 } 223 }
224 224
225 if (priv->cfg->use_rts_for_aggregation && 225 if (priv->cfg->ht_params &&
226 priv->cfg->ht_params->use_rts_for_aggregation &&
226 info->flags & IEEE80211_TX_CTL_AMPDU) { 227 info->flags & IEEE80211_TX_CTL_AMPDU) {
227 *tx_flags |= TX_CMD_FLG_PROT_REQUIRE_MSK; 228 *tx_flags |= TX_CMD_FLG_PROT_REQUIRE_MSK;
228 return; 229 return;
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-ict.c b/drivers/net/wireless/iwlwifi/iwl-agn-ict.c
index c92b2c0cbd9..a5dbfea1bfa 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-ict.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-ict.c
@@ -59,7 +59,7 @@ void iwl_free_isr_ict(struct iwl_priv *priv)
59int iwl_alloc_isr_ict(struct iwl_priv *priv) 59int iwl_alloc_isr_ict(struct iwl_priv *priv)
60{ 60{
61 61
62 if (priv->cfg->use_isr_legacy) 62 if (priv->cfg->base_params->use_isr_legacy)
63 return 0; 63 return 0;
64 /* allocate shrared data table */ 64 /* allocate shrared data table */
65 priv->_agn.ict_tbl_vir = 65 priv->_agn.ict_tbl_vir =
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
index 299fd9d5960..f5445d575fe 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
@@ -40,7 +40,7 @@
40#include "iwl-agn.h" 40#include "iwl-agn.h"
41#include "iwl-sta.h" 41#include "iwl-sta.h"
42 42
43static inline u32 iwlagn_get_scd_ssn(struct iwl5000_tx_resp *tx_resp) 43static inline u32 iwlagn_get_scd_ssn(struct iwlagn_tx_resp *tx_resp)
44{ 44{
45 return le32_to_cpup((__le32 *)&tx_resp->status + 45 return le32_to_cpup((__le32 *)&tx_resp->status +
46 tx_resp->frame_count) & MAX_SN; 46 tx_resp->frame_count) & MAX_SN;
@@ -172,7 +172,7 @@ static void iwlagn_count_agg_tx_err_status(struct iwl_priv *priv, u16 status)
172 172
173static void iwlagn_set_tx_status(struct iwl_priv *priv, 173static void iwlagn_set_tx_status(struct iwl_priv *priv,
174 struct ieee80211_tx_info *info, 174 struct ieee80211_tx_info *info,
175 struct iwl5000_tx_resp *tx_resp, 175 struct iwlagn_tx_resp *tx_resp,
176 int txq_id, bool is_agg) 176 int txq_id, bool is_agg)
177{ 177{
178 u16 status = le16_to_cpu(tx_resp->status.status); 178 u16 status = le16_to_cpu(tx_resp->status.status);
@@ -223,7 +223,7 @@ const char *iwl_get_agg_tx_fail_reason(u16 status)
223 223
224static int iwlagn_tx_status_reply_tx(struct iwl_priv *priv, 224static int iwlagn_tx_status_reply_tx(struct iwl_priv *priv,
225 struct iwl_ht_agg *agg, 225 struct iwl_ht_agg *agg,
226 struct iwl5000_tx_resp *tx_resp, 226 struct iwlagn_tx_resp *tx_resp,
227 int txq_id, u16 start_idx) 227 int txq_id, u16 start_idx)
228{ 228{
229 u16 status; 229 u16 status;
@@ -390,7 +390,7 @@ static void iwlagn_rx_reply_tx(struct iwl_priv *priv,
390 int index = SEQ_TO_INDEX(sequence); 390 int index = SEQ_TO_INDEX(sequence);
391 struct iwl_tx_queue *txq = &priv->txq[txq_id]; 391 struct iwl_tx_queue *txq = &priv->txq[txq_id];
392 struct ieee80211_tx_info *info; 392 struct ieee80211_tx_info *info;
393 struct iwl5000_tx_resp *tx_resp = (void *)&pkt->u.raw[0]; 393 struct iwlagn_tx_resp *tx_resp = (void *)&pkt->u.raw[0];
394 u32 status = le16_to_cpu(tx_resp->status.status); 394 u32 status = le16_to_cpu(tx_resp->status.status);
395 int tid; 395 int tid;
396 int sta_id; 396 int sta_id;
@@ -408,8 +408,10 @@ static void iwlagn_rx_reply_tx(struct iwl_priv *priv,
408 info = IEEE80211_SKB_CB(txq->txb[txq->q.read_ptr].skb); 408 info = IEEE80211_SKB_CB(txq->txb[txq->q.read_ptr].skb);
409 memset(&info->status, 0, sizeof(info->status)); 409 memset(&info->status, 0, sizeof(info->status));
410 410
411 tid = (tx_resp->ra_tid & IWL50_TX_RES_TID_MSK) >> IWL50_TX_RES_TID_POS; 411 tid = (tx_resp->ra_tid & IWLAGN_TX_RES_TID_MSK) >>
412 sta_id = (tx_resp->ra_tid & IWL50_TX_RES_RA_MSK) >> IWL50_TX_RES_RA_POS; 412 IWLAGN_TX_RES_TID_POS;
413 sta_id = (tx_resp->ra_tid & IWLAGN_TX_RES_RA_MSK) >>
414 IWLAGN_TX_RES_RA_POS;
413 415
414 spin_lock_irqsave(&priv->sta_lock, flags); 416 spin_lock_irqsave(&priv->sta_lock, flags);
415 if (txq->sched_retry) { 417 if (txq->sched_retry) {
@@ -422,7 +424,8 @@ static void iwlagn_rx_reply_tx(struct iwl_priv *priv,
422 * notification again. 424 * notification again.
423 */ 425 */
424 if (tx_resp->bt_kill_count && tx_resp->frame_count == 1 && 426 if (tx_resp->bt_kill_count && tx_resp->frame_count == 1 &&
425 priv->cfg->advanced_bt_coexist) { 427 priv->cfg->bt_params &&
428 priv->cfg->bt_params->advanced_bt_coexist) {
426 IWL_WARN(priv, "receive reply tx with bt_kill\n"); 429 IWL_WARN(priv, "receive reply tx with bt_kill\n");
427 } 430 }
428 iwlagn_tx_status_reply_tx(priv, agg, tx_resp, txq_id, index); 431 iwlagn_tx_status_reply_tx(priv, agg, tx_resp, txq_id, index);
@@ -490,7 +493,7 @@ int iwlagn_hw_valid_rtc_data_addr(u32 addr)
490 493
491int iwlagn_send_tx_power(struct iwl_priv *priv) 494int iwlagn_send_tx_power(struct iwl_priv *priv)
492{ 495{
493 struct iwl5000_tx_power_dbm_cmd tx_power_cmd; 496 struct iwlagn_tx_power_dbm_cmd tx_power_cmd;
494 u8 tx_ant_cfg_cmd; 497 u8 tx_ant_cfg_cmd;
495 498
496 /* half dBm need to multiply */ 499 /* half dBm need to multiply */
@@ -511,8 +514,8 @@ int iwlagn_send_tx_power(struct iwl_priv *priv)
511 */ 514 */
512 tx_power_cmd.global_lmt = priv->tx_power_lmt_in_half_dbm; 515 tx_power_cmd.global_lmt = priv->tx_power_lmt_in_half_dbm;
513 } 516 }
514 tx_power_cmd.flags = IWL50_TX_POWER_NO_CLOSED; 517 tx_power_cmd.flags = IWLAGN_TX_POWER_NO_CLOSED;
515 tx_power_cmd.srv_chan_lmt = IWL50_TX_POWER_AUTO; 518 tx_power_cmd.srv_chan_lmt = IWLAGN_TX_POWER_AUTO;
516 519
517 if (IWL_UCODE_API(priv->ucode_ver) == 1) 520 if (IWL_UCODE_API(priv->ucode_ver) == 1)
518 tx_ant_cfg_cmd = REPLY_TX_POWER_DBM_CMD_V1; 521 tx_ant_cfg_cmd = REPLY_TX_POWER_DBM_CMD_V1;
@@ -589,7 +592,7 @@ const u8 *iwlagn_eeprom_query_addr(const struct iwl_priv *priv,
589 size_t offset) 592 size_t offset)
590{ 593{
591 u32 address = eeprom_indirect_address(priv, offset); 594 u32 address = eeprom_indirect_address(priv, offset);
592 BUG_ON(address >= priv->cfg->eeprom_size); 595 BUG_ON(address >= priv->cfg->base_params->eeprom_size);
593 return &priv->eeprom[address]; 596 return &priv->eeprom[address];
594} 597}
595 598
@@ -637,7 +640,7 @@ int iwlagn_rx_init(struct iwl_priv *priv, struct iwl_rx_queue *rxq)
637 const u32 rfdnlog = RX_QUEUE_SIZE_LOG; /* 256 RBDs */ 640 const u32 rfdnlog = RX_QUEUE_SIZE_LOG; /* 256 RBDs */
638 u32 rb_timeout = 0; /* FIXME: RX_RB_TIMEOUT for all devices? */ 641 u32 rb_timeout = 0; /* FIXME: RX_RB_TIMEOUT for all devices? */
639 642
640 if (!priv->cfg->use_isr_legacy) 643 if (!priv->cfg->base_params->use_isr_legacy)
641 rb_timeout = RX_RB_TIMEOUT; 644 rb_timeout = RX_RB_TIMEOUT;
642 645
643 if (priv->cfg->mod_params->amsdu_size_8K) 646 if (priv->cfg->mod_params->amsdu_size_8K)
@@ -1424,7 +1427,8 @@ int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
1424 * Internal scans are passive, so we can indiscriminately set 1427 * Internal scans are passive, so we can indiscriminately set
1425 * the BT ignore flag on 2.4 GHz since it applies to TX only. 1428 * the BT ignore flag on 2.4 GHz since it applies to TX only.
1426 */ 1429 */
1427 if (priv->cfg->advanced_bt_coexist) 1430 if (priv->cfg->bt_params &&
1431 priv->cfg->bt_params->advanced_bt_coexist)
1428 scan->tx_cmd.tx_flags |= TX_CMD_FLG_IGNORE_BT; 1432 scan->tx_cmd.tx_flags |= TX_CMD_FLG_IGNORE_BT;
1429 scan->good_CRC_th = IWL_GOOD_CRC_TH_DISABLED; 1433 scan->good_CRC_th = IWL_GOOD_CRC_TH_DISABLED;
1430 break; 1434 break;
@@ -1463,10 +1467,12 @@ int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
1463 if (priv->cfg->scan_tx_antennas[band]) 1467 if (priv->cfg->scan_tx_antennas[band])
1464 scan_tx_antennas = priv->cfg->scan_tx_antennas[band]; 1468 scan_tx_antennas = priv->cfg->scan_tx_antennas[band];
1465 1469
1466 if (priv->cfg->advanced_bt_coexist && priv->bt_full_concurrent) { 1470 if (priv->cfg->bt_params &&
1471 priv->cfg->bt_params->advanced_bt_coexist &&
1472 priv->bt_full_concurrent) {
1467 /* operated as 1x1 in full concurrency mode */ 1473 /* operated as 1x1 in full concurrency mode */
1468 scan_tx_antennas = 1474 scan_tx_antennas = first_antenna(
1469 first_antenna(priv->cfg->scan_tx_antennas[band]); 1475 priv->cfg->scan_tx_antennas[band]);
1470 } 1476 }
1471 1477
1472 priv->scan_tx_ant[band] = iwl_toggle_tx_ant(priv, priv->scan_tx_ant[band], 1478 priv->scan_tx_ant[band] = iwl_toggle_tx_ant(priv, priv->scan_tx_ant[band],
@@ -1487,7 +1493,9 @@ int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
1487 1493
1488 rx_ant = first_antenna(active_chains); 1494 rx_ant = first_antenna(active_chains);
1489 } 1495 }
1490 if (priv->cfg->advanced_bt_coexist && priv->bt_full_concurrent) { 1496 if (priv->cfg->bt_params &&
1497 priv->cfg->bt_params->advanced_bt_coexist &&
1498 priv->bt_full_concurrent) {
1491 /* operated as 1x1 in full concurrency mode */ 1499 /* operated as 1x1 in full concurrency mode */
1492 rx_ant = first_antenna(rx_ant); 1500 rx_ant = first_antenna(rx_ant);
1493 } 1501 }
@@ -1777,7 +1785,10 @@ void iwlagn_send_advance_bt_config(struct iwl_priv *priv)
1777 BUILD_BUG_ON(sizeof(iwlagn_def_3w_lookup) != 1785 BUILD_BUG_ON(sizeof(iwlagn_def_3w_lookup) !=
1778 sizeof(bt_cmd.bt3_lookup_table)); 1786 sizeof(bt_cmd.bt3_lookup_table));
1779 1787
1780 bt_cmd.prio_boost = priv->cfg->bt_prio_boost; 1788 if (priv->cfg->bt_params)
1789 bt_cmd.prio_boost = priv->cfg->bt_params->bt_prio_boost;
1790 else
1791 bt_cmd.prio_boost = 0;
1781 bt_cmd.kill_ack_mask = priv->kill_ack_mask; 1792 bt_cmd.kill_ack_mask = priv->kill_ack_mask;
1782 bt_cmd.kill_cts_mask = priv->kill_cts_mask; 1793 bt_cmd.kill_cts_mask = priv->kill_cts_mask;
1783 bt_cmd.valid = priv->bt_valid; 1794 bt_cmd.valid = priv->bt_valid;
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
index 57629fba3a7..f865685fd5f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
@@ -2939,11 +2939,14 @@ static void rs_fill_link_cmd(struct iwl_priv *priv,
2939 * overwrite if needed, pass aggregation time limit 2939 * overwrite if needed, pass aggregation time limit
2940 * to uCode in uSec 2940 * to uCode in uSec
2941 */ 2941 */
2942 if (priv && priv->cfg->agg_time_limit && 2942 if (priv && priv->cfg->bt_params &&
2943 priv->cfg->agg_time_limit >= LINK_QUAL_AGG_TIME_LIMIT_MIN && 2943 priv->cfg->bt_params->agg_time_limit &&
2944 priv->cfg->agg_time_limit <= LINK_QUAL_AGG_TIME_LIMIT_MAX) 2944 priv->cfg->bt_params->agg_time_limit >=
2945 LINK_QUAL_AGG_TIME_LIMIT_MIN &&
2946 priv->cfg->bt_params->agg_time_limit <=
2947 LINK_QUAL_AGG_TIME_LIMIT_MAX)
2945 lq_cmd->agg_params.agg_time_limit = 2948 lq_cmd->agg_params.agg_time_limit =
2946 cpu_to_le16(priv->cfg->agg_time_limit); 2949 cpu_to_le16(priv->cfg->bt_params->agg_time_limit);
2947} 2950}
2948 2951
2949static void *rs_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir) 2952static void *rs_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir)
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rx.c b/drivers/net/wireless/iwlwifi/iwl-agn-rx.c
index 9490eced119..1e08eb45547 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-rx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rx.c
@@ -73,7 +73,8 @@ static void iwl_rx_calc_noise(struct iwl_priv *priv)
73 int bcn_silence_a, bcn_silence_b, bcn_silence_c; 73 int bcn_silence_a, bcn_silence_b, bcn_silence_c;
74 int last_rx_noise; 74 int last_rx_noise;
75 75
76 if (priv->cfg->bt_statistics) 76 if (priv->cfg->bt_params &&
77 priv->cfg->bt_params->bt_statistics)
77 rx_info = &(priv->_agn.statistics_bt.rx.general.common); 78 rx_info = &(priv->_agn.statistics_bt.rx.general.common);
78 else 79 else
79 rx_info = &(priv->_agn.statistics.rx.general); 80 rx_info = &(priv->_agn.statistics.rx.general);
@@ -124,7 +125,8 @@ static void iwl_accumulative_statistics(struct iwl_priv *priv,
124 struct statistics_general_common *general, *accum_general; 125 struct statistics_general_common *general, *accum_general;
125 struct statistics_tx *tx, *accum_tx; 126 struct statistics_tx *tx, *accum_tx;
126 127
127 if (priv->cfg->bt_statistics) { 128 if (priv->cfg->bt_params &&
129 priv->cfg->bt_params->bt_statistics) {
128 prev_stats = (__le32 *)&priv->_agn.statistics_bt; 130 prev_stats = (__le32 *)&priv->_agn.statistics_bt;
129 accum_stats = (u32 *)&priv->_agn.accum_statistics_bt; 131 accum_stats = (u32 *)&priv->_agn.accum_statistics_bt;
130 size = sizeof(struct iwl_bt_notif_statistics); 132 size = sizeof(struct iwl_bt_notif_statistics);
@@ -183,7 +185,7 @@ bool iwl_good_plcp_health(struct iwl_priv *priv,
183 unsigned int plcp_msec; 185 unsigned int plcp_msec;
184 unsigned long plcp_received_jiffies; 186 unsigned long plcp_received_jiffies;
185 187
186 if (priv->cfg->plcp_delta_threshold == 188 if (priv->cfg->base_params->plcp_delta_threshold ==
187 IWL_MAX_PLCP_ERR_THRESHOLD_DISABLE) { 189 IWL_MAX_PLCP_ERR_THRESHOLD_DISABLE) {
188 IWL_DEBUG_RADIO(priv, "plcp_err check disabled\n"); 190 IWL_DEBUG_RADIO(priv, "plcp_err check disabled\n");
189 return rc; 191 return rc;
@@ -205,7 +207,8 @@ bool iwl_good_plcp_health(struct iwl_priv *priv,
205 struct statistics_rx_phy *ofdm; 207 struct statistics_rx_phy *ofdm;
206 struct statistics_rx_ht_phy *ofdm_ht; 208 struct statistics_rx_ht_phy *ofdm_ht;
207 209
208 if (priv->cfg->bt_statistics) { 210 if (priv->cfg->bt_params &&
211 priv->cfg->bt_params->bt_statistics) {
209 ofdm = &pkt->u.stats_bt.rx.ofdm; 212 ofdm = &pkt->u.stats_bt.rx.ofdm;
210 ofdm_ht = &pkt->u.stats_bt.rx.ofdm_ht; 213 ofdm_ht = &pkt->u.stats_bt.rx.ofdm_ht;
211 combined_plcp_delta = 214 combined_plcp_delta =
@@ -229,7 +232,7 @@ bool iwl_good_plcp_health(struct iwl_priv *priv,
229 232
230 if ((combined_plcp_delta > 0) && 233 if ((combined_plcp_delta > 0) &&
231 ((combined_plcp_delta * 100) / plcp_msec) > 234 ((combined_plcp_delta * 100) / plcp_msec) >
232 priv->cfg->plcp_delta_threshold) { 235 priv->cfg->base_params->plcp_delta_threshold) {
233 /* 236 /*
234 * if plcp_err exceed the threshold, 237 * if plcp_err exceed the threshold,
235 * the following data is printed in csv format: 238 * the following data is printed in csv format:
@@ -242,13 +245,13 @@ bool iwl_good_plcp_health(struct iwl_priv *priv,
242 * plcp_msec 245 * plcp_msec
243 */ 246 */
244 IWL_DEBUG_RADIO(priv, "plcp_err exceeded %u, " 247 IWL_DEBUG_RADIO(priv, "plcp_err exceeded %u, "
245 "%u, %u, %u, %u, %d, %u mSecs\n", 248 "%u, %u, %u, %u, %d, %u mSecs\n",
246 priv->cfg->plcp_delta_threshold, 249 priv->cfg->base_params->plcp_delta_threshold,
247 le32_to_cpu(ofdm->plcp_err), 250 le32_to_cpu(ofdm->plcp_err),
248 le32_to_cpu(ofdm->plcp_err), 251 le32_to_cpu(ofdm->plcp_err),
249 le32_to_cpu(ofdm_ht->plcp_err), 252 le32_to_cpu(ofdm_ht->plcp_err),
250 le32_to_cpu(ofdm_ht->plcp_err), 253 le32_to_cpu(ofdm_ht->plcp_err),
251 combined_plcp_delta, plcp_msec); 254 combined_plcp_delta, plcp_msec);
252 255
253 rc = false; 256 rc = false;
254 } 257 }
@@ -262,7 +265,8 @@ void iwl_rx_statistics(struct iwl_priv *priv,
262 int change; 265 int change;
263 struct iwl_rx_packet *pkt = rxb_addr(rxb); 266 struct iwl_rx_packet *pkt = rxb_addr(rxb);
264 267
265 if (priv->cfg->bt_statistics) { 268 if (priv->cfg->bt_params &&
269 priv->cfg->bt_params->bt_statistics) {
266 IWL_DEBUG_RX(priv, 270 IWL_DEBUG_RX(priv,
267 "Statistics notification received (%d vs %d).\n", 271 "Statistics notification received (%d vs %d).\n",
268 (int)sizeof(struct iwl_bt_notif_statistics), 272 (int)sizeof(struct iwl_bt_notif_statistics),
@@ -300,7 +304,8 @@ void iwl_rx_statistics(struct iwl_priv *priv,
300 304
301 iwl_recover_from_statistics(priv, pkt); 305 iwl_recover_from_statistics(priv, pkt);
302 306
303 if (priv->cfg->bt_statistics) 307 if (priv->cfg->bt_params &&
308 priv->cfg->bt_params->bt_statistics)
304 memcpy(&priv->_agn.statistics_bt, &pkt->u.stats_bt, 309 memcpy(&priv->_agn.statistics_bt, &pkt->u.stats_bt,
305 sizeof(priv->_agn.statistics_bt)); 310 sizeof(priv->_agn.statistics_bt));
306 else 311 else
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tt.c b/drivers/net/wireless/iwlwifi/iwl-agn-tt.c
index 07b2c6cadf5..0c6c4d96970 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-tt.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-tt.c
@@ -114,7 +114,7 @@ static bool iwl_within_ct_kill_margin(struct iwl_priv *priv)
114 s32 temp = priv->temperature; /* degrees CELSIUS except specified */ 114 s32 temp = priv->temperature; /* degrees CELSIUS except specified */
115 bool within_margin = false; 115 bool within_margin = false;
116 116
117 if (priv->cfg->temperature_kelvin) 117 if (priv->cfg->base_params->temperature_kelvin)
118 temp = KELVIN_TO_CELSIUS(priv->temperature); 118 temp = KELVIN_TO_CELSIUS(priv->temperature);
119 119
120 if (!priv->thermal_throttle.advanced_tt) 120 if (!priv->thermal_throttle.advanced_tt)
@@ -591,7 +591,7 @@ static void iwl_bg_tt_work(struct work_struct *work)
591 if (test_bit(STATUS_EXIT_PENDING, &priv->status)) 591 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
592 return; 592 return;
593 593
594 if (priv->cfg->temperature_kelvin) 594 if (priv->cfg->base_params->temperature_kelvin)
595 temp = KELVIN_TO_CELSIUS(priv->temperature); 595 temp = KELVIN_TO_CELSIUS(priv->temperature);
596 596
597 if (!priv->thermal_throttle.advanced_tt) 597 if (!priv->thermal_throttle.advanced_tt)
@@ -640,7 +640,7 @@ void iwl_tt_initialize(struct iwl_priv *priv)
640 INIT_WORK(&priv->ct_enter, iwl_bg_ct_enter); 640 INIT_WORK(&priv->ct_enter, iwl_bg_ct_enter);
641 INIT_WORK(&priv->ct_exit, iwl_bg_ct_exit); 641 INIT_WORK(&priv->ct_exit, iwl_bg_ct_exit);
642 642
643 if (priv->cfg->adv_thermal_throttle) { 643 if (priv->cfg->base_params->adv_thermal_throttle) {
644 IWL_DEBUG_POWER(priv, "Advanced Thermal Throttling\n"); 644 IWL_DEBUG_POWER(priv, "Advanced Thermal Throttling\n");
645 tt->restriction = kzalloc(sizeof(struct iwl_tt_restriction) * 645 tt->restriction = kzalloc(sizeof(struct iwl_tt_restriction) *
646 IWL_TI_STATE_MAX, GFP_KERNEL); 646 IWL_TI_STATE_MAX, GFP_KERNEL);
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
index 5950184d986..77753b72f23 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
@@ -224,13 +224,13 @@ int iwlagn_txq_agg_enable(struct iwl_priv *priv, int txq_id,
224 int ret; 224 int ret;
225 225
226 if ((IWLAGN_FIRST_AMPDU_QUEUE > txq_id) || 226 if ((IWLAGN_FIRST_AMPDU_QUEUE > txq_id) ||
227 (IWLAGN_FIRST_AMPDU_QUEUE + priv->cfg->num_of_ampdu_queues 227 (IWLAGN_FIRST_AMPDU_QUEUE +
228 <= txq_id)) { 228 priv->cfg->base_params->num_of_ampdu_queues <= txq_id)) {
229 IWL_WARN(priv, 229 IWL_WARN(priv,
230 "queue number out of range: %d, must be %d to %d\n", 230 "queue number out of range: %d, must be %d to %d\n",
231 txq_id, IWLAGN_FIRST_AMPDU_QUEUE, 231 txq_id, IWLAGN_FIRST_AMPDU_QUEUE,
232 IWLAGN_FIRST_AMPDU_QUEUE + 232 IWLAGN_FIRST_AMPDU_QUEUE +
233 priv->cfg->num_of_ampdu_queues - 1); 233 priv->cfg->base_params->num_of_ampdu_queues - 1);
234 return -EINVAL; 234 return -EINVAL;
235 } 235 }
236 236
@@ -286,13 +286,13 @@ int iwlagn_txq_agg_disable(struct iwl_priv *priv, u16 txq_id,
286 u16 ssn_idx, u8 tx_fifo) 286 u16 ssn_idx, u8 tx_fifo)
287{ 287{
288 if ((IWLAGN_FIRST_AMPDU_QUEUE > txq_id) || 288 if ((IWLAGN_FIRST_AMPDU_QUEUE > txq_id) ||
289 (IWLAGN_FIRST_AMPDU_QUEUE + priv->cfg->num_of_ampdu_queues 289 (IWLAGN_FIRST_AMPDU_QUEUE +
290 <= txq_id)) { 290 priv->cfg->base_params->num_of_ampdu_queues <= txq_id)) {
291 IWL_ERR(priv, 291 IWL_ERR(priv,
292 "queue number out of range: %d, must be %d to %d\n", 292 "queue number out of range: %d, must be %d to %d\n",
293 txq_id, IWLAGN_FIRST_AMPDU_QUEUE, 293 txq_id, IWLAGN_FIRST_AMPDU_QUEUE,
294 IWLAGN_FIRST_AMPDU_QUEUE + 294 IWLAGN_FIRST_AMPDU_QUEUE +
295 priv->cfg->num_of_ampdu_queues - 1); 295 priv->cfg->base_params->num_of_ampdu_queues - 1);
296 return -EINVAL; 296 return -EINVAL;
297 } 297 }
298 298
@@ -350,7 +350,8 @@ static void iwlagn_tx_cmd_build_basic(struct iwl_priv *priv,
350 if (ieee80211_is_back_req(fc)) 350 if (ieee80211_is_back_req(fc))
351 tx_flags |= TX_CMD_FLG_ACK_MSK | TX_CMD_FLG_IMM_BA_RSP_MASK; 351 tx_flags |= TX_CMD_FLG_ACK_MSK | TX_CMD_FLG_IMM_BA_RSP_MASK;
352 else if (info->band == IEEE80211_BAND_2GHZ && 352 else if (info->band == IEEE80211_BAND_2GHZ &&
353 priv->cfg->advanced_bt_coexist && 353 priv->cfg->bt_params &&
354 priv->cfg->bt_params->advanced_bt_coexist &&
354 (ieee80211_is_auth(fc) || ieee80211_is_assoc_req(fc) || 355 (ieee80211_is_auth(fc) || ieee80211_is_assoc_req(fc) ||
355 ieee80211_is_reassoc_req(fc) || 356 ieee80211_is_reassoc_req(fc) ||
356 skb->protocol == cpu_to_be16(ETH_P_PAE))) 357 skb->protocol == cpu_to_be16(ETH_P_PAE)))
@@ -444,7 +445,9 @@ static void iwlagn_tx_cmd_build_rate(struct iwl_priv *priv,
444 rate_flags |= RATE_MCS_CCK_MSK; 445 rate_flags |= RATE_MCS_CCK_MSK;
445 446
446 /* Set up antennas */ 447 /* Set up antennas */
447 if (priv->cfg->advanced_bt_coexist && priv->bt_full_concurrent) { 448 if (priv->cfg->bt_params &&
449 priv->cfg->bt_params->advanced_bt_coexist &&
450 priv->bt_full_concurrent) {
448 /* operated as 1x1 in full concurrency mode */ 451 /* operated as 1x1 in full concurrency mode */
449 priv->mgmt_tx_ant = iwl_toggle_tx_ant(priv, priv->mgmt_tx_ant, 452 priv->mgmt_tx_ant = iwl_toggle_tx_ant(priv, priv->mgmt_tx_ant,
450 first_antenna(priv->hw_params.valid_tx_ant)); 453 first_antenna(priv->hw_params.valid_tx_ant));
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c
index 8bfb0495a76..e1dd76267dc 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c
@@ -307,7 +307,8 @@ void iwlagn_init_alive_start(struct iwl_priv *priv)
307 goto restart; 307 goto restart;
308 } 308 }
309 309
310 if (priv->cfg->advanced_bt_coexist) { 310 if (priv->cfg->bt_params &&
311 priv->cfg->bt_params->advanced_bt_coexist) {
311 /* 312 /*
312 * Tell uCode we are ready to perform calibration 313 * Tell uCode we are ready to perform calibration
313 * need to perform this before any calibration 314 * need to perform this before any calibration
@@ -330,7 +331,7 @@ static int iwlagn_send_wimax_coex(struct iwl_priv *priv)
330{ 331{
331 struct iwl_wimax_coex_cmd coex_cmd; 332 struct iwl_wimax_coex_cmd coex_cmd;
332 333
333 if (priv->cfg->support_wimax_coexist) { 334 if (priv->cfg->base_params->support_wimax_coexist) {
334 /* UnMask wake up src at associated sleep */ 335 /* UnMask wake up src at associated sleep */
335 coex_cmd.flags = COEX_FLAGS_ASSOC_WA_UNMASK_MSK; 336 coex_cmd.flags = COEX_FLAGS_ASSOC_WA_UNMASK_MSK;
336 337
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index 646864a26ea..a6dce616ee3 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -2256,13 +2256,15 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
2256 if (pieces.init_evtlog_size) 2256 if (pieces.init_evtlog_size)
2257 priv->_agn.init_evtlog_size = (pieces.init_evtlog_size - 16)/12; 2257 priv->_agn.init_evtlog_size = (pieces.init_evtlog_size - 16)/12;
2258 else 2258 else
2259 priv->_agn.init_evtlog_size = priv->cfg->max_event_log_size; 2259 priv->_agn.init_evtlog_size =
2260 priv->cfg->base_params->max_event_log_size;
2260 priv->_agn.init_errlog_ptr = pieces.init_errlog_ptr; 2261 priv->_agn.init_errlog_ptr = pieces.init_errlog_ptr;
2261 priv->_agn.inst_evtlog_ptr = pieces.inst_evtlog_ptr; 2262 priv->_agn.inst_evtlog_ptr = pieces.inst_evtlog_ptr;
2262 if (pieces.inst_evtlog_size) 2263 if (pieces.inst_evtlog_size)
2263 priv->_agn.inst_evtlog_size = (pieces.inst_evtlog_size - 16)/12; 2264 priv->_agn.inst_evtlog_size = (pieces.inst_evtlog_size - 16)/12;
2264 else 2265 else
2265 priv->_agn.inst_evtlog_size = priv->cfg->max_event_log_size; 2266 priv->_agn.inst_evtlog_size =
2267 priv->cfg->base_params->max_event_log_size;
2266 priv->_agn.inst_errlog_ptr = pieces.inst_errlog_ptr; 2268 priv->_agn.inst_errlog_ptr = pieces.inst_errlog_ptr;
2267 2269
2268 if (ucode_capa.pan) { 2270 if (ucode_capa.pan) {
@@ -2732,7 +2734,7 @@ static void iwl_rf_kill_ct_config(struct iwl_priv *priv)
2732 spin_unlock_irqrestore(&priv->lock, flags); 2734 spin_unlock_irqrestore(&priv->lock, flags);
2733 priv->thermal_throttle.ct_kill_toggle = false; 2735 priv->thermal_throttle.ct_kill_toggle = false;
2734 2736
2735 if (priv->cfg->support_ct_kill_exit) { 2737 if (priv->cfg->base_params->support_ct_kill_exit) {
2736 adv_cmd.critical_temperature_enter = 2738 adv_cmd.critical_temperature_enter =
2737 cpu_to_le32(priv->hw_params.ct_kill_threshold); 2739 cpu_to_le32(priv->hw_params.ct_kill_threshold);
2738 adv_cmd.critical_temperature_exit = 2740 adv_cmd.critical_temperature_exit =
@@ -2765,6 +2767,23 @@ static void iwl_rf_kill_ct_config(struct iwl_priv *priv)
2765 } 2767 }
2766} 2768}
2767 2769
2770static int iwlagn_send_calib_cfg_rt(struct iwl_priv *priv, u32 cfg)
2771{
2772 struct iwl_calib_cfg_cmd calib_cfg_cmd;
2773 struct iwl_host_cmd cmd = {
2774 .id = CALIBRATION_CFG_CMD,
2775 .len = sizeof(struct iwl_calib_cfg_cmd),
2776 .data = &calib_cfg_cmd,
2777 };
2778
2779 memset(&calib_cfg_cmd, 0, sizeof(calib_cfg_cmd));
2780 calib_cfg_cmd.ucd_calib_cfg.once.is_enable = IWL_CALIB_INIT_CFG_ALL;
2781 calib_cfg_cmd.ucd_calib_cfg.once.start = cpu_to_le32(cfg);
2782
2783 return iwl_send_cmd(priv, &cmd);
2784}
2785
2786
2768/** 2787/**
2769 * iwl_alive_start - called after REPLY_ALIVE notification received 2788 * iwl_alive_start - called after REPLY_ALIVE notification received
2770 * from protocol/runtime uCode (initialization uCode's 2789 * from protocol/runtime uCode (initialization uCode's
@@ -2801,6 +2820,10 @@ static void iwl_alive_start(struct iwl_priv *priv)
2801 goto restart; 2820 goto restart;
2802 } 2821 }
2803 2822
2823 if (priv->hw_params.calib_rt_cfg)
2824 iwlagn_send_calib_cfg_rt(priv, priv->hw_params.calib_rt_cfg);
2825
2826
2804 /* After the ALIVE response, we can send host commands to the uCode */ 2827 /* After the ALIVE response, we can send host commands to the uCode */
2805 set_bit(STATUS_ALIVE, &priv->status); 2828 set_bit(STATUS_ALIVE, &priv->status);
2806 2829
@@ -2808,13 +2831,15 @@ static void iwl_alive_start(struct iwl_priv *priv)
2808 /* Enable timer to monitor the driver queues */ 2831 /* Enable timer to monitor the driver queues */
2809 mod_timer(&priv->monitor_recover, 2832 mod_timer(&priv->monitor_recover,
2810 jiffies + 2833 jiffies +
2811 msecs_to_jiffies(priv->cfg->monitor_recover_period)); 2834 msecs_to_jiffies(
2835 priv->cfg->base_params->monitor_recover_period));
2812 } 2836 }
2813 2837
2814 if (iwl_is_rfkill(priv)) 2838 if (iwl_is_rfkill(priv))
2815 return; 2839 return;
2816 2840
2817 if (priv->cfg->advanced_bt_coexist) { 2841 if (priv->cfg->bt_params &&
2842 priv->cfg->bt_params->advanced_bt_coexist) {
2818 /* Configure Bluetooth device coexistence support */ 2843 /* Configure Bluetooth device coexistence support */
2819 priv->bt_valid = IWLAGN_BT_ALL_VALID_MSK; 2844 priv->bt_valid = IWLAGN_BT_ALL_VALID_MSK;
2820 priv->kill_ack_mask = IWLAGN_BT_KILL_ACK_MASK_DEFAULT; 2845 priv->kill_ack_mask = IWLAGN_BT_KILL_ACK_MASK_DEFAULT;
@@ -2854,7 +2879,8 @@ static void iwl_alive_start(struct iwl_priv *priv)
2854 priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx); 2879 priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx);
2855 } 2880 }
2856 2881
2857 if (!priv->cfg->advanced_bt_coexist) { 2882 if (priv->cfg->bt_params &&
2883 !priv->cfg->bt_params->advanced_bt_coexist) {
2858 /* Configure Bluetooth device coexistence support */ 2884 /* Configure Bluetooth device coexistence support */
2859 priv->cfg->ops->hcmd->send_bt_config(priv); 2885 priv->cfg->ops->hcmd->send_bt_config(priv);
2860 } 2886 }
@@ -2907,7 +2933,11 @@ static void __iwl_down(struct iwl_priv *priv)
2907 2933
2908 /* reset BT coex data */ 2934 /* reset BT coex data */
2909 priv->bt_status = 0; 2935 priv->bt_status = 0;
2910 priv->bt_traffic_load = priv->cfg->bt_init_traffic_load; 2936 if (priv->cfg->bt_params)
2937 priv->bt_traffic_load =
2938 priv->cfg->bt_params->bt_init_traffic_load;
2939 else
2940 priv->bt_traffic_load = 0;
2911 priv->bt_sco_active = false; 2941 priv->bt_sco_active = false;
2912 priv->bt_full_concurrent = false; 2942 priv->bt_full_concurrent = false;
2913 priv->bt_ci_compliance = 0; 2943 priv->bt_ci_compliance = 0;
@@ -3201,7 +3231,8 @@ static void iwl_bg_run_time_calib_work(struct work_struct *work)
3201 } 3231 }
3202 3232
3203 if (priv->start_calib) { 3233 if (priv->start_calib) {
3204 if (priv->cfg->bt_statistics) { 3234 if (priv->cfg->bt_params &&
3235 priv->cfg->bt_params->bt_statistics) {
3205 iwl_chain_noise_calibration(priv, 3236 iwl_chain_noise_calibration(priv,
3206 (void *)&priv->_agn.statistics_bt); 3237 (void *)&priv->_agn.statistics_bt);
3207 iwl_sensitivity_calibration(priv, 3238 iwl_sensitivity_calibration(priv,
@@ -3400,7 +3431,7 @@ static int iwl_mac_setup_register(struct iwl_priv *priv,
3400 IEEE80211_HW_NEED_DTIM_PERIOD | 3431 IEEE80211_HW_NEED_DTIM_PERIOD |
3401 IEEE80211_HW_SPECTRUM_MGMT; 3432 IEEE80211_HW_SPECTRUM_MGMT;
3402 3433
3403 if (!priv->cfg->broken_powersave) 3434 if (!priv->cfg->base_params->broken_powersave)
3404 hw->flags |= IEEE80211_HW_SUPPORTS_PS | 3435 hw->flags |= IEEE80211_HW_SUPPORTS_PS |
3405 IEEE80211_HW_SUPPORTS_DYNAMIC_PS; 3436 IEEE80211_HW_SUPPORTS_DYNAMIC_PS;
3406 3437
@@ -3725,7 +3756,8 @@ static int iwl_mac_ampdu_action(struct ieee80211_hw *hw,
3725 } 3756 }
3726 if (test_bit(STATUS_EXIT_PENDING, &priv->status)) 3757 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
3727 ret = 0; 3758 ret = 0;
3728 if (priv->cfg->use_rts_for_aggregation) { 3759 if (priv->cfg->ht_params &&
3760 priv->cfg->ht_params->use_rts_for_aggregation) {
3729 struct iwl_station_priv *sta_priv = 3761 struct iwl_station_priv *sta_priv =
3730 (void *) sta->drv_priv; 3762 (void *) sta->drv_priv;
3731 /* 3763 /*
@@ -3739,7 +3771,8 @@ static int iwl_mac_ampdu_action(struct ieee80211_hw *hw,
3739 } 3771 }
3740 break; 3772 break;
3741 case IEEE80211_AMPDU_TX_OPERATIONAL: 3773 case IEEE80211_AMPDU_TX_OPERATIONAL:
3742 if (priv->cfg->use_rts_for_aggregation) { 3774 if (priv->cfg->ht_params &&
3775 priv->cfg->ht_params->use_rts_for_aggregation) {
3743 struct iwl_station_priv *sta_priv = 3776 struct iwl_station_priv *sta_priv =
3744 (void *) sta->drv_priv; 3777 (void *) sta->drv_priv;
3745 3778
@@ -4057,7 +4090,7 @@ static void iwl_setup_deferred_work(struct iwl_priv *priv)
4057 priv->cfg->ops->lib->recover_from_tx_stall; 4090 priv->cfg->ops->lib->recover_from_tx_stall;
4058 } 4091 }
4059 4092
4060 if (!priv->cfg->use_isr_legacy) 4093 if (!priv->cfg->base_params->use_isr_legacy)
4061 tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long)) 4094 tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long))
4062 iwl_irq_tasklet, (unsigned long)priv); 4095 iwl_irq_tasklet, (unsigned long)priv);
4063 else 4096 else
@@ -4142,7 +4175,8 @@ static int iwl_init_drv(struct iwl_priv *priv)
4142 iwl_init_scan_params(priv); 4175 iwl_init_scan_params(priv);
4143 4176
4144 /* init bt coex */ 4177 /* init bt coex */
4145 if (priv->cfg->advanced_bt_coexist) { 4178 if (priv->cfg->bt_params &&
4179 priv->cfg->bt_params->advanced_bt_coexist) {
4146 priv->kill_ack_mask = IWLAGN_BT_KILL_ACK_MASK_DEFAULT; 4180 priv->kill_ack_mask = IWLAGN_BT_KILL_ACK_MASK_DEFAULT;
4147 priv->kill_cts_mask = IWLAGN_BT_KILL_CTS_MASK_DEFAULT; 4181 priv->kill_cts_mask = IWLAGN_BT_KILL_CTS_MASK_DEFAULT;
4148 priv->bt_valid = IWLAGN_BT_ALL_VALID_MSK; 4182 priv->bt_valid = IWLAGN_BT_ALL_VALID_MSK;
@@ -4273,9 +4307,8 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
4273 /* Disabling hardware scan means that mac80211 will perform scans 4307 /* Disabling hardware scan means that mac80211 will perform scans
4274 * "the hard way", rather than using device's scan. */ 4308 * "the hard way", rather than using device's scan. */
4275 if (cfg->mod_params->disable_hw_scan) { 4309 if (cfg->mod_params->disable_hw_scan) {
4276 if (iwl_debug_level & IWL_DL_INFO) 4310 dev_printk(KERN_DEBUG, &(pdev->dev),
4277 dev_printk(KERN_DEBUG, &(pdev->dev), 4311 "sw scan support is deprecated\n");
4278 "Disabling hw_scan\n");
4279 iwl_hw_ops.hw_scan = NULL; 4312 iwl_hw_ops.hw_scan = NULL;
4280 } 4313 }
4281 4314
@@ -4788,6 +4821,22 @@ static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = {
4788 {IWL_PCI_DEVICE(0x0083, 0x1326, iwl1000_bg_cfg)}, 4821 {IWL_PCI_DEVICE(0x0083, 0x1326, iwl1000_bg_cfg)},
4789 {IWL_PCI_DEVICE(0x0084, 0x1216, iwl1000_bg_cfg)}, 4822 {IWL_PCI_DEVICE(0x0084, 0x1216, iwl1000_bg_cfg)},
4790 {IWL_PCI_DEVICE(0x0084, 0x1316, iwl1000_bg_cfg)}, 4823 {IWL_PCI_DEVICE(0x0084, 0x1316, iwl1000_bg_cfg)},
4824
4825/* 100 Series WiFi */
4826 {IWL_PCI_DEVICE(0x08AE, 0x1005, iwl100_bgn_cfg)},
4827 {IWL_PCI_DEVICE(0x08AF, 0x1015, iwl100_bgn_cfg)},
4828 {IWL_PCI_DEVICE(0x08AE, 0x1025, iwl100_bgn_cfg)},
4829 {IWL_PCI_DEVICE(0x08AE, 0x1007, iwl100_bg_cfg)},
4830 {IWL_PCI_DEVICE(0x08AE, 0x1017, iwl100_bg_cfg)},
4831
4832/* 130 Series WiFi */
4833 {IWL_PCI_DEVICE(0x0896, 0x5005, iwl130_bgn_cfg)},
4834 {IWL_PCI_DEVICE(0x0896, 0x5007, iwl130_bg_cfg)},
4835 {IWL_PCI_DEVICE(0x0897, 0x5015, iwl130_bgn_cfg)},
4836 {IWL_PCI_DEVICE(0x0897, 0x5017, iwl130_bg_cfg)},
4837 {IWL_PCI_DEVICE(0x0896, 0x5025, iwl130_bgn_cfg)},
4838 {IWL_PCI_DEVICE(0x0896, 0x5027, iwl130_bg_cfg)},
4839
4791#endif /* CONFIG_IWL5000 */ 4840#endif /* CONFIG_IWL5000 */
4792 4841
4793 {0} 4842 {0}
@@ -4876,7 +4925,8 @@ module_param_named(fw_restart, iwlagn_mod_params.restart_fw, int, S_IRUGO);
4876MODULE_PARM_DESC(fw_restart, "restart firmware in case of error"); 4925MODULE_PARM_DESC(fw_restart, "restart firmware in case of error");
4877module_param_named( 4926module_param_named(
4878 disable_hw_scan, iwlagn_mod_params.disable_hw_scan, int, S_IRUGO); 4927 disable_hw_scan, iwlagn_mod_params.disable_hw_scan, int, S_IRUGO);
4879MODULE_PARM_DESC(disable_hw_scan, "disable hardware scanning (default 0)"); 4928MODULE_PARM_DESC(disable_hw_scan,
4929 "disable hardware scanning (default 0) (deprecated)");
4880 4930
4881module_param_named(ucode_alternative, iwlagn_wanted_ucode_alternative, int, 4931module_param_named(ucode_alternative, iwlagn_wanted_ucode_alternative, int,
4882 S_IRUGO); 4932 S_IRUGO);
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h
index a372184ac21..eb3812a3586 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.h
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.h
@@ -92,6 +92,10 @@ extern struct iwl_cfg iwl6050_2abg_cfg;
92extern struct iwl_cfg iwl6050g2_bgn_cfg; 92extern struct iwl_cfg iwl6050g2_bgn_cfg;
93extern struct iwl_cfg iwl1000_bgn_cfg; 93extern struct iwl_cfg iwl1000_bgn_cfg;
94extern struct iwl_cfg iwl1000_bg_cfg; 94extern struct iwl_cfg iwl1000_bg_cfg;
95extern struct iwl_cfg iwl100_bgn_cfg;
96extern struct iwl_cfg iwl100_bg_cfg;
97extern struct iwl_cfg iwl130_bgn_cfg;
98extern struct iwl_cfg iwl130_bg_cfg;
95 99
96extern struct iwl_mod_params iwlagn_mod_params; 100extern struct iwl_mod_params iwlagn_mod_params;
97extern struct iwl_hcmd_ops iwlagn_hcmd; 101extern struct iwl_hcmd_ops iwlagn_hcmd;
diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h
index 27e250c8d4b..fe652568fec 100644
--- a/drivers/net/wireless/iwlwifi/iwl-commands.h
+++ b/drivers/net/wireless/iwlwifi/iwl-commands.h
@@ -420,12 +420,12 @@ struct iwl4965_tx_power_db {
420 420
421/** 421/**
422 * Command REPLY_TX_POWER_DBM_CMD = 0x98 422 * Command REPLY_TX_POWER_DBM_CMD = 0x98
423 * struct iwl5000_tx_power_dbm_cmd 423 * struct iwlagn_tx_power_dbm_cmd
424 */ 424 */
425#define IWL50_TX_POWER_AUTO 0x7f 425#define IWLAGN_TX_POWER_AUTO 0x7f
426#define IWL50_TX_POWER_NO_CLOSED (0x1 << 6) 426#define IWLAGN_TX_POWER_NO_CLOSED (0x1 << 6)
427 427
428struct iwl5000_tx_power_dbm_cmd { 428struct iwlagn_tx_power_dbm_cmd {
429 s8 global_lmt; /*in half-dBm (e.g. 30 = 15 dBm) */ 429 s8 global_lmt; /*in half-dBm (e.g. 30 = 15 dBm) */
430 u8 flags; 430 u8 flags;
431 s8 srv_chan_lmt; /*in half-dBm (e.g. 30 = 15 dBm) */ 431 s8 srv_chan_lmt; /*in half-dBm (e.g. 30 = 15 dBm) */
@@ -1042,7 +1042,7 @@ struct iwl4965_keyinfo {
1042 u8 key[16]; /* 16-byte unicast decryption key */ 1042 u8 key[16]; /* 16-byte unicast decryption key */
1043} __packed; 1043} __packed;
1044 1044
1045/* 5000 */ 1045/* agn */
1046struct iwl_keyinfo { 1046struct iwl_keyinfo {
1047 __le16 key_flags; 1047 __le16 key_flags;
1048 u8 tkip_rx_tsc_byte2; /* TSC[2] for key mix ph1 detection */ 1048 u8 tkip_rx_tsc_byte2; /* TSC[2] for key mix ph1 detection */
@@ -1168,7 +1168,7 @@ struct iwl4965_addsta_cmd {
1168 __le16 reserved2; 1168 __le16 reserved2;
1169} __packed; 1169} __packed;
1170 1170
1171/* 5000 */ 1171/* agn */
1172struct iwl_addsta_cmd { 1172struct iwl_addsta_cmd {
1173 u8 mode; /* 1: modify existing, 0: add new station */ 1173 u8 mode; /* 1: modify existing, 0: add new station */
1174 u8 reserved[3]; 1174 u8 reserved[3];
@@ -1959,12 +1959,12 @@ struct iwl4965_tx_resp {
1959#define IWL50_TX_RES_INV_RATE_INDEX_MSK 0x80 1959#define IWL50_TX_RES_INV_RATE_INDEX_MSK 0x80
1960 1960
1961/* refer to ra_tid */ 1961/* refer to ra_tid */
1962#define IWL50_TX_RES_TID_POS 0 1962#define IWLAGN_TX_RES_TID_POS 0
1963#define IWL50_TX_RES_TID_MSK 0x0f 1963#define IWLAGN_TX_RES_TID_MSK 0x0f
1964#define IWL50_TX_RES_RA_POS 4 1964#define IWLAGN_TX_RES_RA_POS 4
1965#define IWL50_TX_RES_RA_MSK 0xf0 1965#define IWLAGN_TX_RES_RA_MSK 0xf0
1966 1966
1967struct iwl5000_tx_resp { 1967struct iwlagn_tx_resp {
1968 u8 frame_count; /* 1 no aggregation, >1 aggregation */ 1968 u8 frame_count; /* 1 no aggregation, >1 aggregation */
1969 u8 bt_kill_count; /* # blocked by bluetooth (unused for agg) */ 1969 u8 bt_kill_count; /* # blocked by bluetooth (unused for agg) */
1970 u8 failure_rts; /* # failures due to unsuccessful RTS */ 1970 u8 failure_rts; /* # failures due to unsuccessful RTS */
@@ -3800,6 +3800,21 @@ enum {
3800 3800
3801#define IWL_CALIB_INIT_CFG_ALL cpu_to_le32(0xffffffff) 3801#define IWL_CALIB_INIT_CFG_ALL cpu_to_le32(0xffffffff)
3802 3802
3803/* This enum defines the bitmap of various calibrations to enable in both
3804 * init ucode and runtime ucode through CALIBRATION_CFG_CMD.
3805 */
3806enum iwl_ucode_calib_cfg {
3807 IWL_CALIB_CFG_RX_BB_IDX,
3808 IWL_CALIB_CFG_DC_IDX,
3809 IWL_CALIB_CFG_TX_IQ_IDX,
3810 IWL_CALIB_CFG_RX_IQ_IDX,
3811 IWL_CALIB_CFG_NOISE_IDX,
3812 IWL_CALIB_CFG_CRYSTAL_IDX,
3813 IWL_CALIB_CFG_TEMPERATURE_IDX,
3814 IWL_CALIB_CFG_PAPD_IDX,
3815};
3816
3817
3803struct iwl_calib_cfg_elmnt_s { 3818struct iwl_calib_cfg_elmnt_s {
3804 __le32 is_enable; 3819 __le32 is_enable;
3805 __le32 start; 3820 __le32 start;
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index 5c568933ce4..516c55ae38a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -232,7 +232,8 @@ static void iwlcore_init_ht_hw_capab(const struct iwl_priv *priv,
232 232
233 ht_info->ht_supported = true; 233 ht_info->ht_supported = true;
234 234
235 if (priv->cfg->ht_greenfield_support) 235 if (priv->cfg->ht_params &&
236 priv->cfg->ht_params->ht_greenfield_support)
236 ht_info->cap |= IEEE80211_HT_CAP_GRN_FLD; 237 ht_info->cap |= IEEE80211_HT_CAP_GRN_FLD;
237 ht_info->cap |= IEEE80211_HT_CAP_SGI_20; 238 ht_info->cap |= IEEE80211_HT_CAP_SGI_20;
238 max_bit_rate = MAX_BIT_RATE_20_MHZ; 239 max_bit_rate = MAX_BIT_RATE_20_MHZ;
@@ -247,11 +248,11 @@ static void iwlcore_init_ht_hw_capab(const struct iwl_priv *priv,
247 ht_info->cap |= IEEE80211_HT_CAP_MAX_AMSDU; 248 ht_info->cap |= IEEE80211_HT_CAP_MAX_AMSDU;
248 249
249 ht_info->ampdu_factor = CFG_HT_RX_AMPDU_FACTOR_DEF; 250 ht_info->ampdu_factor = CFG_HT_RX_AMPDU_FACTOR_DEF;
250 if (priv->cfg->ampdu_factor) 251 if (priv->cfg->bt_params && priv->cfg->bt_params->ampdu_factor)
251 ht_info->ampdu_factor = priv->cfg->ampdu_factor; 252 ht_info->ampdu_factor = priv->cfg->bt_params->ampdu_factor;
252 ht_info->ampdu_density = CFG_HT_MPDU_DENSITY_DEF; 253 ht_info->ampdu_density = CFG_HT_MPDU_DENSITY_DEF;
253 if (priv->cfg->ampdu_density) 254 if (priv->cfg->bt_params && priv->cfg->bt_params->ampdu_density)
254 ht_info->ampdu_density = priv->cfg->ampdu_density; 255 ht_info->ampdu_density = priv->cfg->bt_params->ampdu_density;
255 256
256 ht_info->mcs.rx_mask[0] = 0xFF; 257 ht_info->mcs.rx_mask[0] = 0xFF;
257 if (rx_chains_num >= 2) 258 if (rx_chains_num >= 2)
@@ -850,8 +851,10 @@ EXPORT_SYMBOL(iwl_set_rxon_ht);
850 */ 851 */
851static int iwl_get_active_rx_chain_count(struct iwl_priv *priv) 852static int iwl_get_active_rx_chain_count(struct iwl_priv *priv)
852{ 853{
853 if (priv->cfg->advanced_bt_coexist && (priv->bt_full_concurrent || 854 if (priv->cfg->bt_params &&
854 priv->bt_traffic_load >= IWL_BT_COEX_TRAFFIC_LOAD_HIGH)) { 855 priv->cfg->bt_params->advanced_bt_coexist &&
856 (priv->bt_full_concurrent ||
857 priv->bt_traffic_load >= IWL_BT_COEX_TRAFFIC_LOAD_HIGH)) {
855 /* 858 /*
856 * only use chain 'A' in bt high traffic load or 859 * only use chain 'A' in bt high traffic load or
857 * full concurrency mode 860 * full concurrency mode
@@ -919,8 +922,10 @@ void iwl_set_rxon_chain(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
919 else 922 else
920 active_chains = priv->hw_params.valid_rx_ant; 923 active_chains = priv->hw_params.valid_rx_ant;
921 924
922 if (priv->cfg->advanced_bt_coexist && (priv->bt_full_concurrent || 925 if (priv->cfg->bt_params &&
923 priv->bt_traffic_load >= IWL_BT_COEX_TRAFFIC_LOAD_HIGH)) { 926 priv->cfg->bt_params->advanced_bt_coexist &&
927 (priv->bt_full_concurrent ||
928 priv->bt_traffic_load >= IWL_BT_COEX_TRAFFIC_LOAD_HIGH)) {
924 /* 929 /*
925 * only use chain 'A' in bt high traffic load or 930 * only use chain 'A' in bt high traffic load or
926 * full concurrency mode 931 * full concurrency mode
@@ -1362,7 +1367,7 @@ int iwl_apm_init(struct iwl_priv *priv)
1362 * If not (unlikely), enable L0S, so there is at least some 1367 * If not (unlikely), enable L0S, so there is at least some
1363 * power savings, even without L1. 1368 * power savings, even without L1.
1364 */ 1369 */
1365 if (priv->cfg->set_l0s) { 1370 if (priv->cfg->base_params->set_l0s) {
1366 lctl = iwl_pcie_link_ctl(priv); 1371 lctl = iwl_pcie_link_ctl(priv);
1367 if ((lctl & PCI_CFG_LINK_CTRL_VAL_L1_EN) == 1372 if ((lctl & PCI_CFG_LINK_CTRL_VAL_L1_EN) ==
1368 PCI_CFG_LINK_CTRL_VAL_L1_EN) { 1373 PCI_CFG_LINK_CTRL_VAL_L1_EN) {
@@ -1379,8 +1384,9 @@ int iwl_apm_init(struct iwl_priv *priv)
1379 } 1384 }
1380 1385
1381 /* Configure analog phase-lock-loop before activating to D0A */ 1386 /* Configure analog phase-lock-loop before activating to D0A */
1382 if (priv->cfg->pll_cfg_val) 1387 if (priv->cfg->base_params->pll_cfg_val)
1383 iwl_set_bit(priv, CSR_ANA_PLL_CFG, priv->cfg->pll_cfg_val); 1388 iwl_set_bit(priv, CSR_ANA_PLL_CFG,
1389 priv->cfg->base_params->pll_cfg_val);
1384 1390
1385 /* 1391 /*
1386 * Set "initialization complete" bit to move adapter from 1392 * Set "initialization complete" bit to move adapter from
@@ -1411,7 +1417,7 @@ int iwl_apm_init(struct iwl_priv *priv)
1411 * do not disable clocks. This preserves any hardware bits already 1417 * do not disable clocks. This preserves any hardware bits already
1412 * set by default in "CLK_CTRL_REG" after reset. 1418 * set by default in "CLK_CTRL_REG" after reset.
1413 */ 1419 */
1414 if (priv->cfg->use_bsm) 1420 if (priv->cfg->base_params->use_bsm)
1415 iwl_write_prph(priv, APMG_CLK_EN_REG, 1421 iwl_write_prph(priv, APMG_CLK_EN_REG,
1416 APMG_CLK_VAL_DMA_CLK_RQT | APMG_CLK_VAL_BSM_CLK_RQT); 1422 APMG_CLK_VAL_DMA_CLK_RQT | APMG_CLK_VAL_BSM_CLK_RQT);
1417 else 1423 else
@@ -2003,7 +2009,8 @@ int iwl_mac_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
2003 2009
2004 mutex_lock(&priv->mutex); 2010 mutex_lock(&priv->mutex);
2005 2011
2006 if (WARN_ON(!iwl_is_ready_rf(priv))) { 2012 if (!iwl_is_ready_rf(priv)) {
2013 IWL_WARN(priv, "Try to add interface when device not ready\n");
2007 err = -EINVAL; 2014 err = -EINVAL;
2008 goto out; 2015 goto out;
2009 } 2016 }
@@ -2053,7 +2060,8 @@ int iwl_mac_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
2053 goto out_err; 2060 goto out_err;
2054 } 2061 }
2055 2062
2056 if (priv->cfg->advanced_bt_coexist && 2063 if (priv->cfg->bt_params &&
2064 priv->cfg->bt_params->advanced_bt_coexist &&
2057 vif->type == NL80211_IFTYPE_ADHOC) { 2065 vif->type == NL80211_IFTYPE_ADHOC) {
2058 /* 2066 /*
2059 * pretend to have high BT traffic as long as we 2067 * pretend to have high BT traffic as long as we
@@ -2316,7 +2324,8 @@ int iwl_alloc_txq_mem(struct iwl_priv *priv)
2316{ 2324{
2317 if (!priv->txq) 2325 if (!priv->txq)
2318 priv->txq = kzalloc( 2326 priv->txq = kzalloc(
2319 sizeof(struct iwl_tx_queue) * priv->cfg->num_of_queues, 2327 sizeof(struct iwl_tx_queue) *
2328 priv->cfg->base_params->num_of_queues,
2320 GFP_KERNEL); 2329 GFP_KERNEL);
2321 if (!priv->txq) { 2330 if (!priv->txq) {
2322 IWL_ERR(priv, "Not enough memory for txq\n"); 2331 IWL_ERR(priv, "Not enough memory for txq\n");
@@ -2736,11 +2745,6 @@ int iwl_force_reset(struct iwl_priv *priv, int mode, bool external)
2736 if (test_bit(STATUS_EXIT_PENDING, &priv->status)) 2745 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
2737 return -EINVAL; 2746 return -EINVAL;
2738 2747
2739 if (test_bit(STATUS_SCANNING, &priv->status)) {
2740 IWL_DEBUG_INFO(priv, "scan in progress.\n");
2741 return -EINVAL;
2742 }
2743
2744 if (mode >= IWL_MAX_FORCE_RESET) { 2748 if (mode >= IWL_MAX_FORCE_RESET) {
2745 IWL_DEBUG_INFO(priv, "invalid reset request.\n"); 2749 IWL_DEBUG_INFO(priv, "invalid reset request.\n");
2746 return -EINVAL; 2750 return -EINVAL;
@@ -2827,33 +2831,34 @@ static int iwl_check_stuck_queue(struct iwl_priv *priv, int cnt)
2827 txq = &priv->txq[cnt]; 2831 txq = &priv->txq[cnt];
2828 q = &txq->q; 2832 q = &txq->q;
2829 /* queue is empty, skip */ 2833 /* queue is empty, skip */
2830 if (q->read_ptr != q->write_ptr) { 2834 if (q->read_ptr == q->write_ptr)
2831 if (q->read_ptr == q->last_read_ptr) { 2835 return 0;
2832 /* a queue has not been read from last time */ 2836
2833 if (q->repeat_same_read_ptr > MAX_REPEAT) { 2837 if (q->read_ptr == q->last_read_ptr) {
2834 IWL_ERR(priv, 2838 /* a queue has not been read from last time */
2835 "queue %d stuck %d time. Fw reload.\n", 2839 if (q->repeat_same_read_ptr > MAX_REPEAT) {
2836 q->id, q->repeat_same_read_ptr); 2840 IWL_ERR(priv,
2837 q->repeat_same_read_ptr = 0; 2841 "queue %d stuck %d time. Fw reload.\n",
2838 iwl_force_reset(priv, IWL_FW_RESET, false); 2842 q->id, q->repeat_same_read_ptr);
2839 } else {
2840 q->repeat_same_read_ptr++;
2841 IWL_DEBUG_RADIO(priv,
2842 "queue %d, not read %d time\n",
2843 q->id,
2844 q->repeat_same_read_ptr);
2845 if (!priv->cfg->advanced_bt_coexist) {
2846 mod_timer(&priv->monitor_recover,
2847 jiffies + msecs_to_jiffies(
2848 IWL_ONE_HUNDRED_MSECS));
2849 return 1;
2850 }
2851 }
2852 return 0;
2853 } else {
2854 q->last_read_ptr = q->read_ptr;
2855 q->repeat_same_read_ptr = 0; 2843 q->repeat_same_read_ptr = 0;
2844 iwl_force_reset(priv, IWL_FW_RESET, false);
2845 } else {
2846 q->repeat_same_read_ptr++;
2847 IWL_DEBUG_RADIO(priv,
2848 "queue %d, not read %d time\n",
2849 q->id,
2850 q->repeat_same_read_ptr);
2851 if (priv->cfg->bt_params &&
2852 !priv->cfg->bt_params->advanced_bt_coexist) {
2853 mod_timer(&priv->monitor_recover,
2854 jiffies + msecs_to_jiffies(
2855 IWL_ONE_HUNDRED_MSECS));
2856 return 1;
2857 }
2856 } 2858 }
2859 } else {
2860 q->last_read_ptr = q->read_ptr;
2861 q->repeat_same_read_ptr = 0;
2857 } 2862 }
2858 return 0; 2863 return 0;
2859} 2864}
@@ -2880,13 +2885,13 @@ void iwl_bg_monitor_recover(unsigned long data)
2880 return; 2885 return;
2881 } 2886 }
2882 } 2887 }
2883 if (priv->cfg->monitor_recover_period) { 2888 if (priv->cfg->base_params->monitor_recover_period) {
2884 /* 2889 /*
2885 * Reschedule the timer to occur in 2890 * Reschedule the timer to occur in
2886 * priv->cfg->monitor_recover_period 2891 * priv->cfg->base_params->monitor_recover_period
2887 */ 2892 */
2888 mod_timer(&priv->monitor_recover, jiffies + msecs_to_jiffies( 2893 mod_timer(&priv->monitor_recover, jiffies + msecs_to_jiffies(
2889 priv->cfg->monitor_recover_period)); 2894 priv->cfg->base_params->monitor_recover_period));
2890 } 2895 }
2891} 2896}
2892EXPORT_SYMBOL(iwl_bg_monitor_recover); 2897EXPORT_SYMBOL(iwl_bg_monitor_recover);
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index f0302bfe85f..6228b1c2ec9 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -137,7 +137,6 @@ struct iwl_debugfs_ops {
137struct iwl_temp_ops { 137struct iwl_temp_ops {
138 void (*temperature)(struct iwl_priv *priv); 138 void (*temperature)(struct iwl_priv *priv);
139 void (*set_ct_kill)(struct iwl_priv *priv); 139 void (*set_ct_kill)(struct iwl_priv *priv);
140 void (*set_calib_version)(struct iwl_priv *priv);
141}; 140};
142 141
143struct iwl_tt_ops { 142struct iwl_tt_ops {
@@ -233,11 +232,17 @@ struct iwl_led_ops {
233 int (*off)(struct iwl_priv *priv); 232 int (*off)(struct iwl_priv *priv);
234}; 233};
235 234
235/* NIC specific ops */
236struct iwl_nic_ops {
237 void (*additional_nic_config)(struct iwl_priv *priv);
238};
239
236struct iwl_ops { 240struct iwl_ops {
237 const struct iwl_lib_ops *lib; 241 const struct iwl_lib_ops *lib;
238 const struct iwl_hcmd_ops *hcmd; 242 const struct iwl_hcmd_ops *hcmd;
239 const struct iwl_hcmd_utils_ops *utils; 243 const struct iwl_hcmd_utils_ops *utils;
240 const struct iwl_led_ops *led; 244 const struct iwl_led_ops *led;
245 const struct iwl_nic_ops *nic;
241}; 246};
242 247
243struct iwl_mod_params { 248struct iwl_mod_params {
@@ -250,20 +255,12 @@ struct iwl_mod_params {
250 int restart_fw; /* def: 1 = restart firmware */ 255 int restart_fw; /* def: 1 = restart firmware */
251}; 256};
252 257
253/** 258/*
254 * struct iwl_cfg
255 * @fw_name_pre: Firmware filename prefix. The api version and extension
256 * (.ucode) will be added to filename before loading from disk. The
257 * filename is constructed as fw_name_pre<api>.ucode.
258 * @ucode_api_max: Highest version of uCode API supported by driver.
259 * @ucode_api_min: Lowest version of uCode API supported by driver.
260 * @pa_type: used by 6000 series only to identify the type of Power Amplifier
261 * @max_ll_items: max number of OTP blocks 259 * @max_ll_items: max number of OTP blocks
262 * @shadow_ram_support: shadow support for OTP memory 260 * @shadow_ram_support: shadow support for OTP memory
263 * @led_compensation: compensate on the led on/off time per HW according 261 * @led_compensation: compensate on the led on/off time per HW according
264 * to the deviation to achieve the desired led frequency. 262 * to the deviation to achieve the desired led frequency.
265 * The detail algorithm is described in iwl-led.c 263 * The detail algorithm is described in iwl-led.c
266 * @use_rts_for_aggregation: use rts/cts protection for HT traffic
267 * @chain_noise_num_beacons: number of beacons used to compute chain noise 264 * @chain_noise_num_beacons: number of beacons used to compute chain noise
268 * @adv_thermal_throttle: support advance thermal throttle 265 * @adv_thermal_throttle: support advance thermal throttle
269 * @support_ct_kill_exit: support ct kill exit condition 266 * @support_ct_kill_exit: support ct kill exit condition
@@ -281,15 +278,73 @@ struct iwl_mod_params {
281 * sensitivity calibration operation 278 * sensitivity calibration operation
282 * @chain_noise_calib_by_driver: driver has the capability to perform 279 * @chain_noise_calib_by_driver: driver has the capability to perform
283 * chain noise calibration operation 280 * chain noise calibration operation
284 * @scan_antennas: available antenna for scan operation 281*/
282struct iwl_base_params {
283 int eeprom_size;
284 int num_of_queues; /* def: HW dependent */
285 int num_of_ampdu_queues;/* def: HW dependent */
286 /* for iwl_apm_init() */
287 u32 pll_cfg_val;
288 bool set_l0s;
289 bool use_bsm;
290
291 bool use_isr_legacy;
292 const u16 max_ll_items;
293 const bool shadow_ram_support;
294 u16 led_compensation;
295 const bool broken_powersave;
296 int chain_noise_num_beacons;
297 const bool supports_idle;
298 bool adv_thermal_throttle;
299 bool support_ct_kill_exit;
300 const bool support_wimax_coexist;
301 u8 plcp_delta_threshold;
302 s32 chain_noise_scale;
303 /* timer period for monitor the driver queues */
304 u32 monitor_recover_period;
305 bool temperature_kelvin;
306 u32 max_event_log_size;
307 const bool tx_power_by_driver;
308 const bool ucode_tracing;
309 const bool sensitivity_calib_by_driver;
310 const bool chain_noise_calib_by_driver;
311};
312/*
285 * @advanced_bt_coexist: support advanced bt coexist 313 * @advanced_bt_coexist: support advanced bt coexist
286 * @bt_init_traffic_load: specify initial bt traffic load 314 * @bt_init_traffic_load: specify initial bt traffic load
287 * @bt_prio_boost: default bt priority boost value 315 * @bt_prio_boost: default bt priority boost value
288 * @need_dc_calib: need to perform init dc calibration
289 * @bt_statistics: use BT version of statistics notification 316 * @bt_statistics: use BT version of statistics notification
290 * @agg_time_limit: maximum number of uSec in aggregation 317 * @agg_time_limit: maximum number of uSec in aggregation
291 * @ampdu_factor: Maximum A-MPDU length factor 318 * @ampdu_factor: Maximum A-MPDU length factor
292 * @ampdu_density: Minimum A-MPDU spacing 319 * @ampdu_density: Minimum A-MPDU spacing
320*/
321struct iwl_bt_params {
322 bool advanced_bt_coexist;
323 u8 bt_init_traffic_load;
324 u8 bt_prio_boost;
325 const bool bt_statistics;
326 u16 agg_time_limit;
327 u8 ampdu_factor;
328 u8 ampdu_density;
329};
330/*
331 * @use_rts_for_aggregation: use rts/cts protection for HT traffic
332*/
333struct iwl_ht_params {
334 const bool ht_greenfield_support; /* if used set to true */
335 bool use_rts_for_aggregation;
336};
337
338/**
339 * struct iwl_cfg
340 * @fw_name_pre: Firmware filename prefix. The api version and extension
341 * (.ucode) will be added to filename before loading from disk. The
342 * filename is constructed as fw_name_pre<api>.ucode.
343 * @ucode_api_max: Highest version of uCode API supported by driver.
344 * @ucode_api_min: Lowest version of uCode API supported by driver.
345 * @pa_type: used by 6000 series only to identify the type of Power Amplifier
346 * @need_dc_calib: need to perform init dc calibration
347 * @scan_antennas: available antenna for scan operation
293 * 348 *
294 * We enable the driver to be backward compatible wrt API version. The 349 * We enable the driver to be backward compatible wrt API version. The
295 * driver specifies which APIs it supports (with @ucode_api_max being the 350 * driver specifies which APIs it supports (with @ucode_api_max being the
@@ -300,9 +355,9 @@ struct iwl_mod_params {
300 * 355 *
301 * For example, 356 * For example,
302 * if (IWL_UCODE_API(priv->ucode_ver) >= 2) { 357 * if (IWL_UCODE_API(priv->ucode_ver) >= 2) {
303 * Driver interacts with Firmware API version >= 2. 358 * Driver interacts with Firmware API version >= 2.
304 * } else { 359 * } else {
305 * Driver interacts with Firmware API version 1. 360 * Driver interacts with Firmware API version 1.
306 * } 361 * }
307 * 362 *
308 * The ideal usage of this infrastructure is to treat a new ucode API 363 * The ideal usage of this infrastructure is to treat a new ucode API
@@ -313,59 +368,28 @@ struct iwl_mod_params {
313 * 368 *
314 */ 369 */
315struct iwl_cfg { 370struct iwl_cfg {
371 /* params specific to an individual device within a device family */
316 const char *name; 372 const char *name;
317 const char *fw_name_pre; 373 const char *fw_name_pre;
318 const unsigned int ucode_api_max; 374 const unsigned int ucode_api_max;
319 const unsigned int ucode_api_min; 375 const unsigned int ucode_api_min;
376 u8 valid_tx_ant;
377 u8 valid_rx_ant;
320 unsigned int sku; 378 unsigned int sku;
321 int eeprom_size;
322 u16 eeprom_ver; 379 u16 eeprom_ver;
323 u16 eeprom_calib_ver; 380 u16 eeprom_calib_ver;
324 int num_of_queues; /* def: HW dependent */
325 int num_of_ampdu_queues;/* def: HW dependent */
326 const struct iwl_ops *ops; 381 const struct iwl_ops *ops;
382 /* module based parameters which can be set from modprobe cmd */
327 const struct iwl_mod_params *mod_params; 383 const struct iwl_mod_params *mod_params;
328 u8 valid_tx_ant; 384 /* params not likely to change within a device family */
329 u8 valid_rx_ant; 385 struct iwl_base_params *base_params;
330 386 /* params likely to change within a device family */
331 /* for iwl_apm_init() */ 387 struct iwl_ht_params *ht_params;
332 u32 pll_cfg_val; 388 struct iwl_bt_params *bt_params;
333 bool set_l0s; 389 enum iwl_pa_type pa_type; /* if used set to IWL_PA_SYSTEM */
334 bool use_bsm; 390 const bool need_dc_calib; /* if used set to true */
335
336 bool use_isr_legacy;
337 enum iwl_pa_type pa_type;
338 const u16 max_ll_items;
339 const bool shadow_ram_support;
340 const bool ht_greenfield_support;
341 u16 led_compensation;
342 const bool broken_powersave;
343 bool use_rts_for_aggregation;
344 int chain_noise_num_beacons;
345 const bool supports_idle;
346 bool adv_thermal_throttle;
347 bool support_ct_kill_exit;
348 const bool support_wimax_coexist;
349 u8 plcp_delta_threshold;
350 s32 chain_noise_scale;
351 /* timer period for monitor the driver queues */
352 u32 monitor_recover_period;
353 bool temperature_kelvin;
354 u32 max_event_log_size;
355 const bool tx_power_by_driver;
356 const bool ucode_tracing;
357 const bool sensitivity_calib_by_driver;
358 const bool chain_noise_calib_by_driver;
359 u8 scan_rx_antennas[IEEE80211_NUM_BANDS]; 391 u8 scan_rx_antennas[IEEE80211_NUM_BANDS];
360 u8 scan_tx_antennas[IEEE80211_NUM_BANDS]; 392 u8 scan_tx_antennas[IEEE80211_NUM_BANDS];
361 bool advanced_bt_coexist;
362 u8 bt_init_traffic_load;
363 u8 bt_prio_boost;
364 const bool need_dc_calib;
365 const bool bt_statistics;
366 u16 agg_time_limit;
367 u8 ampdu_factor;
368 u8 ampdu_density;
369}; 393};
370 394
371/*************************** 395/***************************
diff --git a/drivers/net/wireless/iwlwifi/iwl-csr.h b/drivers/net/wireless/iwlwifi/iwl-csr.h
index ecf98e7ac4e..2aa15ab1389 100644
--- a/drivers/net/wireless/iwlwifi/iwl-csr.h
+++ b/drivers/net/wireless/iwlwifi/iwl-csr.h
@@ -371,7 +371,8 @@
371#define CSR_GP_DRIVER_REG_BIT_RADIO_SKU_3x3_HYB (0x00000000) 371#define CSR_GP_DRIVER_REG_BIT_RADIO_SKU_3x3_HYB (0x00000000)
372#define CSR_GP_DRIVER_REG_BIT_RADIO_SKU_2x2_HYB (0x00000001) 372#define CSR_GP_DRIVER_REG_BIT_RADIO_SKU_2x2_HYB (0x00000001)
373#define CSR_GP_DRIVER_REG_BIT_RADIO_SKU_2x2_IPA (0x00000002) 373#define CSR_GP_DRIVER_REG_BIT_RADIO_SKU_2x2_IPA (0x00000002)
374#define CSR_GP_DRIVER_REG_BIT_CALIB_VERSION6 (0x00000004) 374#define CSR_GP_DRIVER_REG_BIT_CALIB_VERSION6 (0x00000004)
375#define CSR_GP_DRIVER_REG_BIT_6050_1x2 (0x00000008)
375 376
376/* GIO Chicken Bits (PCI Express bus link power management) */ 377/* GIO Chicken Bits (PCI Express bus link power management) */
377#define CSR_GIO_CHICKEN_BITS_REG_BIT_L1A_NO_L0S_RX (0x00800000) 378#define CSR_GIO_CHICKEN_BITS_REG_BIT_L1A_NO_L0S_RX (0x00800000)
diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
index 265ad01a443..fc340311ea0 100644
--- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
@@ -356,7 +356,7 @@ static ssize_t iwl_dbgfs_nvm_read(struct file *file,
356 const u8 *ptr; 356 const u8 *ptr;
357 char *buf; 357 char *buf;
358 u16 eeprom_ver; 358 u16 eeprom_ver;
359 size_t eeprom_len = priv->cfg->eeprom_size; 359 size_t eeprom_len = priv->cfg->base_params->eeprom_size;
360 buf_size = 4 * eeprom_len + 256; 360 buf_size = 4 * eeprom_len + 256;
361 361
362 if (eeprom_len % 16) { 362 if (eeprom_len % 16) {
@@ -872,7 +872,7 @@ static ssize_t iwl_dbgfs_traffic_log_read(struct file *file,
872 struct iwl_rx_queue *rxq = &priv->rxq; 872 struct iwl_rx_queue *rxq = &priv->rxq;
873 char *buf; 873 char *buf;
874 int bufsz = ((IWL_TRAFFIC_ENTRIES * IWL_TRAFFIC_ENTRY_SIZE * 64) * 2) + 874 int bufsz = ((IWL_TRAFFIC_ENTRIES * IWL_TRAFFIC_ENTRY_SIZE * 64) * 2) +
875 (priv->cfg->num_of_queues * 32 * 8) + 400; 875 (priv->cfg->base_params->num_of_queues * 32 * 8) + 400;
876 const u8 *ptr; 876 const u8 *ptr;
877 ssize_t ret; 877 ssize_t ret;
878 878
@@ -971,7 +971,8 @@ static ssize_t iwl_dbgfs_tx_queue_read(struct file *file,
971 int pos = 0; 971 int pos = 0;
972 int cnt; 972 int cnt;
973 int ret; 973 int ret;
974 const size_t bufsz = sizeof(char) * 64 * priv->cfg->num_of_queues; 974 const size_t bufsz = sizeof(char) * 64 *
975 priv->cfg->base_params->num_of_queues;
975 976
976 if (!priv->txq) { 977 if (!priv->txq) {
977 IWL_ERR(priv, "txq not ready\n"); 978 IWL_ERR(priv, "txq not ready\n");
@@ -1415,7 +1416,7 @@ static ssize_t iwl_dbgfs_plcp_delta_read(struct file *file,
1415 const size_t bufsz = sizeof(buf); 1416 const size_t bufsz = sizeof(buf);
1416 1417
1417 pos += scnprintf(buf + pos, bufsz - pos, "%u\n", 1418 pos += scnprintf(buf + pos, bufsz - pos, "%u\n",
1418 priv->cfg->plcp_delta_threshold); 1419 priv->cfg->base_params->plcp_delta_threshold);
1419 1420
1420 return simple_read_from_buffer(user_buf, count, ppos, buf, pos); 1421 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1421} 1422}
@@ -1437,10 +1438,10 @@ static ssize_t iwl_dbgfs_plcp_delta_write(struct file *file,
1437 return -EINVAL; 1438 return -EINVAL;
1438 if ((plcp < IWL_MAX_PLCP_ERR_THRESHOLD_MIN) || 1439 if ((plcp < IWL_MAX_PLCP_ERR_THRESHOLD_MIN) ||
1439 (plcp > IWL_MAX_PLCP_ERR_THRESHOLD_MAX)) 1440 (plcp > IWL_MAX_PLCP_ERR_THRESHOLD_MAX))
1440 priv->cfg->plcp_delta_threshold = 1441 priv->cfg->base_params->plcp_delta_threshold =
1441 IWL_MAX_PLCP_ERR_THRESHOLD_DISABLE; 1442 IWL_MAX_PLCP_ERR_THRESHOLD_DISABLE;
1442 else 1443 else
1443 priv->cfg->plcp_delta_threshold = plcp; 1444 priv->cfg->base_params->plcp_delta_threshold = plcp;
1444 return count; 1445 return count;
1445} 1446}
1446 1447
@@ -1550,13 +1551,14 @@ static ssize_t iwl_dbgfs_monitor_period_write(struct file *file,
1550 if (sscanf(buf, "%d", &period) != 1) 1551 if (sscanf(buf, "%d", &period) != 1)
1551 return -EINVAL; 1552 return -EINVAL;
1552 if (period < 0 || period > IWL_MAX_MONITORING_PERIOD) 1553 if (period < 0 || period > IWL_MAX_MONITORING_PERIOD)
1553 priv->cfg->monitor_recover_period = IWL_DEF_MONITORING_PERIOD; 1554 priv->cfg->base_params->monitor_recover_period =
1555 IWL_DEF_MONITORING_PERIOD;
1554 else 1556 else
1555 priv->cfg->monitor_recover_period = period; 1557 priv->cfg->base_params->monitor_recover_period = period;
1556 1558
1557 if (priv->cfg->monitor_recover_period) 1559 if (priv->cfg->base_params->monitor_recover_period)
1558 mod_timer(&priv->monitor_recover, jiffies + msecs_to_jiffies( 1560 mod_timer(&priv->monitor_recover, jiffies + msecs_to_jiffies(
1559 priv->cfg->monitor_recover_period)); 1561 priv->cfg->base_params->monitor_recover_period));
1560 else 1562 else
1561 del_timer_sync(&priv->monitor_recover); 1563 del_timer_sync(&priv->monitor_recover);
1562 return count; 1564 return count;
@@ -1614,9 +1616,14 @@ static ssize_t iwl_dbgfs_protection_mode_read(struct file *file,
1614 char buf[40]; 1616 char buf[40];
1615 const size_t bufsz = sizeof(buf); 1617 const size_t bufsz = sizeof(buf);
1616 1618
1617 pos += scnprintf(buf + pos, bufsz - pos, "use %s for aggregation\n", 1619 if (priv->cfg->ht_params)
1618 (priv->cfg->use_rts_for_aggregation) ? "rts/cts" : 1620 pos += scnprintf(buf + pos, bufsz - pos,
1619 "cts-to-self"); 1621 "use %s for aggregation\n",
1622 (priv->cfg->ht_params->use_rts_for_aggregation) ?
1623 "rts/cts" : "cts-to-self");
1624 else
1625 pos += scnprintf(buf + pos, bufsz - pos, "N/A");
1626
1620 return simple_read_from_buffer(user_buf, count, ppos, buf, pos); 1627 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1621} 1628}
1622 1629
@@ -1629,6 +1636,9 @@ static ssize_t iwl_dbgfs_protection_mode_write(struct file *file,
1629 int buf_size; 1636 int buf_size;
1630 int rts; 1637 int rts;
1631 1638
1639 if (!priv->cfg->ht_params)
1640 return -EINVAL;
1641
1632 memset(buf, 0, sizeof(buf)); 1642 memset(buf, 0, sizeof(buf));
1633 buf_size = min(count, sizeof(buf) - 1); 1643 buf_size = min(count, sizeof(buf) - 1);
1634 if (copy_from_user(buf, user_buf, buf_size)) 1644 if (copy_from_user(buf, user_buf, buf_size))
@@ -1636,9 +1646,9 @@ static ssize_t iwl_dbgfs_protection_mode_write(struct file *file,
1636 if (sscanf(buf, "%d", &rts) != 1) 1646 if (sscanf(buf, "%d", &rts) != 1)
1637 return -EINVAL; 1647 return -EINVAL;
1638 if (rts) 1648 if (rts)
1639 priv->cfg->use_rts_for_aggregation = true; 1649 priv->cfg->ht_params->use_rts_for_aggregation = true;
1640 else 1650 else
1641 priv->cfg->use_rts_for_aggregation = false; 1651 priv->cfg->ht_params->use_rts_for_aggregation = false;
1642 return count; 1652 return count;
1643} 1653}
1644 1654
@@ -1716,7 +1726,7 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name)
1716 DEBUGFS_ADD_FILE(interrupt, dir_data, S_IWUSR | S_IRUSR); 1726 DEBUGFS_ADD_FILE(interrupt, dir_data, S_IWUSR | S_IRUSR);
1717 DEBUGFS_ADD_FILE(qos, dir_data, S_IRUSR); 1727 DEBUGFS_ADD_FILE(qos, dir_data, S_IRUSR);
1718 DEBUGFS_ADD_FILE(led, dir_data, S_IRUSR); 1728 DEBUGFS_ADD_FILE(led, dir_data, S_IRUSR);
1719 if (!priv->cfg->broken_powersave) { 1729 if (!priv->cfg->base_params->broken_powersave) {
1720 DEBUGFS_ADD_FILE(sleep_level_override, dir_data, 1730 DEBUGFS_ADD_FILE(sleep_level_override, dir_data,
1721 S_IWUSR | S_IRUSR); 1731 S_IWUSR | S_IRUSR);
1722 DEBUGFS_ADD_FILE(current_sleep_command, dir_data, S_IRUSR); 1732 DEBUGFS_ADD_FILE(current_sleep_command, dir_data, S_IRUSR);
@@ -1743,27 +1753,27 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name)
1743 DEBUGFS_ADD_FILE(txfifo_flush, dir_debug, S_IWUSR); 1753 DEBUGFS_ADD_FILE(txfifo_flush, dir_debug, S_IWUSR);
1744 DEBUGFS_ADD_FILE(protection_mode, dir_debug, S_IWUSR | S_IRUSR); 1754 DEBUGFS_ADD_FILE(protection_mode, dir_debug, S_IWUSR | S_IRUSR);
1745 1755
1746 if (priv->cfg->sensitivity_calib_by_driver) 1756 if (priv->cfg->base_params->sensitivity_calib_by_driver)
1747 DEBUGFS_ADD_FILE(sensitivity, dir_debug, S_IRUSR); 1757 DEBUGFS_ADD_FILE(sensitivity, dir_debug, S_IRUSR);
1748 if (priv->cfg->chain_noise_calib_by_driver) 1758 if (priv->cfg->base_params->chain_noise_calib_by_driver)
1749 DEBUGFS_ADD_FILE(chain_noise, dir_debug, S_IRUSR); 1759 DEBUGFS_ADD_FILE(chain_noise, dir_debug, S_IRUSR);
1750 if (priv->cfg->ucode_tracing) 1760 if (priv->cfg->base_params->ucode_tracing)
1751 DEBUGFS_ADD_FILE(ucode_tracing, dir_debug, S_IWUSR | S_IRUSR); 1761 DEBUGFS_ADD_FILE(ucode_tracing, dir_debug, S_IWUSR | S_IRUSR);
1752 if (priv->cfg->bt_statistics) 1762 if (priv->cfg->bt_params && priv->cfg->bt_params->bt_statistics)
1753 DEBUGFS_ADD_FILE(ucode_bt_stats, dir_debug, S_IRUSR); 1763 DEBUGFS_ADD_FILE(ucode_bt_stats, dir_debug, S_IRUSR);
1754 DEBUGFS_ADD_FILE(reply_tx_error, dir_debug, S_IRUSR); 1764 DEBUGFS_ADD_FILE(reply_tx_error, dir_debug, S_IRUSR);
1755 DEBUGFS_ADD_FILE(rxon_flags, dir_debug, S_IWUSR); 1765 DEBUGFS_ADD_FILE(rxon_flags, dir_debug, S_IWUSR);
1756 DEBUGFS_ADD_FILE(rxon_filter_flags, dir_debug, S_IWUSR); 1766 DEBUGFS_ADD_FILE(rxon_filter_flags, dir_debug, S_IWUSR);
1757 DEBUGFS_ADD_FILE(monitor_period, dir_debug, S_IWUSR); 1767 DEBUGFS_ADD_FILE(monitor_period, dir_debug, S_IWUSR);
1758 if (priv->cfg->advanced_bt_coexist) 1768 if (priv->cfg->bt_params && priv->cfg->bt_params->advanced_bt_coexist)
1759 DEBUGFS_ADD_FILE(bt_traffic, dir_debug, S_IRUSR); 1769 DEBUGFS_ADD_FILE(bt_traffic, dir_debug, S_IRUSR);
1760 if (priv->cfg->sensitivity_calib_by_driver) 1770 if (priv->cfg->base_params->sensitivity_calib_by_driver)
1761 DEBUGFS_ADD_BOOL(disable_sensitivity, dir_rf, 1771 DEBUGFS_ADD_BOOL(disable_sensitivity, dir_rf,
1762 &priv->disable_sens_cal); 1772 &priv->disable_sens_cal);
1763 if (priv->cfg->chain_noise_calib_by_driver) 1773 if (priv->cfg->base_params->chain_noise_calib_by_driver)
1764 DEBUGFS_ADD_BOOL(disable_chain_noise, dir_rf, 1774 DEBUGFS_ADD_BOOL(disable_chain_noise, dir_rf,
1765 &priv->disable_chain_noise_cal); 1775 &priv->disable_chain_noise_cal);
1766 if (priv->cfg->tx_power_by_driver) 1776 if (priv->cfg->base_params->tx_power_by_driver)
1767 DEBUGFS_ADD_BOOL(disable_tx_power, dir_rf, 1777 DEBUGFS_ADD_BOOL(disable_tx_power, dir_rf,
1768 &priv->disable_tx_power_cal); 1778 &priv->disable_tx_power_cal);
1769 return 0; 1779 return 0;
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index 74d25bcbfcb..90a37a94c69 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -684,6 +684,7 @@ struct iwl_sensitivity_ranges {
684 * @ct_kill_threshold: temperature threshold 684 * @ct_kill_threshold: temperature threshold
685 * @beacon_time_tsf_bits: number of valid tsf bits for beacon time 685 * @beacon_time_tsf_bits: number of valid tsf bits for beacon time
686 * @calib_init_cfg: setup initial calibrations for the hw 686 * @calib_init_cfg: setup initial calibrations for the hw
687 * @calib_rt_cfg: setup runtime calibrations for the hw
687 * @struct iwl_sensitivity_ranges: range of sensitivity values 688 * @struct iwl_sensitivity_ranges: range of sensitivity values
688 */ 689 */
689struct iwl_hw_params { 690struct iwl_hw_params {
@@ -710,6 +711,7 @@ struct iwl_hw_params {
710 /* for 1000, 6000 series and up */ 711 /* for 1000, 6000 series and up */
711 u16 beacon_time_tsf_bits; 712 u16 beacon_time_tsf_bits;
712 u32 calib_init_cfg; 713 u32 calib_init_cfg;
714 u32 calib_rt_cfg;
713 const struct iwl_sensitivity_ranges *sens; 715 const struct iwl_sensitivity_ranges *sens;
714}; 716};
715 717
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-eeprom.c
index a45d02e555c..88f4a80d473 100644
--- a/drivers/net/wireless/iwlwifi/iwl-eeprom.c
+++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.c
@@ -332,7 +332,7 @@ EXPORT_SYMBOL(iwlcore_eeprom_release_semaphore);
332 332
333const u8 *iwlcore_eeprom_query_addr(const struct iwl_priv *priv, size_t offset) 333const u8 *iwlcore_eeprom_query_addr(const struct iwl_priv *priv, size_t offset)
334{ 334{
335 BUG_ON(offset >= priv->cfg->eeprom_size); 335 BUG_ON(offset >= priv->cfg->base_params->eeprom_size);
336 return &priv->eeprom[offset]; 336 return &priv->eeprom[offset];
337} 337}
338EXPORT_SYMBOL(iwlcore_eeprom_query_addr); 338EXPORT_SYMBOL(iwlcore_eeprom_query_addr);
@@ -364,7 +364,7 @@ static int iwl_init_otp_access(struct iwl_priv *priv)
364 * CSR auto clock gate disable bit - 364 * CSR auto clock gate disable bit -
365 * this is only applicable for HW with OTP shadow RAM 365 * this is only applicable for HW with OTP shadow RAM
366 */ 366 */
367 if (priv->cfg->shadow_ram_support) 367 if (priv->cfg->base_params->shadow_ram_support)
368 iwl_set_bit(priv, CSR_DBG_LINK_PWR_MGMT_REG, 368 iwl_set_bit(priv, CSR_DBG_LINK_PWR_MGMT_REG,
369 CSR_RESET_LINK_PWR_MGMT_DISABLED); 369 CSR_RESET_LINK_PWR_MGMT_DISABLED);
370 } 370 }
@@ -484,7 +484,7 @@ static int iwl_find_otp_image(struct iwl_priv *priv,
484 } 484 }
485 /* more in the link list, continue */ 485 /* more in the link list, continue */
486 usedblocks++; 486 usedblocks++;
487 } while (usedblocks <= priv->cfg->max_ll_items); 487 } while (usedblocks <= priv->cfg->base_params->max_ll_items);
488 488
489 /* OTP has no valid blocks */ 489 /* OTP has no valid blocks */
490 IWL_DEBUG_INFO(priv, "OTP has no valid blocks\n"); 490 IWL_DEBUG_INFO(priv, "OTP has no valid blocks\n");
@@ -512,8 +512,8 @@ int iwl_eeprom_init(struct iwl_priv *priv)
512 if (priv->nvm_device_type == -ENOENT) 512 if (priv->nvm_device_type == -ENOENT)
513 return -ENOENT; 513 return -ENOENT;
514 /* allocate eeprom */ 514 /* allocate eeprom */
515 IWL_DEBUG_INFO(priv, "NVM size = %d\n", priv->cfg->eeprom_size); 515 sz = priv->cfg->base_params->eeprom_size;
516 sz = priv->cfg->eeprom_size; 516 IWL_DEBUG_INFO(priv, "NVM size = %d\n", sz);
517 priv->eeprom = kzalloc(sz, GFP_KERNEL); 517 priv->eeprom = kzalloc(sz, GFP_KERNEL);
518 if (!priv->eeprom) { 518 if (!priv->eeprom) {
519 ret = -ENOMEM; 519 ret = -ENOMEM;
@@ -554,7 +554,7 @@ int iwl_eeprom_init(struct iwl_priv *priv)
554 CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK | 554 CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK |
555 CSR_OTP_GP_REG_ECC_UNCORR_STATUS_MSK); 555 CSR_OTP_GP_REG_ECC_UNCORR_STATUS_MSK);
556 /* traversing the linked list if no shadow ram supported */ 556 /* traversing the linked list if no shadow ram supported */
557 if (!priv->cfg->shadow_ram_support) { 557 if (!priv->cfg->base_params->shadow_ram_support) {
558 if (iwl_find_otp_image(priv, &validblockaddr)) { 558 if (iwl_find_otp_image(priv, &validblockaddr)) {
559 ret = -ENOENT; 559 ret = -ENOENT;
560 goto done; 560 goto done;
diff --git a/drivers/net/wireless/iwlwifi/iwl-led.c b/drivers/net/wireless/iwlwifi/iwl-led.c
index db5bfcb036c..86c2b6fed0c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-led.c
+++ b/drivers/net/wireless/iwlwifi/iwl-led.c
@@ -108,13 +108,13 @@ static int iwl_led_pattern(struct iwl_priv *priv, unsigned int idx)
108 BUG_ON(idx > IWL_MAX_BLINK_TBL); 108 BUG_ON(idx > IWL_MAX_BLINK_TBL);
109 109
110 IWL_DEBUG_LED(priv, "Led blink time compensation= %u\n", 110 IWL_DEBUG_LED(priv, "Led blink time compensation= %u\n",
111 priv->cfg->led_compensation); 111 priv->cfg->base_params->led_compensation);
112 led_cmd.on = 112 led_cmd.on =
113 iwl_blink_compensation(priv, blink_tbl[idx].on_time, 113 iwl_blink_compensation(priv, blink_tbl[idx].on_time,
114 priv->cfg->led_compensation); 114 priv->cfg->base_params->led_compensation);
115 led_cmd.off = 115 led_cmd.off =
116 iwl_blink_compensation(priv, blink_tbl[idx].off_time, 116 iwl_blink_compensation(priv, blink_tbl[idx].off_time,
117 priv->cfg->led_compensation); 117 priv->cfg->base_params->led_compensation);
118 118
119 return priv->cfg->ops->led->cmd(priv, &led_cmd); 119 return priv->cfg->ops->led->cmd(priv, &led_cmd);
120} 120}
diff --git a/drivers/net/wireless/iwlwifi/iwl-power.c b/drivers/net/wireless/iwlwifi/iwl-power.c
index 63c0ab46261..49d7788937a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-power.c
+++ b/drivers/net/wireless/iwlwifi/iwl-power.c
@@ -278,9 +278,9 @@ int iwl_power_update_mode(struct iwl_priv *priv, bool force)
278 278
279 dtimper = priv->hw->conf.ps_dtim_period ?: 1; 279 dtimper = priv->hw->conf.ps_dtim_period ?: 1;
280 280
281 if (priv->cfg->broken_powersave) 281 if (priv->cfg->base_params->broken_powersave)
282 iwl_power_sleep_cam_cmd(priv, &cmd); 282 iwl_power_sleep_cam_cmd(priv, &cmd);
283 else if (priv->cfg->supports_idle && 283 else if (priv->cfg->base_params->supports_idle &&
284 priv->hw->conf.flags & IEEE80211_CONF_IDLE) 284 priv->hw->conf.flags & IEEE80211_CONF_IDLE)
285 iwl_static_sleep_cmd(priv, &cmd, IWL_POWER_INDEX_5, 20); 285 iwl_static_sleep_cmd(priv, &cmd, IWL_POWER_INDEX_5, 20);
286 else if (priv->cfg->ops->lib->tt_ops.lower_power_detection && 286 else if (priv->cfg->ops->lib->tt_ops.lower_power_detection &&
diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c
index c54c20023e7..eaae49ee0c6 100644
--- a/drivers/net/wireless/iwlwifi/iwl-scan.c
+++ b/drivers/net/wireless/iwlwifi/iwl-scan.c
@@ -259,7 +259,8 @@ static void iwl_rx_scan_complete_notif(struct iwl_priv *priv,
259 queue_work(priv->workqueue, &priv->scan_completed); 259 queue_work(priv->workqueue, &priv->scan_completed);
260 260
261 if (priv->iw_mode != NL80211_IFTYPE_ADHOC && 261 if (priv->iw_mode != NL80211_IFTYPE_ADHOC &&
262 priv->cfg->advanced_bt_coexist && 262 priv->cfg->bt_params &&
263 priv->cfg->bt_params->advanced_bt_coexist &&
263 priv->bt_status != scan_notif->bt_status) { 264 priv->bt_status != scan_notif->bt_status) {
264 if (scan_notif->bt_status) { 265 if (scan_notif->bt_status) {
265 /* BT on */ 266 /* BT on */
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index 116777122a7..43db5f38e3e 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -1581,16 +1581,16 @@ int iwl3945_dump_nic_event_log(struct iwl_priv *priv, bool full_log,
1581 num_wraps = iwl_read_targ_mem(priv, base + (2 * sizeof(u32))); 1581 num_wraps = iwl_read_targ_mem(priv, base + (2 * sizeof(u32)));
1582 next_entry = iwl_read_targ_mem(priv, base + (3 * sizeof(u32))); 1582 next_entry = iwl_read_targ_mem(priv, base + (3 * sizeof(u32)));
1583 1583
1584 if (capacity > priv->cfg->max_event_log_size) { 1584 if (capacity > priv->cfg->base_params->max_event_log_size) {
1585 IWL_ERR(priv, "Log capacity %d is bogus, limit to %d entries\n", 1585 IWL_ERR(priv, "Log capacity %d is bogus, limit to %d entries\n",
1586 capacity, priv->cfg->max_event_log_size); 1586 capacity, priv->cfg->base_params->max_event_log_size);
1587 capacity = priv->cfg->max_event_log_size; 1587 capacity = priv->cfg->base_params->max_event_log_size;
1588 } 1588 }
1589 1589
1590 if (next_entry > priv->cfg->max_event_log_size) { 1590 if (next_entry > priv->cfg->base_params->max_event_log_size) {
1591 IWL_ERR(priv, "Log write index %d is bogus, limit to %d\n", 1591 IWL_ERR(priv, "Log write index %d is bogus, limit to %d\n",
1592 next_entry, priv->cfg->max_event_log_size); 1592 next_entry, priv->cfg->base_params->max_event_log_size);
1593 next_entry = priv->cfg->max_event_log_size; 1593 next_entry = priv->cfg->base_params->max_event_log_size;
1594 } 1594 }
1595 1595
1596 size = num_wraps ? capacity : next_entry; 1596 size = num_wraps ? capacity : next_entry;
@@ -2519,7 +2519,8 @@ static void iwl3945_alive_start(struct iwl_priv *priv)
2519 /* Enable timer to monitor the driver queues */ 2519 /* Enable timer to monitor the driver queues */
2520 mod_timer(&priv->monitor_recover, 2520 mod_timer(&priv->monitor_recover,
2521 jiffies + 2521 jiffies +
2522 msecs_to_jiffies(priv->cfg->monitor_recover_period)); 2522 msecs_to_jiffies(
2523 priv->cfg->base_params->monitor_recover_period));
2523 } 2524 }
2524 2525
2525 if (iwl_is_rfkill(priv)) 2526 if (iwl_is_rfkill(priv))
@@ -3881,7 +3882,7 @@ static int iwl3945_setup_mac(struct iwl_priv *priv)
3881 hw->flags = IEEE80211_HW_SIGNAL_DBM | 3882 hw->flags = IEEE80211_HW_SIGNAL_DBM |
3882 IEEE80211_HW_SPECTRUM_MGMT; 3883 IEEE80211_HW_SPECTRUM_MGMT;
3883 3884
3884 if (!priv->cfg->broken_powersave) 3885 if (!priv->cfg->base_params->broken_powersave)
3885 hw->flags |= IEEE80211_HW_SUPPORTS_PS | 3886 hw->flags |= IEEE80211_HW_SUPPORTS_PS |
3886 IEEE80211_HW_SUPPORTS_DYNAMIC_PS; 3887 IEEE80211_HW_SUPPORTS_DYNAMIC_PS;
3887 3888
@@ -3966,7 +3967,7 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
3966 * "the hard way", rather than using device's scan. 3967 * "the hard way", rather than using device's scan.
3967 */ 3968 */
3968 if (iwl3945_mod_params.disable_hw_scan) { 3969 if (iwl3945_mod_params.disable_hw_scan) {
3969 IWL_DEBUG_INFO(priv, "Disabling hw_scan\n"); 3970 IWL_ERR(priv, "sw scan support is deprecated\n");
3970 iwl3945_hw_ops.hw_scan = NULL; 3971 iwl3945_hw_ops.hw_scan = NULL;
3971 } 3972 }
3972 3973
@@ -4291,7 +4292,8 @@ MODULE_PARM_DESC(debug, "debug output mask");
4291#endif 4292#endif
4292module_param_named(disable_hw_scan, iwl3945_mod_params.disable_hw_scan, 4293module_param_named(disable_hw_scan, iwl3945_mod_params.disable_hw_scan,
4293 int, S_IRUGO); 4294 int, S_IRUGO);
4294MODULE_PARM_DESC(disable_hw_scan, "disable hardware scanning (default 0)"); 4295MODULE_PARM_DESC(disable_hw_scan,
4296 "disable hardware scanning (default 0) (deprecated)");
4295module_param_named(fw_restart3945, iwl3945_mod_params.restart_fw, int, S_IRUGO); 4297module_param_named(fw_restart3945, iwl3945_mod_params.restart_fw, int, S_IRUGO);
4296MODULE_PARM_DESC(fw_restart3945, "restart firmware in case of error"); 4298MODULE_PARM_DESC(fw_restart3945, "restart firmware in case of error");
4297 4299
diff --git a/drivers/net/wireless/iwmc3200wifi/cfg80211.c b/drivers/net/wireless/iwmc3200wifi/cfg80211.c
index 60619678f4e..c6c0eff9b5e 100644
--- a/drivers/net/wireless/iwmc3200wifi/cfg80211.c
+++ b/drivers/net/wireless/iwmc3200wifi/cfg80211.c
@@ -161,7 +161,7 @@ static int iwm_key_init(struct iwm_key *key, u8 key_index,
161} 161}
162 162
163static int iwm_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev, 163static int iwm_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
164 u8 key_index, const u8 *mac_addr, 164 u8 key_index, bool pairwise, const u8 *mac_addr,
165 struct key_params *params) 165 struct key_params *params)
166{ 166{
167 struct iwm_priv *iwm = ndev_to_iwm(ndev); 167 struct iwm_priv *iwm = ndev_to_iwm(ndev);
@@ -181,7 +181,8 @@ static int iwm_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
181} 181}
182 182
183static int iwm_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev, 183static int iwm_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev,
184 u8 key_index, const u8 *mac_addr, void *cookie, 184 u8 key_index, bool pairwise, const u8 *mac_addr,
185 void *cookie,
185 void (*callback)(void *cookie, 186 void (*callback)(void *cookie,
186 struct key_params*)) 187 struct key_params*))
187{ 188{
@@ -206,7 +207,7 @@ static int iwm_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev,
206 207
207 208
208static int iwm_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev, 209static int iwm_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev,
209 u8 key_index, const u8 *mac_addr) 210 u8 key_index, bool pairwise, const u8 *mac_addr)
210{ 211{
211 struct iwm_priv *iwm = ndev_to_iwm(ndev); 212 struct iwm_priv *iwm = ndev_to_iwm(ndev);
212 struct iwm_key *key = &iwm->keys[key_index]; 213 struct iwm_key *key = &iwm->keys[key_index];
diff --git a/drivers/net/wireless/libertas/cfg.c b/drivers/net/wireless/libertas/cfg.c
index 1bbdb14f7d7..5046a000503 100644
--- a/drivers/net/wireless/libertas/cfg.c
+++ b/drivers/net/wireless/libertas/cfg.c
@@ -1440,7 +1440,7 @@ static int lbs_cfg_set_default_key(struct wiphy *wiphy,
1440 1440
1441 1441
1442static int lbs_cfg_add_key(struct wiphy *wiphy, struct net_device *netdev, 1442static int lbs_cfg_add_key(struct wiphy *wiphy, struct net_device *netdev,
1443 u8 idx, const u8 *mac_addr, 1443 u8 idx, bool pairwise, const u8 *mac_addr,
1444 struct key_params *params) 1444 struct key_params *params)
1445{ 1445{
1446 struct lbs_private *priv = wiphy_priv(wiphy); 1446 struct lbs_private *priv = wiphy_priv(wiphy);
@@ -1500,7 +1500,7 @@ static int lbs_cfg_add_key(struct wiphy *wiphy, struct net_device *netdev,
1500 1500
1501 1501
1502static int lbs_cfg_del_key(struct wiphy *wiphy, struct net_device *netdev, 1502static int lbs_cfg_del_key(struct wiphy *wiphy, struct net_device *netdev,
1503 u8 key_index, const u8 *mac_addr) 1503 u8 key_index, bool pairwise, const u8 *mac_addr)
1504{ 1504{
1505 1505
1506 lbs_deb_enter(LBS_DEB_CFG80211); 1506 lbs_deb_enter(LBS_DEB_CFG80211);
diff --git a/drivers/net/wireless/p54/p54usb.c b/drivers/net/wireless/p54/p54usb.c
index 063248b3506..d5bc21e5a02 100644
--- a/drivers/net/wireless/p54/p54usb.c
+++ b/drivers/net/wireless/p54/p54usb.c
@@ -33,8 +33,17 @@ MODULE_ALIAS("prism54usb");
33MODULE_FIRMWARE("isl3886usb"); 33MODULE_FIRMWARE("isl3886usb");
34MODULE_FIRMWARE("isl3887usb"); 34MODULE_FIRMWARE("isl3887usb");
35 35
36/*
37 * Note:
38 *
39 * Always update our wiki's device list (located at:
40 * http://wireless.kernel.org/en/users/Drivers/p54/devices ),
41 * whenever you add a new device.
42 */
43
36static struct usb_device_id p54u_table[] __devinitdata = { 44static struct usb_device_id p54u_table[] __devinitdata = {
37 /* Version 1 devices (pci chip + net2280) */ 45 /* Version 1 devices (pci chip + net2280) */
46 {USB_DEVICE(0x045e, 0x00c2)}, /* Microsoft MN-710 */
38 {USB_DEVICE(0x0506, 0x0a11)}, /* 3COM 3CRWE254G72 */ 47 {USB_DEVICE(0x0506, 0x0a11)}, /* 3COM 3CRWE254G72 */
39 {USB_DEVICE(0x06b9, 0x0120)}, /* Thomson SpeedTouch 120g */ 48 {USB_DEVICE(0x06b9, 0x0120)}, /* Thomson SpeedTouch 120g */
40 {USB_DEVICE(0x0707, 0xee06)}, /* SMC 2862W-G */ 49 {USB_DEVICE(0x0707, 0xee06)}, /* SMC 2862W-G */
@@ -47,7 +56,9 @@ static struct usb_device_id p54u_table[] __devinitdata = {
47 {USB_DEVICE(0x0846, 0x4220)}, /* Netgear WG111 */ 56 {USB_DEVICE(0x0846, 0x4220)}, /* Netgear WG111 */
48 {USB_DEVICE(0x09aa, 0x1000)}, /* Spinnaker Proto board */ 57 {USB_DEVICE(0x09aa, 0x1000)}, /* Spinnaker Proto board */
49 {USB_DEVICE(0x0cde, 0x0006)}, /* Medion 40900, Roper Europe */ 58 {USB_DEVICE(0x0cde, 0x0006)}, /* Medion 40900, Roper Europe */
59 {USB_DEVICE(0x107b, 0x55f2)}, /* Gateway WGU-210 (Gemtek) */
50 {USB_DEVICE(0x124a, 0x4023)}, /* Shuttle PN15, Airvast WM168g, IOGear GWU513 */ 60 {USB_DEVICE(0x124a, 0x4023)}, /* Shuttle PN15, Airvast WM168g, IOGear GWU513 */
61 {USB_DEVICE(0x1630, 0x0005)}, /* 2Wire 802.11g USB (v1) / Z-Com */
51 {USB_DEVICE(0x1915, 0x2234)}, /* Linksys WUSB54G OEM */ 62 {USB_DEVICE(0x1915, 0x2234)}, /* Linksys WUSB54G OEM */
52 {USB_DEVICE(0x1915, 0x2235)}, /* Linksys WUSB54G Portable OEM */ 63 {USB_DEVICE(0x1915, 0x2235)}, /* Linksys WUSB54G Portable OEM */
53 {USB_DEVICE(0x2001, 0x3701)}, /* DLink DWL-G120 Spinnaker */ 64 {USB_DEVICE(0x2001, 0x3701)}, /* DLink DWL-G120 Spinnaker */
@@ -60,6 +71,7 @@ static struct usb_device_id p54u_table[] __devinitdata = {
60 {USB_DEVICE(0x050d, 0x7050)}, /* Belkin F5D7050 ver 1000 */ 71 {USB_DEVICE(0x050d, 0x7050)}, /* Belkin F5D7050 ver 1000 */
61 {USB_DEVICE(0x0572, 0x2000)}, /* Cohiba Proto board */ 72 {USB_DEVICE(0x0572, 0x2000)}, /* Cohiba Proto board */
62 {USB_DEVICE(0x0572, 0x2002)}, /* Cohiba Proto board */ 73 {USB_DEVICE(0x0572, 0x2002)}, /* Cohiba Proto board */
74 {USB_DEVICE(0x06a9, 0x000e)}, /* Westell 802.11g USB (A90-211WG-01) */
63 {USB_DEVICE(0x06b9, 0x0121)}, /* Thomson SpeedTouch 121g */ 75 {USB_DEVICE(0x06b9, 0x0121)}, /* Thomson SpeedTouch 121g */
64 {USB_DEVICE(0x0707, 0xee13)}, /* SMC 2862W-G version 2 */ 76 {USB_DEVICE(0x0707, 0xee13)}, /* SMC 2862W-G version 2 */
65 {USB_DEVICE(0x083a, 0x4521)}, /* Siemens Gigaset USB Adapter 54 version 2 */ 77 {USB_DEVICE(0x083a, 0x4521)}, /* Siemens Gigaset USB Adapter 54 version 2 */
@@ -80,6 +92,7 @@ static struct usb_device_id p54u_table[] __devinitdata = {
80 {USB_DEVICE(0x13B1, 0x000C)}, /* Linksys WUSB54AG */ 92 {USB_DEVICE(0x13B1, 0x000C)}, /* Linksys WUSB54AG */
81 {USB_DEVICE(0x1413, 0x5400)}, /* Telsey 802.11g USB2.0 Adapter */ 93 {USB_DEVICE(0x1413, 0x5400)}, /* Telsey 802.11g USB2.0 Adapter */
82 {USB_DEVICE(0x1435, 0x0427)}, /* Inventel UR054G */ 94 {USB_DEVICE(0x1435, 0x0427)}, /* Inventel UR054G */
95 {USB_DEVICE(0x1668, 0x1050)}, /* Actiontec 802UIG-1 */
83 {USB_DEVICE(0x2001, 0x3704)}, /* DLink DWL-G122 rev A2 */ 96 {USB_DEVICE(0x2001, 0x3704)}, /* DLink DWL-G122 rev A2 */
84 {USB_DEVICE(0x413c, 0x5513)}, /* Dell WLA3310 USB Wireless Adapter */ 97 {USB_DEVICE(0x413c, 0x5513)}, /* Dell WLA3310 USB Wireless Adapter */
85 {USB_DEVICE(0x413c, 0x8102)}, /* Spinnaker DUT */ 98 {USB_DEVICE(0x413c, 0x8102)}, /* Spinnaker DUT */
diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c
index 719573bbbf8..71b5971da59 100644
--- a/drivers/net/wireless/rndis_wlan.c
+++ b/drivers/net/wireless/rndis_wlan.c
@@ -540,11 +540,11 @@ static int rndis_set_channel(struct wiphy *wiphy, struct net_device *dev,
540 struct ieee80211_channel *chan, enum nl80211_channel_type channel_type); 540 struct ieee80211_channel *chan, enum nl80211_channel_type channel_type);
541 541
542static int rndis_add_key(struct wiphy *wiphy, struct net_device *netdev, 542static int rndis_add_key(struct wiphy *wiphy, struct net_device *netdev,
543 u8 key_index, const u8 *mac_addr, 543 u8 key_index, bool pairwise, const u8 *mac_addr,
544 struct key_params *params); 544 struct key_params *params);
545 545
546static int rndis_del_key(struct wiphy *wiphy, struct net_device *netdev, 546static int rndis_del_key(struct wiphy *wiphy, struct net_device *netdev,
547 u8 key_index, const u8 *mac_addr); 547 u8 key_index, bool pairwise, const u8 *mac_addr);
548 548
549static int rndis_set_default_key(struct wiphy *wiphy, struct net_device *netdev, 549static int rndis_set_default_key(struct wiphy *wiphy, struct net_device *netdev,
550 u8 key_index); 550 u8 key_index);
@@ -2308,8 +2308,8 @@ static int rndis_set_channel(struct wiphy *wiphy, struct net_device *netdev,
2308} 2308}
2309 2309
2310static int rndis_add_key(struct wiphy *wiphy, struct net_device *netdev, 2310static int rndis_add_key(struct wiphy *wiphy, struct net_device *netdev,
2311 u8 key_index, const u8 *mac_addr, 2311 u8 key_index, bool pairwise, const u8 *mac_addr,
2312 struct key_params *params) 2312 struct key_params *params)
2313{ 2313{
2314 struct rndis_wlan_private *priv = wiphy_priv(wiphy); 2314 struct rndis_wlan_private *priv = wiphy_priv(wiphy);
2315 struct usbnet *usbdev = priv->usbdev; 2315 struct usbnet *usbdev = priv->usbdev;
@@ -2344,7 +2344,7 @@ static int rndis_add_key(struct wiphy *wiphy, struct net_device *netdev,
2344} 2344}
2345 2345
2346static int rndis_del_key(struct wiphy *wiphy, struct net_device *netdev, 2346static int rndis_del_key(struct wiphy *wiphy, struct net_device *netdev,
2347 u8 key_index, const u8 *mac_addr) 2347 u8 key_index, bool pairwise, const u8 *mac_addr)
2348{ 2348{
2349 struct rndis_wlan_private *priv = wiphy_priv(wiphy); 2349 struct rndis_wlan_private *priv = wiphy_priv(wiphy);
2350 struct usbnet *usbdev = priv->usbdev; 2350 struct usbnet *usbdev = priv->usbdev;
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c
index 6e94356265b..93e44c7f3a7 100644
--- a/drivers/net/wireless/rt2x00/rt2500usb.c
+++ b/drivers/net/wireless/rt2x00/rt2500usb.c
@@ -1674,10 +1674,15 @@ static int rt2500usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
1674 1674
1675 /* 1675 /*
1676 * Initialize all hw fields. 1676 * Initialize all hw fields.
1677 *
1678 * Don't set IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING unless we are
1679 * capable of sending the buffered frames out after the DTIM
1680 * transmission using rt2x00lib_beacondone. This will send out
1681 * multicast and broadcast traffic immediately instead of buffering it
1682 * infinitly and thus dropping it after some time.
1677 */ 1683 */
1678 rt2x00dev->hw->flags = 1684 rt2x00dev->hw->flags =
1679 IEEE80211_HW_RX_INCLUDES_FCS | 1685 IEEE80211_HW_RX_INCLUDES_FCS |
1680 IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
1681 IEEE80211_HW_SIGNAL_DBM | 1686 IEEE80211_HW_SIGNAL_DBM |
1682 IEEE80211_HW_SUPPORTS_PS | 1687 IEEE80211_HW_SUPPORTS_PS |
1683 IEEE80211_HW_PS_NULLFUNC_STACK; 1688 IEEE80211_HW_PS_NULLFUNC_STACK;
diff --git a/drivers/net/wireless/rt2x00/rt2800.h b/drivers/net/wireless/rt2x00/rt2800.h
index 2edc7742a7e..eb8b6cab992 100644
--- a/drivers/net/wireless/rt2x00/rt2800.h
+++ b/drivers/net/wireless/rt2x00/rt2800.h
@@ -1,5 +1,6 @@
1/* 1/*
2 Copyright (C) 2004 - 2009 Ivo van Doorn <IvDoorn@gmail.com> 2 Copyright (C) 2004 - 2010 Ivo van Doorn <IvDoorn@gmail.com>
3 Copyright (C) 2010 Willow Garage <http://www.willowgarage.com>
3 Copyright (C) 2009 Alban Browaeys <prahal@yahoo.com> 4 Copyright (C) 2009 Alban Browaeys <prahal@yahoo.com>
4 Copyright (C) 2009 Felix Fietkau <nbd@openwrt.org> 5 Copyright (C) 2009 Felix Fietkau <nbd@openwrt.org>
5 Copyright (C) 2009 Luis Correia <luis.f.correia@gmail.com> 6 Copyright (C) 2009 Luis Correia <luis.f.correia@gmail.com>
@@ -710,8 +711,14 @@
710 711
711/* 712/*
712 * TBTT_SYNC_CFG: 713 * TBTT_SYNC_CFG:
714 * BCN_AIFSN: Beacon AIFSN after TBTT interrupt in slots
715 * BCN_CWMIN: Beacon CWMin after TBTT interrupt in slots
713 */ 716 */
714#define TBTT_SYNC_CFG 0x1118 717#define TBTT_SYNC_CFG 0x1118
718#define TBTT_SYNC_CFG_TBTT_ADJUST FIELD32(0x000000ff)
719#define TBTT_SYNC_CFG_BCN_EXP_WIN FIELD32(0x0000ff00)
720#define TBTT_SYNC_CFG_BCN_AIFSN FIELD32(0x000f0000)
721#define TBTT_SYNC_CFG_BCN_CWMIN FIELD32(0x00f00000)
715 722
716/* 723/*
717 * TSF_TIMER_DW0: Local lsb TSF timer, read-only 724 * TSF_TIMER_DW0: Local lsb TSF timer, read-only
@@ -747,16 +754,21 @@
747#define INT_TIMER_EN_GP_TIMER FIELD32(0x00000002) 754#define INT_TIMER_EN_GP_TIMER FIELD32(0x00000002)
748 755
749/* 756/*
750 * CH_IDLE_STA: channel idle time 757 * CH_IDLE_STA: channel idle time (in us)
751 */ 758 */
752#define CH_IDLE_STA 0x1130 759#define CH_IDLE_STA 0x1130
753 760
754/* 761/*
755 * CH_BUSY_STA: channel busy time 762 * CH_BUSY_STA: channel busy time on primary channel (in us)
756 */ 763 */
757#define CH_BUSY_STA 0x1134 764#define CH_BUSY_STA 0x1134
758 765
759/* 766/*
767 * CH_BUSY_STA_SEC: channel busy time on secondary channel in HT40 mode (in us)
768 */
769#define CH_BUSY_STA_SEC 0x1138
770
771/*
760 * MAC_STATUS_CFG: 772 * MAC_STATUS_CFG:
761 * BBP_RF_BUSY: When set to 0, BBP and RF are stable. 773 * BBP_RF_BUSY: When set to 0, BBP and RF are stable.
762 * if 1 or higher one of the 2 registers is busy. 774 * if 1 or higher one of the 2 registers is busy.
@@ -1342,6 +1354,9 @@
1342 * PID_TYPE: The PID latched from the PID field in the TXWI, can be used 1354 * PID_TYPE: The PID latched from the PID field in the TXWI, can be used
1343 * to match a frame with its tx result (even though the PID is 1355 * to match a frame with its tx result (even though the PID is
1344 * only 4 bits wide). 1356 * only 4 bits wide).
1357 * PID_QUEUE: Part of PID_TYPE, this is the queue index number (0-3)
1358 * PID_ENTRY: Part of PID_TYPE, this is the queue entry index number (1-3)
1359 * This identification number is calculated by ((idx % 3) + 1).
1345 * TX_SUCCESS: Indicates tx success (1) or failure (0) 1360 * TX_SUCCESS: Indicates tx success (1) or failure (0)
1346 * TX_AGGRE: Indicates if the frame was part of an aggregate (1) or not (0) 1361 * TX_AGGRE: Indicates if the frame was part of an aggregate (1) or not (0)
1347 * TX_ACK_REQUIRED: Indicates if the frame needed to get ack'ed (1) or not (0) 1362 * TX_ACK_REQUIRED: Indicates if the frame needed to get ack'ed (1) or not (0)
@@ -1353,6 +1368,8 @@
1353#define TX_STA_FIFO 0x1718 1368#define TX_STA_FIFO 0x1718
1354#define TX_STA_FIFO_VALID FIELD32(0x00000001) 1369#define TX_STA_FIFO_VALID FIELD32(0x00000001)
1355#define TX_STA_FIFO_PID_TYPE FIELD32(0x0000001e) 1370#define TX_STA_FIFO_PID_TYPE FIELD32(0x0000001e)
1371#define TX_STA_FIFO_PID_QUEUE FIELD32(0x00000006)
1372#define TX_STA_FIFO_PID_ENTRY FIELD32(0x00000018)
1356#define TX_STA_FIFO_TX_SUCCESS FIELD32(0x00000020) 1373#define TX_STA_FIFO_TX_SUCCESS FIELD32(0x00000020)
1357#define TX_STA_FIFO_TX_AGGRE FIELD32(0x00000040) 1374#define TX_STA_FIFO_TX_AGGRE FIELD32(0x00000040)
1358#define TX_STA_FIFO_TX_ACK_REQUIRED FIELD32(0x00000080) 1375#define TX_STA_FIFO_TX_ACK_REQUIRED FIELD32(0x00000080)
@@ -1435,6 +1452,24 @@
1435 1452
1436/* 1453/*
1437 * Security key table memory. 1454 * Security key table memory.
1455 *
1456 * The pairwise key table shares some memory with the beacon frame
1457 * buffers 6 and 7. That basically means that when beacon 6 & 7
1458 * are used we should only use the reduced pairwise key table which
1459 * has a maximum of 222 entries.
1460 *
1461 * ---------------------------------------------
1462 * |0x4000 | Pairwise Key | Reduced Pairwise |
1463 * | | Table | Key Table |
1464 * | | Size: 256 * 32 | Size: 222 * 32 |
1465 * |0x5BC0 | |-------------------
1466 * | | | Beacon 6 |
1467 * |0x5DC0 | |-------------------
1468 * | | | Beacon 7 |
1469 * |0x5FC0 | |-------------------
1470 * |0x5FFF | |
1471 * --------------------------
1472 *
1438 * MAC_WCID_BASE: 8-bytes (use only 6 bytes) * 256 entry 1473 * MAC_WCID_BASE: 8-bytes (use only 6 bytes) * 256 entry
1439 * PAIRWISE_KEY_TABLE_BASE: 32-byte * 256 entry 1474 * PAIRWISE_KEY_TABLE_BASE: 32-byte * 256 entry
1440 * MAC_IVEIV_TABLE_BASE: 8-byte * 256-entry 1475 * MAC_IVEIV_TABLE_BASE: 8-byte * 256-entry
@@ -1584,7 +1619,8 @@ struct mac_iveiv_entry {
1584 * 2. Extract memory from FCE table for BCN 4~5 1619 * 2. Extract memory from FCE table for BCN 4~5
1585 * 3. Extract memory from Pair-wise key table for BCN 6~7 1620 * 3. Extract memory from Pair-wise key table for BCN 6~7
1586 * It occupied those memory of wcid 238~253 for BCN 6 1621 * It occupied those memory of wcid 238~253 for BCN 6
1587 * and wcid 222~237 for BCN 7 1622 * and wcid 222~237 for BCN 7 (see Security key table memory
1623 * for more info).
1588 * 1624 *
1589 * IMPORTANT NOTE: Not sure why legacy driver does this, 1625 * IMPORTANT NOTE: Not sure why legacy driver does this,
1590 * but HW_BEACON_BASE7 is 0x0200 bytes below HW_BEACON_BASE6. 1626 * but HW_BEACON_BASE7 is 0x0200 bytes below HW_BEACON_BASE6.
@@ -1963,10 +1999,17 @@ struct mac_iveiv_entry {
1963 * FRAG: 1 To inform TKIP engine this is a fragment. 1999 * FRAG: 1 To inform TKIP engine this is a fragment.
1964 * MIMO_PS: The remote peer is in dynamic MIMO-PS mode 2000 * MIMO_PS: The remote peer is in dynamic MIMO-PS mode
1965 * TX_OP: 0:HT TXOP rule , 1:PIFS TX ,2:Backoff, 3:sifs 2001 * TX_OP: 0:HT TXOP rule , 1:PIFS TX ,2:Backoff, 3:sifs
1966 * BW: Channel bandwidth 20MHz or 40 MHz 2002 * BW: Channel bandwidth 0:20MHz, 1:40 MHz (for legacy rates this will
2003 * duplicate the frame to both channels).
1967 * STBC: 1: STBC support MCS =0-7, 2,3 : RESERVED 2004 * STBC: 1: STBC support MCS =0-7, 2,3 : RESERVED
1968 * AMPDU: 1: this frame is eligible for AMPDU aggregation, the hw will 2005 * AMPDU: 1: this frame is eligible for AMPDU aggregation, the hw will
1969 * aggregate consecutive frames with the same RA and QoS TID. 2006 * aggregate consecutive frames with the same RA and QoS TID. If
2007 * a frame A with the same RA and QoS TID but AMPDU=0 is queued
2008 * directly after a frame B with AMPDU=1, frame A might still
2009 * get aggregated into the AMPDU started by frame B. So, setting
2010 * AMPDU to 0 does _not_ necessarily mean the frame is sent as
2011 * MPDU, it can still end up in an AMPDU if the previous frame
2012 * was tagged as AMPDU.
1970 */ 2013 */
1971#define TXWI_W0_FRAG FIELD32(0x00000001) 2014#define TXWI_W0_FRAG FIELD32(0x00000001)
1972#define TXWI_W0_MIMO_PS FIELD32(0x00000002) 2015#define TXWI_W0_MIMO_PS FIELD32(0x00000002)
@@ -1993,6 +2036,10 @@ struct mac_iveiv_entry {
1993 * frame was processed. If multiple frames are aggregated together 2036 * frame was processed. If multiple frames are aggregated together
1994 * (AMPDU==1) the reported tx status will always contain the packet 2037 * (AMPDU==1) the reported tx status will always contain the packet
1995 * id of the first frame. 0: Don't report tx status for this frame. 2038 * id of the first frame. 0: Don't report tx status for this frame.
2039 * PACKETID_QUEUE: Part of PACKETID, This is the queue index (0-3)
2040 * PACKETID_ENTRY: Part of PACKETID, THis is the queue entry index (1-3)
2041 * This identification number is calculated by ((idx % 3) + 1).
2042 * The (+1) is required to prevent PACKETID to become 0.
1996 */ 2043 */
1997#define TXWI_W1_ACK FIELD32(0x00000001) 2044#define TXWI_W1_ACK FIELD32(0x00000001)
1998#define TXWI_W1_NSEQ FIELD32(0x00000002) 2045#define TXWI_W1_NSEQ FIELD32(0x00000002)
@@ -2000,6 +2047,8 @@ struct mac_iveiv_entry {
2000#define TXWI_W1_WIRELESS_CLI_ID FIELD32(0x0000ff00) 2047#define TXWI_W1_WIRELESS_CLI_ID FIELD32(0x0000ff00)
2001#define TXWI_W1_MPDU_TOTAL_BYTE_COUNT FIELD32(0x0fff0000) 2048#define TXWI_W1_MPDU_TOTAL_BYTE_COUNT FIELD32(0x0fff0000)
2002#define TXWI_W1_PACKETID FIELD32(0xf0000000) 2049#define TXWI_W1_PACKETID FIELD32(0xf0000000)
2050#define TXWI_W1_PACKETID_QUEUE FIELD32(0x30000000)
2051#define TXWI_W1_PACKETID_ENTRY FIELD32(0xc0000000)
2003 2052
2004/* 2053/*
2005 * Word2 2054 * Word2
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
index 3bb67492d75..10aefc4fb0c 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -483,7 +483,8 @@ void rt2800_write_tx_data(struct queue_entry *entry,
483 txdesc->key_idx : 0xff); 483 txdesc->key_idx : 0xff);
484 rt2x00_set_field32(&word, TXWI_W1_MPDU_TOTAL_BYTE_COUNT, 484 rt2x00_set_field32(&word, TXWI_W1_MPDU_TOTAL_BYTE_COUNT,
485 txdesc->length); 485 txdesc->length);
486 rt2x00_set_field32(&word, TXWI_W1_PACKETID, txdesc->qid + 1); 486 rt2x00_set_field32(&word, TXWI_W1_PACKETID_QUEUE, txdesc->qid);
487 rt2x00_set_field32(&word, TXWI_W1_PACKETID_ENTRY, (entry->entry_idx % 3) + 1);
487 rt2x00_desc_write(txwi, 1, word); 488 rt2x00_desc_write(txwi, 1, word);
488 489
489 /* 490 /*
@@ -630,15 +631,90 @@ static bool rt2800_txdone_entry_check(struct queue_entry *entry, u32 reg)
630 return true; 631 return true;
631} 632}
632 633
634void rt2800_txdone_entry(struct queue_entry *entry, u32 status)
635{
636 struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
637 struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
638 struct txdone_entry_desc txdesc;
639 u32 word;
640 u16 mcs, real_mcs;
641 int aggr, ampdu;
642 __le32 *txwi;
643
644 /*
645 * Obtain the status about this packet.
646 */
647 txdesc.flags = 0;
648 txwi = rt2800_drv_get_txwi(entry);
649 rt2x00_desc_read(txwi, 0, &word);
650
651 mcs = rt2x00_get_field32(word, TXWI_W0_MCS);
652 ampdu = rt2x00_get_field32(word, TXWI_W0_AMPDU);
653
654 real_mcs = rt2x00_get_field32(status, TX_STA_FIFO_MCS);
655 aggr = rt2x00_get_field32(status, TX_STA_FIFO_TX_AGGRE);
656
657 /*
658 * If a frame was meant to be sent as a single non-aggregated MPDU
659 * but ended up in an aggregate the used tx rate doesn't correlate
660 * with the one specified in the TXWI as the whole aggregate is sent
661 * with the same rate.
662 *
663 * For example: two frames are sent to rt2x00, the first one sets
664 * AMPDU=1 and requests MCS7 whereas the second frame sets AMDPU=0
665 * and requests MCS15. If the hw aggregates both frames into one
666 * AMDPU the tx status for both frames will contain MCS7 although
667 * the frame was sent successfully.
668 *
669 * Hence, replace the requested rate with the real tx rate to not
670 * confuse the rate control algortihm by providing clearly wrong
671 * data.
672 */
673 if (aggr == 1 && ampdu == 0 && real_mcs != mcs) {
674 skbdesc->tx_rate_idx = real_mcs;
675 mcs = real_mcs;
676 }
677
678 /*
679 * Ralink has a retry mechanism using a global fallback
680 * table. We setup this fallback table to try the immediate
681 * lower rate for all rates. In the TX_STA_FIFO, the MCS field
682 * always contains the MCS used for the last transmission, be
683 * it successful or not.
684 */
685 if (rt2x00_get_field32(status, TX_STA_FIFO_TX_SUCCESS)) {
686 /*
687 * Transmission succeeded. The number of retries is
688 * mcs - real_mcs
689 */
690 __set_bit(TXDONE_SUCCESS, &txdesc.flags);
691 txdesc.retry = ((mcs > real_mcs) ? mcs - real_mcs : 0);
692 } else {
693 /*
694 * Transmission failed. The number of retries is
695 * always 7 in this case (for a total number of 8
696 * frames sent).
697 */
698 __set_bit(TXDONE_FAILURE, &txdesc.flags);
699 txdesc.retry = rt2x00dev->long_retry;
700 }
701
702 /*
703 * the frame was retried at least once
704 * -> hw used fallback rates
705 */
706 if (txdesc.retry)
707 __set_bit(TXDONE_FALLBACK, &txdesc.flags);
708
709 rt2x00lib_txdone(entry, &txdesc);
710}
711EXPORT_SYMBOL_GPL(rt2800_txdone_entry);
712
633void rt2800_txdone(struct rt2x00_dev *rt2x00dev) 713void rt2800_txdone(struct rt2x00_dev *rt2x00dev)
634{ 714{
635 struct data_queue *queue; 715 struct data_queue *queue;
636 struct queue_entry *entry; 716 struct queue_entry *entry;
637 __le32 *txwi;
638 struct txdone_entry_desc txdesc;
639 u32 word;
640 u32 reg; 717 u32 reg;
641 u16 mcs, real_mcs;
642 u8 pid; 718 u8 pid;
643 int i; 719 int i;
644 720
@@ -660,7 +736,7 @@ void rt2800_txdone(struct rt2x00_dev *rt2x00dev)
660 * Skip this entry when it contains an invalid 736 * Skip this entry when it contains an invalid
661 * queue identication number. 737 * queue identication number.
662 */ 738 */
663 pid = rt2x00_get_field32(reg, TX_STA_FIFO_PID_TYPE) - 1; 739 pid = rt2x00_get_field32(reg, TX_STA_FIFO_PID_QUEUE);
664 if (pid >= QID_RX) 740 if (pid >= QID_RX)
665 continue; 741 continue;
666 742
@@ -673,7 +749,6 @@ void rt2800_txdone(struct rt2x00_dev *rt2x00dev)
673 * order. We first check that the queue is not empty. 749 * order. We first check that the queue is not empty.
674 */ 750 */
675 entry = NULL; 751 entry = NULL;
676 txwi = NULL;
677 while (!rt2x00queue_empty(queue)) { 752 while (!rt2x00queue_empty(queue)) {
678 entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE); 753 entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE);
679 if (rt2800_txdone_entry_check(entry, reg)) 754 if (rt2800_txdone_entry_check(entry, reg))
@@ -683,48 +758,7 @@ void rt2800_txdone(struct rt2x00_dev *rt2x00dev)
683 if (!entry || rt2x00queue_empty(queue)) 758 if (!entry || rt2x00queue_empty(queue))
684 break; 759 break;
685 760
686 761 rt2800_txdone_entry(entry, reg);
687 /*
688 * Obtain the status about this packet.
689 */
690 txdesc.flags = 0;
691 txwi = rt2800_drv_get_txwi(entry);
692 rt2x00_desc_read(txwi, 0, &word);
693 mcs = rt2x00_get_field32(word, TXWI_W0_MCS);
694 real_mcs = rt2x00_get_field32(reg, TX_STA_FIFO_MCS);
695
696 /*
697 * Ralink has a retry mechanism using a global fallback
698 * table. We setup this fallback table to try the immediate
699 * lower rate for all rates. In the TX_STA_FIFO, the MCS field
700 * always contains the MCS used for the last transmission, be
701 * it successful or not.
702 */
703 if (rt2x00_get_field32(reg, TX_STA_FIFO_TX_SUCCESS)) {
704 /*
705 * Transmission succeeded. The number of retries is
706 * mcs - real_mcs
707 */
708 __set_bit(TXDONE_SUCCESS, &txdesc.flags);
709 txdesc.retry = ((mcs > real_mcs) ? mcs - real_mcs : 0);
710 } else {
711 /*
712 * Transmission failed. The number of retries is
713 * always 7 in this case (for a total number of 8
714 * frames sent).
715 */
716 __set_bit(TXDONE_FAILURE, &txdesc.flags);
717 txdesc.retry = rt2x00dev->long_retry;
718 }
719
720 /*
721 * the frame was retried at least once
722 * -> hw used fallback rates
723 */
724 if (txdesc.retry)
725 __set_bit(TXDONE_FALLBACK, &txdesc.flags);
726
727 rt2x00lib_txdone(entry, &txdesc);
728 } 762 }
729} 763}
730EXPORT_SYMBOL_GPL(rt2800_txdone); 764EXPORT_SYMBOL_GPL(rt2800_txdone);
@@ -1031,8 +1065,12 @@ int rt2800_config_pairwise_key(struct rt2x00_dev *rt2x00dev,
1031 * 1 pairwise key is possible per AID, this means that the AID 1065 * 1 pairwise key is possible per AID, this means that the AID
1032 * equals our hw_key_idx. Make sure the WCID starts _after_ the 1066 * equals our hw_key_idx. Make sure the WCID starts _after_ the
1033 * last possible shared key entry. 1067 * last possible shared key entry.
1068 *
1069 * Since parts of the pairwise key table might be shared with
1070 * the beacon frame buffers 6 & 7 we should only write into the
1071 * first 222 entries.
1034 */ 1072 */
1035 if (crypto->aid > (256 - 32)) 1073 if (crypto->aid > (222 - 32))
1036 return -ENOSPC; 1074 return -ENOSPC;
1037 1075
1038 key->hw_key_idx = 32 + crypto->aid; 1076 key->hw_key_idx = 32 + crypto->aid;
@@ -1159,6 +1197,102 @@ void rt2800_config_intf(struct rt2x00_dev *rt2x00dev, struct rt2x00_intf *intf,
1159} 1197}
1160EXPORT_SYMBOL_GPL(rt2800_config_intf); 1198EXPORT_SYMBOL_GPL(rt2800_config_intf);
1161 1199
1200static void rt2800_config_ht_opmode(struct rt2x00_dev *rt2x00dev,
1201 struct rt2x00lib_erp *erp)
1202{
1203 bool any_sta_nongf = !!(erp->ht_opmode &
1204 IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT);
1205 u8 protection = erp->ht_opmode & IEEE80211_HT_OP_MODE_PROTECTION;
1206 u8 mm20_mode, mm40_mode, gf20_mode, gf40_mode;
1207 u16 mm20_rate, mm40_rate, gf20_rate, gf40_rate;
1208 u32 reg;
1209
1210 /* default protection rate for HT20: OFDM 24M */
1211 mm20_rate = gf20_rate = 0x4004;
1212
1213 /* default protection rate for HT40: duplicate OFDM 24M */
1214 mm40_rate = gf40_rate = 0x4084;
1215
1216 switch (protection) {
1217 case IEEE80211_HT_OP_MODE_PROTECTION_NONE:
1218 /*
1219 * All STAs in this BSS are HT20/40 but there might be
1220 * STAs not supporting greenfield mode.
1221 * => Disable protection for HT transmissions.
1222 */
1223 mm20_mode = mm40_mode = gf20_mode = gf40_mode = 0;
1224
1225 break;
1226 case IEEE80211_HT_OP_MODE_PROTECTION_20MHZ:
1227 /*
1228 * All STAs in this BSS are HT20 or HT20/40 but there
1229 * might be STAs not supporting greenfield mode.
1230 * => Protect all HT40 transmissions.
1231 */
1232 mm20_mode = gf20_mode = 0;
1233 mm40_mode = gf40_mode = 2;
1234
1235 break;
1236 case IEEE80211_HT_OP_MODE_PROTECTION_NONMEMBER:
1237 /*
1238 * Nonmember protection:
1239 * According to 802.11n we _should_ protect all
1240 * HT transmissions (but we don't have to).
1241 *
1242 * But if cts_protection is enabled we _shall_ protect
1243 * all HT transmissions using a CCK rate.
1244 *
1245 * And if any station is non GF we _shall_ protect
1246 * GF transmissions.
1247 *
1248 * We decide to protect everything
1249 * -> fall through to mixed mode.
1250 */
1251 case IEEE80211_HT_OP_MODE_PROTECTION_NONHT_MIXED:
1252 /*
1253 * Legacy STAs are present
1254 * => Protect all HT transmissions.
1255 */
1256 mm20_mode = mm40_mode = gf20_mode = gf40_mode = 2;
1257
1258 /*
1259 * If erp protection is needed we have to protect HT
1260 * transmissions with CCK 11M long preamble.
1261 */
1262 if (erp->cts_protection) {
1263 /* don't duplicate RTS/CTS in CCK mode */
1264 mm20_rate = mm40_rate = 0x0003;
1265 gf20_rate = gf40_rate = 0x0003;
1266 }
1267 break;
1268 };
1269
1270 /* check for STAs not supporting greenfield mode */
1271 if (any_sta_nongf)
1272 gf20_mode = gf40_mode = 2;
1273
1274 /* Update HT protection config */
1275 rt2800_register_read(rt2x00dev, MM20_PROT_CFG, &reg);
1276 rt2x00_set_field32(&reg, MM20_PROT_CFG_PROTECT_RATE, mm20_rate);
1277 rt2x00_set_field32(&reg, MM20_PROT_CFG_PROTECT_CTRL, mm20_mode);
1278 rt2800_register_write(rt2x00dev, MM20_PROT_CFG, reg);
1279
1280 rt2800_register_read(rt2x00dev, MM40_PROT_CFG, &reg);
1281 rt2x00_set_field32(&reg, MM40_PROT_CFG_PROTECT_RATE, mm40_rate);
1282 rt2x00_set_field32(&reg, MM40_PROT_CFG_PROTECT_CTRL, mm40_mode);
1283 rt2800_register_write(rt2x00dev, MM40_PROT_CFG, reg);
1284
1285 rt2800_register_read(rt2x00dev, GF20_PROT_CFG, &reg);
1286 rt2x00_set_field32(&reg, GF20_PROT_CFG_PROTECT_RATE, gf20_rate);
1287 rt2x00_set_field32(&reg, GF20_PROT_CFG_PROTECT_CTRL, gf20_mode);
1288 rt2800_register_write(rt2x00dev, GF20_PROT_CFG, reg);
1289
1290 rt2800_register_read(rt2x00dev, GF40_PROT_CFG, &reg);
1291 rt2x00_set_field32(&reg, GF40_PROT_CFG_PROTECT_RATE, gf40_rate);
1292 rt2x00_set_field32(&reg, GF40_PROT_CFG_PROTECT_CTRL, gf40_mode);
1293 rt2800_register_write(rt2x00dev, GF40_PROT_CFG, reg);
1294}
1295
1162void rt2800_config_erp(struct rt2x00_dev *rt2x00dev, struct rt2x00lib_erp *erp, 1296void rt2800_config_erp(struct rt2x00_dev *rt2x00dev, struct rt2x00lib_erp *erp,
1163 u32 changed) 1297 u32 changed)
1164{ 1298{
@@ -1203,6 +1337,9 @@ void rt2800_config_erp(struct rt2x00_dev *rt2x00dev, struct rt2x00lib_erp *erp,
1203 erp->beacon_int * 16); 1337 erp->beacon_int * 16);
1204 rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg); 1338 rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg);
1205 } 1339 }
1340
1341 if (changed & BSS_CHANGED_HT)
1342 rt2800_config_ht_opmode(rt2x00dev, erp);
1206} 1343}
1207EXPORT_SYMBOL_GPL(rt2800_config_erp); 1344EXPORT_SYMBOL_GPL(rt2800_config_erp);
1208 1345
@@ -1907,8 +2044,7 @@ static int rt2800_init_registers(struct rt2x00_dev *rt2x00dev)
1907 2044
1908 rt2800_register_read(rt2x00dev, MM40_PROT_CFG, &reg); 2045 rt2800_register_read(rt2x00dev, MM40_PROT_CFG, &reg);
1909 rt2x00_set_field32(&reg, MM40_PROT_CFG_PROTECT_RATE, 0x4084); 2046 rt2x00_set_field32(&reg, MM40_PROT_CFG_PROTECT_RATE, 0x4084);
1910 rt2x00_set_field32(&reg, MM40_PROT_CFG_PROTECT_CTRL, 2047 rt2x00_set_field32(&reg, MM40_PROT_CFG_PROTECT_CTRL, 0);
1911 !rt2x00_is_usb(rt2x00dev));
1912 rt2x00_set_field32(&reg, MM40_PROT_CFG_PROTECT_NAV, 1); 2048 rt2x00_set_field32(&reg, MM40_PROT_CFG_PROTECT_NAV, 1);
1913 rt2x00_set_field32(&reg, MM40_PROT_CFG_TX_OP_ALLOW_CCK, 1); 2049 rt2x00_set_field32(&reg, MM40_PROT_CFG_TX_OP_ALLOW_CCK, 1);
1914 rt2x00_set_field32(&reg, MM40_PROT_CFG_TX_OP_ALLOW_OFDM, 1); 2050 rt2x00_set_field32(&reg, MM40_PROT_CFG_TX_OP_ALLOW_OFDM, 1);
@@ -3056,11 +3192,20 @@ int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
3056 * Initialize all hw fields. 3192 * Initialize all hw fields.
3057 */ 3193 */
3058 rt2x00dev->hw->flags = 3194 rt2x00dev->hw->flags =
3059 IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
3060 IEEE80211_HW_SIGNAL_DBM | 3195 IEEE80211_HW_SIGNAL_DBM |
3061 IEEE80211_HW_SUPPORTS_PS | 3196 IEEE80211_HW_SUPPORTS_PS |
3062 IEEE80211_HW_PS_NULLFUNC_STACK | 3197 IEEE80211_HW_PS_NULLFUNC_STACK |
3063 IEEE80211_HW_AMPDU_AGGREGATION; 3198 IEEE80211_HW_AMPDU_AGGREGATION;
3199 /*
3200 * Don't set IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING for USB devices
3201 * unless we are capable of sending the buffered frames out after the
3202 * DTIM transmission using rt2x00lib_beacondone. This will send out
3203 * multicast and broadcast traffic immediately instead of buffering it
3204 * infinitly and thus dropping it after some time.
3205 */
3206 if (!rt2x00_is_usb(rt2x00dev))
3207 rt2x00dev->hw->flags |=
3208 IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING;
3064 3209
3065 SET_IEEE80211_DEV(rt2x00dev->hw, rt2x00dev->dev); 3210 SET_IEEE80211_DEV(rt2x00dev->hw, rt2x00dev->dev);
3066 SET_IEEE80211_PERM_ADDR(rt2x00dev->hw, 3211 SET_IEEE80211_PERM_ADDR(rt2x00dev->hw,
@@ -3071,12 +3216,13 @@ int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
3071 * As rt2800 has a global fallback table we cannot specify 3216 * As rt2800 has a global fallback table we cannot specify
3072 * more then one tx rate per frame but since the hw will 3217 * more then one tx rate per frame but since the hw will
3073 * try several rates (based on the fallback table) we should 3218 * try several rates (based on the fallback table) we should
3074 * still initialize max_rates to the maximum number of rates 3219 * initialize max_report_rates to the maximum number of rates
3075 * we are going to try. Otherwise mac80211 will truncate our 3220 * we are going to try. Otherwise mac80211 will truncate our
3076 * reported tx rates and the rc algortihm will end up with 3221 * reported tx rates and the rc algortihm will end up with
3077 * incorrect data. 3222 * incorrect data.
3078 */ 3223 */
3079 rt2x00dev->hw->max_rates = 7; 3224 rt2x00dev->hw->max_rates = 1;
3225 rt2x00dev->hw->max_report_rates = 7;
3080 rt2x00dev->hw->max_rate_tries = 1; 3226 rt2x00dev->hw->max_rate_tries = 1;
3081 3227
3082 rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &eeprom); 3228 rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &eeprom);
@@ -3333,8 +3479,12 @@ int rt2800_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
3333 switch (action) { 3479 switch (action) {
3334 case IEEE80211_AMPDU_RX_START: 3480 case IEEE80211_AMPDU_RX_START:
3335 case IEEE80211_AMPDU_RX_STOP: 3481 case IEEE80211_AMPDU_RX_STOP:
3336 /* we don't support RX aggregation yet */ 3482 /*
3337 ret = -ENOTSUPP; 3483 * The hw itself takes care of setting up BlockAck mechanisms.
3484 * So, we only have to allow mac80211 to nagotiate a BlockAck
3485 * agreement. Once that is done, the hw will BlockAck incoming
3486 * AMPDUs without further setup.
3487 */
3338 break; 3488 break;
3339 case IEEE80211_AMPDU_TX_START: 3489 case IEEE80211_AMPDU_TX_START:
3340 ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid); 3490 ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid);
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.h b/drivers/net/wireless/rt2x00/rt2800lib.h
index 600c5eb25c4..81cbc92e785 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.h
+++ b/drivers/net/wireless/rt2x00/rt2800lib.h
@@ -153,6 +153,7 @@ void rt2800_write_tx_data(struct queue_entry *entry,
153void rt2800_process_rxwi(struct queue_entry *entry, struct rxdone_entry_desc *txdesc); 153void rt2800_process_rxwi(struct queue_entry *entry, struct rxdone_entry_desc *txdesc);
154 154
155void rt2800_txdone(struct rt2x00_dev *rt2x00dev); 155void rt2800_txdone(struct rt2x00_dev *rt2x00dev);
156void rt2800_txdone_entry(struct queue_entry *entry, u32 status);
156 157
157void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc); 158void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc);
158 159
diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c
index 005ee153e0c..85a134cd62b 100644
--- a/drivers/net/wireless/rt2x00/rt2800pci.c
+++ b/drivers/net/wireless/rt2x00/rt2800pci.c
@@ -241,6 +241,7 @@ static void rt2800pci_clear_entry(struct queue_entry *entry)
241{ 241{
242 struct queue_entry_priv_pci *entry_priv = entry->priv_data; 242 struct queue_entry_priv_pci *entry_priv = entry->priv_data;
243 struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); 243 struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
244 struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
244 u32 word; 245 u32 word;
245 246
246 if (entry->queue->qid == QID_RX) { 247 if (entry->queue->qid == QID_RX) {
@@ -251,6 +252,13 @@ static void rt2800pci_clear_entry(struct queue_entry *entry)
251 rt2x00_desc_read(entry_priv->desc, 1, &word); 252 rt2x00_desc_read(entry_priv->desc, 1, &word);
252 rt2x00_set_field32(&word, RXD_W1_DMA_DONE, 0); 253 rt2x00_set_field32(&word, RXD_W1_DMA_DONE, 0);
253 rt2x00_desc_write(entry_priv->desc, 1, word); 254 rt2x00_desc_write(entry_priv->desc, 1, word);
255
256 /*
257 * Set RX IDX in register to inform hardware that we have
258 * handled this entry and it is available for reuse again.
259 */
260 rt2800_register_write(rt2x00dev, RX_CRX_IDX,
261 entry->entry_idx);
254 } else { 262 } else {
255 rt2x00_desc_read(entry_priv->desc, 1, &word); 263 rt2x00_desc_read(entry_priv->desc, 1, &word);
256 rt2x00_set_field32(&word, TXD_W1_DMA_DONE, 1); 264 rt2x00_set_field32(&word, TXD_W1_DMA_DONE, 1);
@@ -599,7 +607,6 @@ static void rt2800pci_kill_tx_queue(struct data_queue *queue)
599static void rt2800pci_fill_rxdone(struct queue_entry *entry, 607static void rt2800pci_fill_rxdone(struct queue_entry *entry,
600 struct rxdone_entry_desc *rxdesc) 608 struct rxdone_entry_desc *rxdesc)
601{ 609{
602 struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
603 struct queue_entry_priv_pci *entry_priv = entry->priv_data; 610 struct queue_entry_priv_pci *entry_priv = entry->priv_data;
604 __le32 *rxd = entry_priv->desc; 611 __le32 *rxd = entry_priv->desc;
605 u32 word; 612 u32 word;
@@ -641,12 +648,6 @@ static void rt2800pci_fill_rxdone(struct queue_entry *entry,
641 * Process the RXWI structure that is at the start of the buffer. 648 * Process the RXWI structure that is at the start of the buffer.
642 */ 649 */
643 rt2800_process_rxwi(entry, rxdesc); 650 rt2800_process_rxwi(entry, rxdesc);
644
645 /*
646 * Set RX IDX in register to inform hardware that we have handled
647 * this entry and it is available for reuse again.
648 */
649 rt2800_register_write(rt2x00dev, RX_CRX_IDX, entry->entry_idx);
650} 651}
651 652
652/* 653/*
@@ -660,6 +661,63 @@ static void rt2800pci_wakeup(struct rt2x00_dev *rt2x00dev)
660 rt2800_config(rt2x00dev, &libconf, IEEE80211_CONF_CHANGE_PS); 661 rt2800_config(rt2x00dev, &libconf, IEEE80211_CONF_CHANGE_PS);
661} 662}
662 663
664static void rt2800pci_txdone(struct rt2x00_dev *rt2x00dev)
665{
666 struct data_queue *queue;
667 struct queue_entry *entry;
668 u32 status;
669 u8 qid;
670
671 while (!kfifo_is_empty(&rt2x00dev->txstatus_fifo)) {
672 /* Now remove the tx status from the FIFO */
673 if (kfifo_out(&rt2x00dev->txstatus_fifo, &status,
674 sizeof(status)) != sizeof(status)) {
675 WARN_ON(1);
676 break;
677 }
678
679 qid = rt2x00_get_field32(status, TX_STA_FIFO_PID_TYPE) - 1;
680 if (qid >= QID_RX) {
681 /*
682 * Unknown queue, this shouldn't happen. Just drop
683 * this tx status.
684 */
685 WARNING(rt2x00dev, "Got TX status report with "
686 "unexpected pid %u, dropping", qid);
687 break;
688 }
689
690 queue = rt2x00queue_get_queue(rt2x00dev, qid);
691 if (unlikely(queue == NULL)) {
692 /*
693 * The queue is NULL, this shouldn't happen. Stop
694 * processing here and drop the tx status
695 */
696 WARNING(rt2x00dev, "Got TX status for an unavailable "
697 "queue %u, dropping", qid);
698 break;
699 }
700
701 if (rt2x00queue_empty(queue)) {
702 /*
703 * The queue is empty. Stop processing here
704 * and drop the tx status.
705 */
706 WARNING(rt2x00dev, "Got TX status for an empty "
707 "queue %u, dropping", qid);
708 break;
709 }
710
711 entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE);
712 rt2800_txdone_entry(entry, status);
713 }
714}
715
716static void rt2800pci_txstatus_tasklet(unsigned long data)
717{
718 rt2800pci_txdone((struct rt2x00_dev *)data);
719}
720
663static irqreturn_t rt2800pci_interrupt_thread(int irq, void *dev_instance) 721static irqreturn_t rt2800pci_interrupt_thread(int irq, void *dev_instance)
664{ 722{
665 struct rt2x00_dev *rt2x00dev = dev_instance; 723 struct rt2x00_dev *rt2x00dev = dev_instance;
@@ -684,13 +742,7 @@ static irqreturn_t rt2800pci_interrupt_thread(int irq, void *dev_instance)
684 rt2x00pci_rxdone(rt2x00dev); 742 rt2x00pci_rxdone(rt2x00dev);
685 743
686 /* 744 /*
687 * 4 - Tx done interrupt. 745 * 4 - Auto wakeup interrupt.
688 */
689 if (rt2x00_get_field32(reg, INT_SOURCE_CSR_TX_FIFO_STATUS))
690 rt2800_txdone(rt2x00dev);
691
692 /*
693 * 5 - Auto wakeup interrupt.
694 */ 746 */
695 if (rt2x00_get_field32(reg, INT_SOURCE_CSR_AUTO_WAKEUP)) 747 if (rt2x00_get_field32(reg, INT_SOURCE_CSR_AUTO_WAKEUP))
696 rt2800pci_wakeup(rt2x00dev); 748 rt2800pci_wakeup(rt2x00dev);
@@ -702,10 +754,58 @@ static irqreturn_t rt2800pci_interrupt_thread(int irq, void *dev_instance)
702 return IRQ_HANDLED; 754 return IRQ_HANDLED;
703} 755}
704 756
757static void rt2800pci_txstatus_interrupt(struct rt2x00_dev *rt2x00dev)
758{
759 u32 status;
760 int i;
761
762 /*
763 * The TX_FIFO_STATUS interrupt needs special care. We should
764 * read TX_STA_FIFO but we should do it immediately as otherwise
765 * the register can overflow and we would lose status reports.
766 *
767 * Hence, read the TX_STA_FIFO register and copy all tx status
768 * reports into a kernel FIFO which is handled in the txstatus
769 * tasklet. We use a tasklet to process the tx status reports
770 * because we can schedule the tasklet multiple times (when the
771 * interrupt fires again during tx status processing).
772 *
773 * Furthermore we don't disable the TX_FIFO_STATUS
774 * interrupt here but leave it enabled so that the TX_STA_FIFO
775 * can also be read while the interrupt thread gets executed.
776 *
777 * Since we have only one producer and one consumer we don't
778 * need to lock the kfifo.
779 */
780 for (i = 0; i < TX_ENTRIES; i++) {
781 rt2800_register_read(rt2x00dev, TX_STA_FIFO, &status);
782
783 if (!rt2x00_get_field32(status, TX_STA_FIFO_VALID))
784 break;
785
786 if (kfifo_is_full(&rt2x00dev->txstatus_fifo)) {
787 WARNING(rt2x00dev, "TX status FIFO overrun,"
788 " drop tx status report.\n");
789 break;
790 }
791
792 if (kfifo_in(&rt2x00dev->txstatus_fifo, &status,
793 sizeof(status)) != sizeof(status)) {
794 WARNING(rt2x00dev, "TX status FIFO overrun,"
795 "drop tx status report.\n");
796 break;
797 }
798 }
799
800 /* Schedule the tasklet for processing the tx status. */
801 tasklet_schedule(&rt2x00dev->txstatus_tasklet);
802}
803
705static irqreturn_t rt2800pci_interrupt(int irq, void *dev_instance) 804static irqreturn_t rt2800pci_interrupt(int irq, void *dev_instance)
706{ 805{
707 struct rt2x00_dev *rt2x00dev = dev_instance; 806 struct rt2x00_dev *rt2x00dev = dev_instance;
708 u32 reg; 807 u32 reg;
808 irqreturn_t ret = IRQ_HANDLED;
709 809
710 /* Read status and ACK all interrupts */ 810 /* Read status and ACK all interrupts */
711 rt2800_register_read(rt2x00dev, INT_SOURCE_CSR, &reg); 811 rt2800_register_read(rt2x00dev, INT_SOURCE_CSR, &reg);
@@ -717,15 +817,38 @@ static irqreturn_t rt2800pci_interrupt(int irq, void *dev_instance)
717 if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) 817 if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
718 return IRQ_HANDLED; 818 return IRQ_HANDLED;
719 819
720 /* Store irqvalue for use in the interrupt thread. */ 820 if (rt2x00_get_field32(reg, INT_SOURCE_CSR_TX_FIFO_STATUS))
721 rt2x00dev->irqvalue[0] = reg; 821 rt2800pci_txstatus_interrupt(rt2x00dev);
722 822
723 /* Disable interrupts, will be enabled again in the interrupt thread. */ 823 if (rt2x00_get_field32(reg, INT_SOURCE_CSR_PRE_TBTT) ||
724 rt2x00dev->ops->lib->set_device_state(rt2x00dev, 824 rt2x00_get_field32(reg, INT_SOURCE_CSR_TBTT) ||
725 STATE_RADIO_IRQ_OFF_ISR); 825 rt2x00_get_field32(reg, INT_SOURCE_CSR_RX_DONE) ||
826 rt2x00_get_field32(reg, INT_SOURCE_CSR_AUTO_WAKEUP)) {
827 /*
828 * All other interrupts are handled in the interrupt thread.
829 * Store irqvalue for use in the interrupt thread.
830 */
831 rt2x00dev->irqvalue[0] = reg;
832
833 /*
834 * Disable interrupts, will be enabled again in the
835 * interrupt thread.
836 */
837 rt2x00dev->ops->lib->set_device_state(rt2x00dev,
838 STATE_RADIO_IRQ_OFF_ISR);
839
840 /*
841 * Leave the TX_FIFO_STATUS interrupt enabled to not lose any
842 * tx status reports.
843 */
844 rt2800_register_read(rt2x00dev, INT_MASK_CSR, &reg);
845 rt2x00_set_field32(&reg, INT_MASK_CSR_TX_FIFO_STATUS, 1);
846 rt2800_register_write(rt2x00dev, INT_MASK_CSR, reg);
726 847
848 ret = IRQ_WAKE_THREAD;
849 }
727 850
728 return IRQ_WAKE_THREAD; 851 return ret;
729} 852}
730 853
731/* 854/*
@@ -788,6 +911,7 @@ static int rt2800pci_probe_hw(struct rt2x00_dev *rt2x00dev)
788 __set_bit(DRIVER_REQUIRE_FIRMWARE, &rt2x00dev->flags); 911 __set_bit(DRIVER_REQUIRE_FIRMWARE, &rt2x00dev->flags);
789 __set_bit(DRIVER_REQUIRE_DMA, &rt2x00dev->flags); 912 __set_bit(DRIVER_REQUIRE_DMA, &rt2x00dev->flags);
790 __set_bit(DRIVER_REQUIRE_L2PAD, &rt2x00dev->flags); 913 __set_bit(DRIVER_REQUIRE_L2PAD, &rt2x00dev->flags);
914 __set_bit(DRIVER_REQUIRE_TXSTATUS_FIFO, &rt2x00dev->flags);
791 if (!modparam_nohwcrypt) 915 if (!modparam_nohwcrypt)
792 __set_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags); 916 __set_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags);
793 __set_bit(DRIVER_SUPPORT_LINK_TUNING, &rt2x00dev->flags); 917 __set_bit(DRIVER_SUPPORT_LINK_TUNING, &rt2x00dev->flags);
@@ -837,6 +961,7 @@ static const struct rt2800_ops rt2800pci_rt2800_ops = {
837static const struct rt2x00lib_ops rt2800pci_rt2x00_ops = { 961static const struct rt2x00lib_ops rt2800pci_rt2x00_ops = {
838 .irq_handler = rt2800pci_interrupt, 962 .irq_handler = rt2800pci_interrupt,
839 .irq_handler_thread = rt2800pci_interrupt_thread, 963 .irq_handler_thread = rt2800pci_interrupt_thread,
964 .txstatus_tasklet = rt2800pci_txstatus_tasklet,
840 .probe_hw = rt2800pci_probe_hw, 965 .probe_hw = rt2800pci_probe_hw,
841 .get_firmware_name = rt2800pci_get_firmware_name, 966 .get_firmware_name = rt2800pci_get_firmware_name,
842 .check_firmware = rt2800_check_firmware, 967 .check_firmware = rt2800_check_firmware,
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h
index 7832a5996a8..75ac6624bf9 100644
--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
@@ -36,6 +36,7 @@
36#include <linux/mutex.h> 36#include <linux/mutex.h>
37#include <linux/etherdevice.h> 37#include <linux/etherdevice.h>
38#include <linux/input-polldev.h> 38#include <linux/input-polldev.h>
39#include <linux/kfifo.h>
39 40
40#include <net/mac80211.h> 41#include <net/mac80211.h>
41 42
@@ -457,6 +458,7 @@ struct rt2x00lib_erp {
457 short eifs; 458 short eifs;
458 459
459 u16 beacon_int; 460 u16 beacon_int;
461 u16 ht_opmode;
460}; 462};
461 463
462/* 464/*
@@ -522,6 +524,11 @@ struct rt2x00lib_ops {
522 irq_handler_t irq_handler_thread; 524 irq_handler_t irq_handler_thread;
523 525
524 /* 526 /*
527 * TX status tasklet handler.
528 */
529 void (*txstatus_tasklet) (unsigned long data);
530
531 /*
525 * Device init handlers. 532 * Device init handlers.
526 */ 533 */
527 int (*probe_hw) (struct rt2x00_dev *rt2x00dev); 534 int (*probe_hw) (struct rt2x00_dev *rt2x00dev);
@@ -651,6 +658,7 @@ enum rt2x00_flags {
651 DRIVER_REQUIRE_DMA, 658 DRIVER_REQUIRE_DMA,
652 DRIVER_REQUIRE_COPY_IV, 659 DRIVER_REQUIRE_COPY_IV,
653 DRIVER_REQUIRE_L2PAD, 660 DRIVER_REQUIRE_L2PAD,
661 DRIVER_REQUIRE_TXSTATUS_FIFO,
654 662
655 /* 663 /*
656 * Driver features 664 * Driver features
@@ -884,6 +892,16 @@ struct rt2x00_dev {
884 * and interrupt thread routine. 892 * and interrupt thread routine.
885 */ 893 */
886 u32 irqvalue[2]; 894 u32 irqvalue[2];
895
896 /*
897 * FIFO for storing tx status reports between isr and tasklet.
898 */
899 struct kfifo txstatus_fifo;
900
901 /*
902 * Tasklet for processing tx status reports (rt2800pci).
903 */
904 struct tasklet_struct txstatus_tasklet;
887}; 905};
888 906
889/* 907/*
diff --git a/drivers/net/wireless/rt2x00/rt2x00config.c b/drivers/net/wireless/rt2x00/rt2x00config.c
index 4c7ff765a8b..54ffb5aeb34 100644
--- a/drivers/net/wireless/rt2x00/rt2x00config.c
+++ b/drivers/net/wireless/rt2x00/rt2x00config.c
@@ -103,6 +103,9 @@ void rt2x00lib_config_erp(struct rt2x00_dev *rt2x00dev,
103 /* Update global beacon interval time, this is needed for PS support */ 103 /* Update global beacon interval time, this is needed for PS support */
104 rt2x00dev->beacon_int = bss_conf->beacon_int; 104 rt2x00dev->beacon_int = bss_conf->beacon_int;
105 105
106 if (changed & BSS_CHANGED_HT)
107 erp.ht_opmode = bss_conf->ht_operation_mode;
108
106 rt2x00dev->ops->lib->config_erp(rt2x00dev, &erp, changed); 109 rt2x00dev->ops->lib->config_erp(rt2x00dev, &erp, changed);
107} 110}
108 111
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c
index 053fdd3bd72..6f442b02b83 100644
--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
@@ -813,6 +813,30 @@ static int rt2x00lib_probe_hw(struct rt2x00_dev *rt2x00dev)
813 rt2x00dev->hw->extra_tx_headroom += RT2X00_ALIGN_SIZE; 813 rt2x00dev->hw->extra_tx_headroom += RT2X00_ALIGN_SIZE;
814 814
815 /* 815 /*
816 * Allocate tx status FIFO for driver use.
817 */
818 if (test_bit(DRIVER_REQUIRE_TXSTATUS_FIFO, &rt2x00dev->flags) &&
819 rt2x00dev->ops->lib->txstatus_tasklet) {
820 /*
821 * Allocate txstatus fifo and tasklet, we use a size of 512
822 * for the kfifo which is big enough to store 512/4=128 tx
823 * status reports. In the worst case (tx status for all tx
824 * queues gets reported before we've got a chance to handle
825 * them) 24*4=384 tx status reports need to be cached.
826 */
827 status = kfifo_alloc(&rt2x00dev->txstatus_fifo, 512,
828 GFP_KERNEL);
829 if (status)
830 return status;
831
832 /* tasklet for processing the tx status reports. */
833 tasklet_init(&rt2x00dev->txstatus_tasklet,
834 rt2x00dev->ops->lib->txstatus_tasklet,
835 (unsigned long)rt2x00dev);
836
837 }
838
839 /*
816 * Register HW. 840 * Register HW.
817 */ 841 */
818 status = ieee80211_register_hw(rt2x00dev->hw); 842 status = ieee80211_register_hw(rt2x00dev->hw);
@@ -909,10 +933,8 @@ int rt2x00lib_start(struct rt2x00_dev *rt2x00dev)
909 933
910 /* Enable the radio */ 934 /* Enable the radio */
911 retval = rt2x00lib_enable_radio(rt2x00dev); 935 retval = rt2x00lib_enable_radio(rt2x00dev);
912 if (retval) { 936 if (retval)
913 rt2x00queue_uninitialize(rt2x00dev);
914 return retval; 937 return retval;
915 }
916 938
917 set_bit(DEVICE_STATE_STARTED, &rt2x00dev->flags); 939 set_bit(DEVICE_STATE_STARTED, &rt2x00dev->flags);
918 940
@@ -1028,6 +1050,16 @@ void rt2x00lib_remove_dev(struct rt2x00_dev *rt2x00dev)
1028 cancel_work_sync(&rt2x00dev->txdone_work); 1050 cancel_work_sync(&rt2x00dev->txdone_work);
1029 1051
1030 /* 1052 /*
1053 * Free the tx status fifo.
1054 */
1055 kfifo_free(&rt2x00dev->txstatus_fifo);
1056
1057 /*
1058 * Kill the tx status tasklet.
1059 */
1060 tasklet_kill(&rt2x00dev->txstatus_tasklet);
1061
1062 /*
1031 * Uninitialize device. 1063 * Uninitialize device.
1032 */ 1064 */
1033 rt2x00lib_uninitialize(rt2x00dev); 1065 rt2x00lib_uninitialize(rt2x00dev);
diff --git a/drivers/net/wireless/rt2x00/rt2x00ht.c b/drivers/net/wireless/rt2x00/rt2x00ht.c
index ad3c7ff4837..c637bcaec5f 100644
--- a/drivers/net/wireless/rt2x00/rt2x00ht.c
+++ b/drivers/net/wireless/rt2x00/rt2x00ht.c
@@ -60,9 +60,10 @@ void rt2x00ht_create_tx_descriptor(struct queue_entry *entry,
60 * when using more then one tx stream (>MCS7). 60 * when using more then one tx stream (>MCS7).
61 */ 61 */
62 if (tx_info->control.sta && txdesc->mcs > 7 && 62 if (tx_info->control.sta && txdesc->mcs > 7 &&
63 (tx_info->control.sta->ht_cap.cap & 63 ((tx_info->control.sta->ht_cap.cap &
64 (WLAN_HT_CAP_SM_PS_DYNAMIC << 64 IEEE80211_HT_CAP_SM_PS) >>
65 IEEE80211_HT_CAP_SM_PS_SHIFT))) 65 IEEE80211_HT_CAP_SM_PS_SHIFT) ==
66 WLAN_HT_CAP_SM_PS_DYNAMIC)
66 __set_bit(ENTRY_TXD_HT_MIMO_PS, &txdesc->flags); 67 __set_bit(ENTRY_TXD_HT_MIMO_PS, &txdesc->flags);
67 } else { 68 } else {
68 txdesc->mcs = rt2x00_get_rate_mcs(hwrate->mcs); 69 txdesc->mcs = rt2x00_get_rate_mcs(hwrate->mcs);
@@ -72,9 +73,11 @@ void rt2x00ht_create_tx_descriptor(struct queue_entry *entry,
72 73
73 74
74 /* 75 /*
75 * Convert flags 76 * This frame is eligible for an AMPDU, however, don't aggregate
77 * frames that are intended to probe a specific tx rate.
76 */ 78 */
77 if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) 79 if (tx_info->flags & IEEE80211_TX_CTL_AMPDU &&
80 !(tx_info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE))
78 __set_bit(ENTRY_TXD_HT_AMPDU, &txdesc->flags); 81 __set_bit(ENTRY_TXD_HT_AMPDU, &txdesc->flags);
79 82
80 /* 83 /*
@@ -84,7 +87,13 @@ void rt2x00ht_create_tx_descriptor(struct queue_entry *entry,
84 txdesc->rate_mode = RATE_MODE_HT_MIX; 87 txdesc->rate_mode = RATE_MODE_HT_MIX;
85 if (txrate->flags & IEEE80211_TX_RC_GREEN_FIELD) 88 if (txrate->flags & IEEE80211_TX_RC_GREEN_FIELD)
86 txdesc->rate_mode = RATE_MODE_HT_GREENFIELD; 89 txdesc->rate_mode = RATE_MODE_HT_GREENFIELD;
87 if (txrate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH) 90
91 /*
92 * Set 40Mhz mode if necessary (for legacy rates this will
93 * duplicate the frame to both channels).
94 */
95 if (txrate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH ||
96 txrate->flags & IEEE80211_TX_RC_DUP_DATA)
88 __set_bit(ENTRY_TXD_HT_BW_40, &txdesc->flags); 97 __set_bit(ENTRY_TXD_HT_BW_40, &txdesc->flags);
89 if (txrate->flags & IEEE80211_TX_RC_SHORT_GI) 98 if (txrate->flags & IEEE80211_TX_RC_SHORT_GI)
90 __set_bit(ENTRY_TXD_HT_SHORT_GI, &txdesc->flags); 99 __set_bit(ENTRY_TXD_HT_SHORT_GI, &txdesc->flags);
diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c
index 7862a840984..c3c206a97d5 100644
--- a/drivers/net/wireless/rt2x00/rt2x00mac.c
+++ b/drivers/net/wireless/rt2x00/rt2x00mac.c
@@ -671,7 +671,7 @@ void rt2x00mac_bss_info_changed(struct ieee80211_hw *hw,
671 */ 671 */
672 if (changes & (BSS_CHANGED_ERP_CTS_PROT | BSS_CHANGED_ERP_PREAMBLE | 672 if (changes & (BSS_CHANGED_ERP_CTS_PROT | BSS_CHANGED_ERP_PREAMBLE |
673 BSS_CHANGED_ERP_SLOT | BSS_CHANGED_BASIC_RATES | 673 BSS_CHANGED_ERP_SLOT | BSS_CHANGED_BASIC_RATES |
674 BSS_CHANGED_BEACON_INT)) 674 BSS_CHANGED_BEACON_INT | BSS_CHANGED_HT))
675 rt2x00lib_config_erp(rt2x00dev, intf, bss_conf, changes); 675 rt2x00lib_config_erp(rt2x00dev, intf, bss_conf, changes);
676} 676}
677EXPORT_SYMBOL_GPL(rt2x00mac_bss_info_changed); 677EXPORT_SYMBOL_GPL(rt2x00mac_bss_info_changed);
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c
index 97b3935f615..af548c87f10 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.c
+++ b/drivers/net/wireless/rt2x00/rt61pci.c
@@ -2630,12 +2630,13 @@ static int rt61pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
2630 * As rt61 has a global fallback table we cannot specify 2630 * As rt61 has a global fallback table we cannot specify
2631 * more then one tx rate per frame but since the hw will 2631 * more then one tx rate per frame but since the hw will
2632 * try several rates (based on the fallback table) we should 2632 * try several rates (based on the fallback table) we should
2633 * still initialize max_rates to the maximum number of rates 2633 * initialize max_report_rates to the maximum number of rates
2634 * we are going to try. Otherwise mac80211 will truncate our 2634 * we are going to try. Otherwise mac80211 will truncate our
2635 * reported tx rates and the rc algortihm will end up with 2635 * reported tx rates and the rc algortihm will end up with
2636 * incorrect data. 2636 * incorrect data.
2637 */ 2637 */
2638 rt2x00dev->hw->max_rates = 7; 2638 rt2x00dev->hw->max_rates = 1;
2639 rt2x00dev->hw->max_report_rates = 7;
2639 rt2x00dev->hw->max_rate_tries = 1; 2640 rt2x00dev->hw->max_rate_tries = 1;
2640 2641
2641 /* 2642 /*
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c
index e22f01c1818..9be8089317e 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.c
+++ b/drivers/net/wireless/rt2x00/rt73usb.c
@@ -2063,9 +2063,14 @@ static int rt73usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
2063 2063
2064 /* 2064 /*
2065 * Initialize all hw fields. 2065 * Initialize all hw fields.
2066 *
2067 * Don't set IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING unless we are
2068 * capable of sending the buffered frames out after the DTIM
2069 * transmission using rt2x00lib_beacondone. This will send out
2070 * multicast and broadcast traffic immediately instead of buffering it
2071 * infinitly and thus dropping it after some time.
2066 */ 2072 */
2067 rt2x00dev->hw->flags = 2073 rt2x00dev->hw->flags =
2068 IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
2069 IEEE80211_HW_SIGNAL_DBM | 2074 IEEE80211_HW_SIGNAL_DBM |
2070 IEEE80211_HW_SUPPORTS_PS | 2075 IEEE80211_HW_SUPPORTS_PS |
2071 IEEE80211_HW_PS_NULLFUNC_STACK; 2076 IEEE80211_HW_PS_NULLFUNC_STACK;
@@ -2365,6 +2370,7 @@ static struct usb_device_id rt73usb_device_table[] = {
2365 { USB_DEVICE(0x0411, 0x00f4), USB_DEVICE_DATA(&rt73usb_ops) }, 2370 { USB_DEVICE(0x0411, 0x00f4), USB_DEVICE_DATA(&rt73usb_ops) },
2366 { USB_DEVICE(0x0411, 0x0116), USB_DEVICE_DATA(&rt73usb_ops) }, 2371 { USB_DEVICE(0x0411, 0x0116), USB_DEVICE_DATA(&rt73usb_ops) },
2367 { USB_DEVICE(0x0411, 0x0119), USB_DEVICE_DATA(&rt73usb_ops) }, 2372 { USB_DEVICE(0x0411, 0x0119), USB_DEVICE_DATA(&rt73usb_ops) },
2373 { USB_DEVICE(0x0411, 0x0137), USB_DEVICE_DATA(&rt73usb_ops) },
2368 /* CEIVA */ 2374 /* CEIVA */
2369 { USB_DEVICE(0x178d, 0x02be), USB_DEVICE_DATA(&rt73usb_ops) }, 2375 { USB_DEVICE(0x178d, 0x02be), USB_DEVICE_DATA(&rt73usb_ops) },
2370 /* CNet */ 2376 /* CNet */
diff --git a/drivers/net/wireless/rtl818x/rtl8180_dev.c b/drivers/net/wireless/rtl818x/rtl8180_dev.c
index 05c6badbe20..707c688da61 100644
--- a/drivers/net/wireless/rtl818x/rtl8180_dev.c
+++ b/drivers/net/wireless/rtl818x/rtl8180_dev.c
@@ -99,66 +99,19 @@ void rtl8180_write_phy(struct ieee80211_hw *dev, u8 addr, u32 data)
99 } 99 }
100} 100}
101 101
102static void rtl8180_handle_tx(struct ieee80211_hw *dev) 102static void rtl8180_handle_rx(struct ieee80211_hw *dev)
103{ 103{
104 struct rtl8180_priv *priv = dev->priv; 104 struct rtl8180_priv *priv = dev->priv;
105 struct rtl8180_tx_ring *ring; 105 unsigned int count = 32;
106 int prio;
107
108 spin_lock(&priv->lock);
109
110 for (prio = 3; prio >= 0; prio--) {
111 ring = &priv->tx_ring[prio];
112
113 while (skb_queue_len(&ring->queue)) {
114 struct rtl8180_tx_desc *entry = &ring->desc[ring->idx];
115 struct sk_buff *skb;
116 struct ieee80211_tx_info *info;
117 u32 flags = le32_to_cpu(entry->flags);
118
119 if (flags & RTL818X_TX_DESC_FLAG_OWN)
120 break;
121
122 ring->idx = (ring->idx + 1) % ring->entries;
123 skb = __skb_dequeue(&ring->queue);
124 pci_unmap_single(priv->pdev, le32_to_cpu(entry->tx_buf),
125 skb->len, PCI_DMA_TODEVICE);
126
127 info = IEEE80211_SKB_CB(skb);
128 ieee80211_tx_info_clear_status(info);
129
130 if (!(info->flags & IEEE80211_TX_CTL_NO_ACK) &&
131 (flags & RTL818X_TX_DESC_FLAG_TX_OK))
132 info->flags |= IEEE80211_TX_STAT_ACK;
133
134 info->status.rates[0].count = (flags & 0xFF) + 1;
135 info->status.rates[1].idx = -1;
136
137 ieee80211_tx_status(dev, skb);
138 if (ring->entries - skb_queue_len(&ring->queue) == 2)
139 ieee80211_wake_queue(dev, prio);
140 }
141 }
142
143 spin_unlock(&priv->lock);
144}
145
146static int rtl8180_poll(struct ieee80211_hw *dev, int budget)
147{
148 struct rtl8180_priv *priv = dev->priv;
149 unsigned int count = 0;
150 u8 signal, agc, sq; 106 u8 signal, agc, sq;
151 107
152 /* handle pending Tx queue cleanup */ 108 while (count--) {
153 rtl8180_handle_tx(dev);
154
155 while (count++ < budget) {
156 struct rtl8180_rx_desc *entry = &priv->rx_ring[priv->rx_idx]; 109 struct rtl8180_rx_desc *entry = &priv->rx_ring[priv->rx_idx];
157 struct sk_buff *skb = priv->rx_buf[priv->rx_idx]; 110 struct sk_buff *skb = priv->rx_buf[priv->rx_idx];
158 u32 flags = le32_to_cpu(entry->flags); 111 u32 flags = le32_to_cpu(entry->flags);
159 112
160 if (flags & RTL818X_RX_DESC_FLAG_OWN) 113 if (flags & RTL818X_RX_DESC_FLAG_OWN)
161 break; 114 return;
162 115
163 if (unlikely(flags & (RTL818X_RX_DESC_FLAG_DMA_FAIL | 116 if (unlikely(flags & (RTL818X_RX_DESC_FLAG_DMA_FAIL |
164 RTL818X_RX_DESC_FLAG_FOF | 117 RTL818X_RX_DESC_FLAG_FOF |
@@ -198,7 +151,7 @@ static int rtl8180_poll(struct ieee80211_hw *dev, int budget)
198 rx_status.flag |= RX_FLAG_FAILED_FCS_CRC; 151 rx_status.flag |= RX_FLAG_FAILED_FCS_CRC;
199 152
200 memcpy(IEEE80211_SKB_RXCB(skb), &rx_status, sizeof(rx_status)); 153 memcpy(IEEE80211_SKB_RXCB(skb), &rx_status, sizeof(rx_status));
201 ieee80211_rx(dev, skb); 154 ieee80211_rx_irqsafe(dev, skb);
202 155
203 skb = new_skb; 156 skb = new_skb;
204 priv->rx_buf[priv->rx_idx] = skb; 157 priv->rx_buf[priv->rx_idx] = skb;
@@ -215,16 +168,41 @@ static int rtl8180_poll(struct ieee80211_hw *dev, int budget)
215 entry->flags |= cpu_to_le32(RTL818X_RX_DESC_FLAG_EOR); 168 entry->flags |= cpu_to_le32(RTL818X_RX_DESC_FLAG_EOR);
216 priv->rx_idx = (priv->rx_idx + 1) % 32; 169 priv->rx_idx = (priv->rx_idx + 1) % 32;
217 } 170 }
171}
172
173static void rtl8180_handle_tx(struct ieee80211_hw *dev, unsigned int prio)
174{
175 struct rtl8180_priv *priv = dev->priv;
176 struct rtl8180_tx_ring *ring = &priv->tx_ring[prio];
218 177
219 if (count < budget) { 178 while (skb_queue_len(&ring->queue)) {
220 /* disable polling */ 179 struct rtl8180_tx_desc *entry = &ring->desc[ring->idx];
221 ieee80211_napi_complete(dev); 180 struct sk_buff *skb;
181 struct ieee80211_tx_info *info;
182 u32 flags = le32_to_cpu(entry->flags);
222 183
223 /* enable interrupts */ 184 if (flags & RTL818X_TX_DESC_FLAG_OWN)
224 rtl818x_iowrite16(priv, &priv->map->INT_MASK, 0xFFFF); 185 return;
225 } 186
187 ring->idx = (ring->idx + 1) % ring->entries;
188 skb = __skb_dequeue(&ring->queue);
189 pci_unmap_single(priv->pdev, le32_to_cpu(entry->tx_buf),
190 skb->len, PCI_DMA_TODEVICE);
191
192 info = IEEE80211_SKB_CB(skb);
193 ieee80211_tx_info_clear_status(info);
194
195 if (!(info->flags & IEEE80211_TX_CTL_NO_ACK) &&
196 (flags & RTL818X_TX_DESC_FLAG_TX_OK))
197 info->flags |= IEEE80211_TX_STAT_ACK;
198
199 info->status.rates[0].count = (flags & 0xFF) + 1;
200 info->status.rates[1].idx = -1;
226 201
227 return count; 202 ieee80211_tx_status_irqsafe(dev, skb);
203 if (ring->entries - skb_queue_len(&ring->queue) == 2)
204 ieee80211_wake_queue(dev, prio);
205 }
228} 206}
229 207
230static irqreturn_t rtl8180_interrupt(int irq, void *dev_id) 208static irqreturn_t rtl8180_interrupt(int irq, void *dev_id)
@@ -233,17 +211,31 @@ static irqreturn_t rtl8180_interrupt(int irq, void *dev_id)
233 struct rtl8180_priv *priv = dev->priv; 211 struct rtl8180_priv *priv = dev->priv;
234 u16 reg; 212 u16 reg;
235 213
214 spin_lock(&priv->lock);
236 reg = rtl818x_ioread16(priv, &priv->map->INT_STATUS); 215 reg = rtl818x_ioread16(priv, &priv->map->INT_STATUS);
237 if (unlikely(reg == 0xFFFF)) 216 if (unlikely(reg == 0xFFFF)) {
217 spin_unlock(&priv->lock);
238 return IRQ_HANDLED; 218 return IRQ_HANDLED;
219 }
239 220
240 rtl818x_iowrite16(priv, &priv->map->INT_STATUS, reg); 221 rtl818x_iowrite16(priv, &priv->map->INT_STATUS, reg);
241 222
242 /* disable interrupts */ 223 if (reg & (RTL818X_INT_TXB_OK | RTL818X_INT_TXB_ERR))
243 rtl818x_iowrite16(priv, &priv->map->INT_MASK, 0); 224 rtl8180_handle_tx(dev, 3);
225
226 if (reg & (RTL818X_INT_TXH_OK | RTL818X_INT_TXH_ERR))
227 rtl8180_handle_tx(dev, 2);
228
229 if (reg & (RTL818X_INT_TXN_OK | RTL818X_INT_TXN_ERR))
230 rtl8180_handle_tx(dev, 1);
244 231
245 /* enable polling */ 232 if (reg & (RTL818X_INT_TXL_OK | RTL818X_INT_TXL_ERR))
246 ieee80211_napi_schedule(dev); 233 rtl8180_handle_tx(dev, 0);
234
235 if (reg & (RTL818X_INT_RX_OK | RTL818X_INT_RX_ERR))
236 rtl8180_handle_rx(dev);
237
238 spin_unlock(&priv->lock);
247 239
248 return IRQ_HANDLED; 240 return IRQ_HANDLED;
249} 241}
@@ -255,6 +247,7 @@ static int rtl8180_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
255 struct rtl8180_priv *priv = dev->priv; 247 struct rtl8180_priv *priv = dev->priv;
256 struct rtl8180_tx_ring *ring; 248 struct rtl8180_tx_ring *ring;
257 struct rtl8180_tx_desc *entry; 249 struct rtl8180_tx_desc *entry;
250 unsigned long flags;
258 unsigned int idx, prio; 251 unsigned int idx, prio;
259 dma_addr_t mapping; 252 dma_addr_t mapping;
260 u32 tx_flags; 253 u32 tx_flags;
@@ -301,7 +294,7 @@ static int rtl8180_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
301 plcp_len |= 1 << 15; 294 plcp_len |= 1 << 15;
302 } 295 }
303 296
304 spin_lock(&priv->lock); 297 spin_lock_irqsave(&priv->lock, flags);
305 298
306 if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) { 299 if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
307 if (info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT) 300 if (info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT)
@@ -325,7 +318,7 @@ static int rtl8180_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
325 if (ring->entries - skb_queue_len(&ring->queue) < 2) 318 if (ring->entries - skb_queue_len(&ring->queue) < 2)
326 ieee80211_stop_queue(dev, prio); 319 ieee80211_stop_queue(dev, prio);
327 320
328 spin_unlock(&priv->lock); 321 spin_unlock_irqrestore(&priv->lock, flags);
329 322
330 rtl818x_iowrite8(priv, &priv->map->TX_DMA_POLLING, (1 << (prio + 4))); 323 rtl818x_iowrite8(priv, &priv->map->TX_DMA_POLLING, (1 << (prio + 4)));
331 324
@@ -871,7 +864,6 @@ static const struct ieee80211_ops rtl8180_ops = {
871 .prepare_multicast = rtl8180_prepare_multicast, 864 .prepare_multicast = rtl8180_prepare_multicast,
872 .configure_filter = rtl8180_configure_filter, 865 .configure_filter = rtl8180_configure_filter,
873 .get_tsf = rtl8180_get_tsf, 866 .get_tsf = rtl8180_get_tsf,
874 .napi_poll = rtl8180_poll,
875}; 867};
876 868
877static void rtl8180_eeprom_register_read(struct eeprom_93cx6 *eeprom) 869static void rtl8180_eeprom_register_read(struct eeprom_93cx6 *eeprom)
@@ -1003,8 +995,6 @@ static int __devinit rtl8180_probe(struct pci_dev *pdev,
1003 dev->queues = 1; 995 dev->queues = 1;
1004 dev->max_signal = 65; 996 dev->max_signal = 65;
1005 997
1006 dev->napi_weight = 64;
1007
1008 reg = rtl818x_ioread32(priv, &priv->map->TX_CONF); 998 reg = rtl818x_ioread32(priv, &priv->map->TX_CONF);
1009 reg &= RTL818X_TX_CONF_HWVER_MASK; 999 reg &= RTL818X_TX_CONF_HWVER_MASK;
1010 switch (reg) { 1000 switch (reg) {
diff --git a/drivers/net/wireless/wl12xx/wl1271.h b/drivers/net/wireless/wl12xx/wl1271.h
index 4134f4495b9..8a4cd763e5a 100644
--- a/drivers/net/wireless/wl12xx/wl1271.h
+++ b/drivers/net/wireless/wl12xx/wl1271.h
@@ -117,10 +117,7 @@ enum {
117#define WL1271_TX_SECURITY_LO16(s) ((u16)((s) & 0xffff)) 117#define WL1271_TX_SECURITY_LO16(s) ((u16)((s) & 0xffff))
118#define WL1271_TX_SECURITY_HI32(s) ((u32)(((s) >> 16) & 0xffffffff)) 118#define WL1271_TX_SECURITY_HI32(s) ((u32)(((s) >> 16) & 0xffffffff))
119 119
120/* 120#define WL1271_CIPHER_SUITE_GEM 0x00147201
121 * Enable/disable 802.11a support for WL1273
122 */
123#undef WL1271_80211A_ENABLED
124 121
125#define WL1271_BUSY_WORD_CNT 1 122#define WL1271_BUSY_WORD_CNT 1
126#define WL1271_BUSY_WORD_LEN (WL1271_BUSY_WORD_CNT * sizeof(u32)) 123#define WL1271_BUSY_WORD_LEN (WL1271_BUSY_WORD_CNT * sizeof(u32))
@@ -133,6 +130,8 @@ enum {
133 130
134#define ACX_TX_DESCRIPTORS 32 131#define ACX_TX_DESCRIPTORS 32
135 132
133#define WL1271_AGGR_BUFFER_SIZE (4 * PAGE_SIZE)
134
136enum wl1271_state { 135enum wl1271_state {
137 WL1271_STATE_OFF, 136 WL1271_STATE_OFF,
138 WL1271_STATE_ON, 137 WL1271_STATE_ON,
@@ -301,6 +300,7 @@ struct wl1271_rx_mem_pool_addr {
301struct wl1271_scan { 300struct wl1271_scan {
302 struct cfg80211_scan_request *req; 301 struct cfg80211_scan_request *req;
303 bool *scanned_ch; 302 bool *scanned_ch;
303 bool failed;
304 u8 state; 304 u8 state;
305 u8 ssid[IW_ESSID_MAX_SIZE+1]; 305 u8 ssid[IW_ESSID_MAX_SIZE+1];
306 size_t ssid_len; 306 size_t ssid_len;
@@ -350,6 +350,7 @@ struct wl1271 {
350#define WL1271_FLAG_IDLE (10) 350#define WL1271_FLAG_IDLE (10)
351#define WL1271_FLAG_IDLE_REQUESTED (11) 351#define WL1271_FLAG_IDLE_REQUESTED (11)
352#define WL1271_FLAG_PSPOLL_FAILURE (12) 352#define WL1271_FLAG_PSPOLL_FAILURE (12)
353#define WL1271_FLAG_STA_STATE_SENT (13)
353 unsigned long flags; 354 unsigned long flags;
354 355
355 struct wl1271_partition_set part; 356 struct wl1271_partition_set part;
@@ -362,6 +363,7 @@ struct wl1271 {
362 u8 *fw; 363 u8 *fw;
363 size_t fw_len; 364 size_t fw_len;
364 struct wl1271_nvs_file *nvs; 365 struct wl1271_nvs_file *nvs;
366 size_t nvs_len;
365 367
366 s8 hw_pg_ver; 368 s8 hw_pg_ver;
367 369
@@ -408,9 +410,15 @@ struct wl1271 {
408 /* Rx memory pool address */ 410 /* Rx memory pool address */
409 struct wl1271_rx_mem_pool_addr rx_mem_pool_addr; 411 struct wl1271_rx_mem_pool_addr rx_mem_pool_addr;
410 412
413 /* Intermediate buffer, used for packet aggregation */
414 u8 *aggr_buf;
415
411 /* The target interrupt mask */ 416 /* The target interrupt mask */
412 struct work_struct irq_work; 417 struct work_struct irq_work;
413 418
419 /* Hardware recovery work */
420 struct work_struct recovery_work;
421
414 /* The mbox event mask */ 422 /* The mbox event mask */
415 u32 event_mask; 423 u32 event_mask;
416 424
@@ -419,6 +427,7 @@ struct wl1271 {
419 427
420 /* Are we currently scanning */ 428 /* Are we currently scanning */
421 struct wl1271_scan scan; 429 struct wl1271_scan scan;
430 struct delayed_work scan_complete_work;
422 431
423 /* Our association ID */ 432 /* Our association ID */
424 u16 aid; 433 u16 aid;
@@ -475,6 +484,8 @@ struct wl1271 {
475 484
476 bool sg_enabled; 485 bool sg_enabled;
477 486
487 bool enable_11a;
488
478 struct list_head list; 489 struct list_head list;
479 490
480 /* Most recently reported noise in dBm */ 491 /* Most recently reported noise in dBm */
@@ -498,14 +509,4 @@ int wl1271_plt_stop(struct wl1271 *wl);
498#define WL1271_PRE_POWER_ON_SLEEP 20 /* in miliseconds */ 509#define WL1271_PRE_POWER_ON_SLEEP 20 /* in miliseconds */
499#define WL1271_POWER_ON_SLEEP 200 /* in miliseconds */ 510#define WL1271_POWER_ON_SLEEP 200 /* in miliseconds */
500 511
501static inline bool wl1271_11a_enabled(void)
502{
503 /* FIXME: this could be determined based on the NVS-INI file */
504#ifdef WL1271_80211A_ENABLED
505 return true;
506#else
507 return false;
508#endif
509}
510
511#endif 512#endif
diff --git a/drivers/net/wireless/wl12xx/wl1271_acx.c b/drivers/net/wireless/wl12xx/wl1271_acx.c
index f03ad088db8..61899340526 100644
--- a/drivers/net/wireless/wl12xx/wl1271_acx.c
+++ b/drivers/net/wireless/wl12xx/wl1271_acx.c
@@ -86,40 +86,6 @@ out:
86 return ret; 86 return ret;
87} 87}
88 88
89int wl1271_acx_fw_version(struct wl1271 *wl, char *buf, size_t len)
90{
91 struct acx_revision *rev;
92 int ret;
93
94 wl1271_debug(DEBUG_ACX, "acx fw rev");
95
96 rev = kzalloc(sizeof(*rev), GFP_KERNEL);
97 if (!rev) {
98 ret = -ENOMEM;
99 goto out;
100 }
101
102 ret = wl1271_cmd_interrogate(wl, ACX_FW_REV, rev, sizeof(*rev));
103 if (ret < 0) {
104 wl1271_warning("ACX_FW_REV interrogate failed");
105 goto out;
106 }
107
108 /* be careful with the buffer sizes */
109 strncpy(buf, rev->fw_version, min(len, sizeof(rev->fw_version)));
110
111 /*
112 * if the firmware version string is exactly
113 * sizeof(rev->fw_version) long or fw_len is less than
114 * sizeof(rev->fw_version) it won't be null terminated
115 */
116 buf[min(len, sizeof(rev->fw_version)) - 1] = '\0';
117
118out:
119 kfree(rev);
120 return ret;
121}
122
123int wl1271_acx_tx_power(struct wl1271 *wl, int power) 89int wl1271_acx_tx_power(struct wl1271 *wl, int power)
124{ 90{
125 struct acx_current_tx_power *acx; 91 struct acx_current_tx_power *acx;
diff --git a/drivers/net/wireless/wl12xx/wl1271_acx.h b/drivers/net/wireless/wl12xx/wl1271_acx.h
index 4235bc56f75..ebb341d36e8 100644
--- a/drivers/net/wireless/wl12xx/wl1271_acx.h
+++ b/drivers/net/wireless/wl12xx/wl1271_acx.h
@@ -100,35 +100,6 @@ struct acx_error_counter {
100 __le32 seq_num_miss; 100 __le32 seq_num_miss;
101} __packed; 101} __packed;
102 102
103struct acx_revision {
104 struct acx_header header;
105
106 /*
107 * The WiLink firmware version, an ASCII string x.x.x.x,
108 * that uniquely identifies the current firmware.
109 * The left most digit is incremented each time a
110 * significant change is made to the firmware, such as
111 * code redesign or new platform support.
112 * The second digit is incremented when major enhancements
113 * are added or major fixes are made.
114 * The third digit is incremented for each GA release.
115 * The fourth digit is incremented for each build.
116 * The first two digits identify a firmware release version,
117 * in other words, a unique set of features.
118 * The first three digits identify a GA release.
119 */
120 char fw_version[20];
121
122 /*
123 * This 4 byte field specifies the WiLink hardware version.
124 * bits 0 - 15: Reserved.
125 * bits 16 - 23: Version ID - The WiLink version ID
126 * (1 = first spin, 2 = second spin, and so on).
127 * bits 24 - 31: Chip ID - The WiLink chip ID.
128 */
129 __le32 hw_version;
130} __packed;
131
132enum wl1271_psm_mode { 103enum wl1271_psm_mode {
133 /* Active mode */ 104 /* Active mode */
134 WL1271_PSM_CAM = 0, 105 WL1271_PSM_CAM = 0,
@@ -1060,7 +1031,6 @@ enum {
1060 ACX_PEER_HT_CAP = 0x0057, 1031 ACX_PEER_HT_CAP = 0x0057,
1061 ACX_HT_BSS_OPERATION = 0x0058, 1032 ACX_HT_BSS_OPERATION = 0x0058,
1062 ACX_COEX_ACTIVITY = 0x0059, 1033 ACX_COEX_ACTIVITY = 0x0059,
1063 ACX_SET_SMART_REFLEX_DEBUG = 0x005A,
1064 ACX_SET_DCO_ITRIM_PARAMS = 0x0061, 1034 ACX_SET_DCO_ITRIM_PARAMS = 0x0061,
1065 DOT11_RX_MSDU_LIFE_TIME = 0x1004, 1035 DOT11_RX_MSDU_LIFE_TIME = 0x1004,
1066 DOT11_CUR_TX_PWR = 0x100D, 1036 DOT11_CUR_TX_PWR = 0x100D,
@@ -1077,7 +1047,6 @@ enum {
1077 1047
1078int wl1271_acx_wake_up_conditions(struct wl1271 *wl); 1048int wl1271_acx_wake_up_conditions(struct wl1271 *wl);
1079int wl1271_acx_sleep_auth(struct wl1271 *wl, u8 sleep_auth); 1049int wl1271_acx_sleep_auth(struct wl1271 *wl, u8 sleep_auth);
1080int wl1271_acx_fw_version(struct wl1271 *wl, char *buf, size_t len);
1081int wl1271_acx_tx_power(struct wl1271 *wl, int power); 1050int wl1271_acx_tx_power(struct wl1271 *wl, int power);
1082int wl1271_acx_feature_cfg(struct wl1271 *wl); 1051int wl1271_acx_feature_cfg(struct wl1271 *wl);
1083int wl1271_acx_mem_map(struct wl1271 *wl, 1052int wl1271_acx_mem_map(struct wl1271 *wl,
diff --git a/drivers/net/wireless/wl12xx/wl1271_boot.c b/drivers/net/wireless/wl12xx/wl1271_boot.c
index e5a7f042645..b9102124209 100644
--- a/drivers/net/wireless/wl12xx/wl1271_boot.c
+++ b/drivers/net/wireless/wl12xx/wl1271_boot.c
@@ -225,6 +225,28 @@ static int wl1271_boot_upload_nvs(struct wl1271 *wl)
225 if (wl->nvs == NULL) 225 if (wl->nvs == NULL)
226 return -ENODEV; 226 return -ENODEV;
227 227
228 /*
229 * FIXME: the LEGACY NVS image support (NVS's missing the 5GHz band
230 * configurations) can be removed when those NVS files stop floating
231 * around.
232 */
233 if (wl->nvs_len == sizeof(struct wl1271_nvs_file) ||
234 wl->nvs_len == WL1271_INI_LEGACY_NVS_FILE_SIZE) {
235 if (wl->nvs->general_params.dual_mode_select)
236 wl->enable_11a = true;
237 }
238
239 if (wl->nvs_len != sizeof(struct wl1271_nvs_file) &&
240 (wl->nvs_len != WL1271_INI_LEGACY_NVS_FILE_SIZE ||
241 wl->enable_11a)) {
242 wl1271_error("nvs size is not as expected: %zu != %zu",
243 wl->nvs_len, sizeof(struct wl1271_nvs_file));
244 kfree(wl->nvs);
245 wl->nvs = NULL;
246 wl->nvs_len = 0;
247 return -EILSEQ;
248 }
249
228 /* only the first part of the NVS needs to be uploaded */ 250 /* only the first part of the NVS needs to be uploaded */
229 nvs_len = sizeof(wl->nvs->nvs); 251 nvs_len = sizeof(wl->nvs->nvs);
230 nvs_ptr = (u8 *)wl->nvs->nvs; 252 nvs_ptr = (u8 *)wl->nvs->nvs;
@@ -251,8 +273,10 @@ static int wl1271_boot_upload_nvs(struct wl1271 *wl)
251 burst_len = nvs_ptr[0]; 273 burst_len = nvs_ptr[0];
252 dest_addr = (nvs_ptr[1] & 0xfe) | ((u32)(nvs_ptr[2] << 8)); 274 dest_addr = (nvs_ptr[1] & 0xfe) | ((u32)(nvs_ptr[2] << 8));
253 275
254 /* FIXME: Due to our new wl1271_translate_reg_addr function, 276 /*
255 we need to add the REGISTER_BASE to the destination */ 277 * Due to our new wl1271_translate_reg_addr function,
278 * we need to add the REGISTER_BASE to the destination
279 */
256 dest_addr += REGISTERS_BASE; 280 dest_addr += REGISTERS_BASE;
257 281
258 /* We move our pointer to the data */ 282 /* We move our pointer to the data */
@@ -280,8 +304,6 @@ static int wl1271_boot_upload_nvs(struct wl1271 *wl)
280 ALIGN(nvs_ptr - (u8 *)wl->nvs->nvs + 7, 4); 304 ALIGN(nvs_ptr - (u8 *)wl->nvs->nvs + 7, 4);
281 nvs_len -= nvs_ptr - (u8 *)wl->nvs->nvs; 305 nvs_len -= nvs_ptr - (u8 *)wl->nvs->nvs;
282 306
283 /* FIXME: The driver sets the partition here, but this is not needed,
284 since it sets to the same one as currently in use */
285 /* Now we must set the partition correctly */ 307 /* Now we must set the partition correctly */
286 wl1271_set_partition(wl, &part_table[PART_WORK]); 308 wl1271_set_partition(wl, &part_table[PART_WORK]);
287 309
@@ -291,9 +313,6 @@ static int wl1271_boot_upload_nvs(struct wl1271 *wl)
291 return -ENOMEM; 313 return -ENOMEM;
292 314
293 /* And finally we upload the NVS tables */ 315 /* And finally we upload the NVS tables */
294 /* FIXME: In wl1271, we upload everything at once.
295 No endianness handling needed here?! The ref driver doesn't do
296 anything about it at this point */
297 wl1271_write(wl, CMD_MBOX_ADDRESS, nvs_aligned, nvs_len, false); 316 wl1271_write(wl, CMD_MBOX_ADDRESS, nvs_aligned, nvs_len, false);
298 317
299 kfree(nvs_aligned); 318 kfree(nvs_aligned);
@@ -491,10 +510,7 @@ int wl1271_boot(struct wl1271 *wl)
491 510
492 wl1271_debug(DEBUG_BOOT, "pause1 0x%x", pause); 511 wl1271_debug(DEBUG_BOOT, "pause1 0x%x", pause);
493 512
494 pause &= ~(WU_COUNTER_PAUSE_VAL); /* FIXME: This should probably be 513 pause &= ~(WU_COUNTER_PAUSE_VAL);
495 * WU_COUNTER_PAUSE_VAL instead of
496 * 0x3ff (magic number ). How does
497 * this work?! */
498 pause |= WU_COUNTER_PAUSE_VAL; 514 pause |= WU_COUNTER_PAUSE_VAL;
499 wl1271_write32(wl, WU_COUNTER_PAUSE, pause); 515 wl1271_write32(wl, WU_COUNTER_PAUSE, pause);
500 516
@@ -548,7 +564,6 @@ int wl1271_boot(struct wl1271 *wl)
548 if (ret < 0) 564 if (ret < 0)
549 goto out; 565 goto out;
550 566
551 /* FIXME: Need to check whether this is really what we want */
552 wl1271_write32(wl, ACX_REG_INTERRUPT_MASK, 567 wl1271_write32(wl, ACX_REG_INTERRUPT_MASK,
553 WL1271_ACX_ALL_EVENTS_VECTOR); 568 WL1271_ACX_ALL_EVENTS_VECTOR);
554 569
diff --git a/drivers/net/wireless/wl12xx/wl1271_cmd.c b/drivers/net/wireless/wl12xx/wl1271_cmd.c
index ce503ddd5a4..5d3e8485ea4 100644
--- a/drivers/net/wireless/wl12xx/wl1271_cmd.c
+++ b/drivers/net/wireless/wl12xx/wl1271_cmd.c
@@ -94,6 +94,7 @@ int wl1271_cmd_send(struct wl1271 *wl, u16 id, void *buf, size_t len,
94 status = le16_to_cpu(cmd->status); 94 status = le16_to_cpu(cmd->status);
95 if (status != CMD_STATUS_SUCCESS) { 95 if (status != CMD_STATUS_SUCCESS) {
96 wl1271_error("command execute failure %d", status); 96 wl1271_error("command execute failure %d", status);
97 ieee80211_queue_work(wl->hw, &wl->recovery_work);
97 ret = -EIO; 98 ret = -EIO;
98 } 99 }
99 100
@@ -107,6 +108,8 @@ out:
107int wl1271_cmd_general_parms(struct wl1271 *wl) 108int wl1271_cmd_general_parms(struct wl1271 *wl)
108{ 109{
109 struct wl1271_general_parms_cmd *gen_parms; 110 struct wl1271_general_parms_cmd *gen_parms;
111 struct wl1271_ini_general_params *gp = &wl->nvs->general_params;
112 bool answer = false;
110 int ret; 113 int ret;
111 114
112 if (!wl->nvs) 115 if (!wl->nvs)
@@ -118,13 +121,24 @@ int wl1271_cmd_general_parms(struct wl1271 *wl)
118 121
119 gen_parms->test.id = TEST_CMD_INI_FILE_GENERAL_PARAM; 122 gen_parms->test.id = TEST_CMD_INI_FILE_GENERAL_PARAM;
120 123
121 memcpy(&gen_parms->general_params, &wl->nvs->general_params, 124 memcpy(&gen_parms->general_params, gp, sizeof(*gp));
122 sizeof(struct wl1271_ini_general_params));
123 125
124 ret = wl1271_cmd_test(wl, gen_parms, sizeof(*gen_parms), 0); 126 if (gp->tx_bip_fem_auto_detect)
125 if (ret < 0) 127 answer = true;
128
129 ret = wl1271_cmd_test(wl, gen_parms, sizeof(*gen_parms), answer);
130 if (ret < 0) {
126 wl1271_warning("CMD_INI_FILE_GENERAL_PARAM failed"); 131 wl1271_warning("CMD_INI_FILE_GENERAL_PARAM failed");
132 goto out;
133 }
134
135 gp->tx_bip_fem_manufacturer =
136 gen_parms->general_params.tx_bip_fem_manufacturer;
137
138 wl1271_debug(DEBUG_CMD, "FEM autodetect: %s, manufacturer: %d\n",
139 answer ? "auto" : "manual", gp->tx_bip_fem_manufacturer);
127 140
141out:
128 kfree(gen_parms); 142 kfree(gen_parms);
129 return ret; 143 return ret;
130} 144}
@@ -170,6 +184,39 @@ int wl1271_cmd_radio_parms(struct wl1271 *wl)
170 return ret; 184 return ret;
171} 185}
172 186
187int wl1271_cmd_ext_radio_parms(struct wl1271 *wl)
188{
189 struct wl1271_ext_radio_parms_cmd *ext_radio_parms;
190 struct conf_rf_settings *rf = &wl->conf.rf;
191 int ret;
192
193 if (!wl->nvs)
194 return -ENODEV;
195
196 ext_radio_parms = kzalloc(sizeof(*ext_radio_parms), GFP_KERNEL);
197 if (!ext_radio_parms)
198 return -ENOMEM;
199
200 ext_radio_parms->test.id = TEST_CMD_INI_FILE_RF_EXTENDED_PARAM;
201
202 memcpy(ext_radio_parms->tx_per_channel_power_compensation_2,
203 rf->tx_per_channel_power_compensation_2,
204 CONF_TX_PWR_COMPENSATION_LEN_2);
205 memcpy(ext_radio_parms->tx_per_channel_power_compensation_5,
206 rf->tx_per_channel_power_compensation_5,
207 CONF_TX_PWR_COMPENSATION_LEN_5);
208
209 wl1271_dump(DEBUG_CMD, "TEST_CMD_INI_FILE_EXT_RADIO_PARAM: ",
210 ext_radio_parms, sizeof(*ext_radio_parms));
211
212 ret = wl1271_cmd_test(wl, ext_radio_parms, sizeof(*ext_radio_parms), 0);
213 if (ret < 0)
214 wl1271_warning("TEST_CMD_INI_FILE_RF_EXTENDED_PARAM failed");
215
216 kfree(ext_radio_parms);
217 return ret;
218}
219
173/* 220/*
174 * Poll the mailbox event field until any of the bits in the mask is set or a 221 * Poll the mailbox event field until any of the bits in the mask is set or a
175 * timeout occurs (WL1271_EVENT_TIMEOUT in msecs) 222 * timeout occurs (WL1271_EVENT_TIMEOUT in msecs)
@@ -182,8 +229,10 @@ static int wl1271_cmd_wait_for_event(struct wl1271 *wl, u32 mask)
182 timeout = jiffies + msecs_to_jiffies(WL1271_EVENT_TIMEOUT); 229 timeout = jiffies + msecs_to_jiffies(WL1271_EVENT_TIMEOUT);
183 230
184 do { 231 do {
185 if (time_after(jiffies, timeout)) 232 if (time_after(jiffies, timeout)) {
233 ieee80211_queue_work(wl->hw, &wl->recovery_work);
186 return -ETIMEDOUT; 234 return -ETIMEDOUT;
235 }
187 236
188 msleep(1); 237 msleep(1);
189 238
@@ -390,18 +439,11 @@ out:
390 return ret; 439 return ret;
391} 440}
392 441
393int wl1271_cmd_ps_mode(struct wl1271 *wl, u8 ps_mode, bool send) 442int wl1271_cmd_ps_mode(struct wl1271 *wl, u8 ps_mode, u32 rates, bool send)
394{ 443{
395 struct wl1271_cmd_ps_params *ps_params = NULL; 444 struct wl1271_cmd_ps_params *ps_params = NULL;
396 int ret = 0; 445 int ret = 0;
397 446
398 /* FIXME: this should be in ps.c */
399 ret = wl1271_acx_wake_up_conditions(wl);
400 if (ret < 0) {
401 wl1271_error("couldn't set wake up conditions");
402 goto out;
403 }
404
405 wl1271_debug(DEBUG_CMD, "cmd set ps mode"); 447 wl1271_debug(DEBUG_CMD, "cmd set ps mode");
406 448
407 ps_params = kzalloc(sizeof(*ps_params), GFP_KERNEL); 449 ps_params = kzalloc(sizeof(*ps_params), GFP_KERNEL);
@@ -412,9 +454,9 @@ int wl1271_cmd_ps_mode(struct wl1271 *wl, u8 ps_mode, bool send)
412 454
413 ps_params->ps_mode = ps_mode; 455 ps_params->ps_mode = ps_mode;
414 ps_params->send_null_data = send; 456 ps_params->send_null_data = send;
415 ps_params->retries = 5; 457 ps_params->retries = wl->conf.conn.psm_entry_nullfunc_retries;
416 ps_params->hang_over_period = 1; 458 ps_params->hang_over_period = wl->conf.conn.psm_entry_hangover_period;
417 ps_params->null_data_rate = cpu_to_le32(wl->basic_rate_set); 459 ps_params->null_data_rate = cpu_to_le32(rates);
418 460
419 ret = wl1271_cmd_send(wl, CMD_SET_PS_MODE, ps_params, 461 ret = wl1271_cmd_send(wl, CMD_SET_PS_MODE, ps_params,
420 sizeof(*ps_params), 0); 462 sizeof(*ps_params), 0);
@@ -428,41 +470,6 @@ out:
428 return ret; 470 return ret;
429} 471}
430 472
431int wl1271_cmd_read_memory(struct wl1271 *wl, u32 addr, void *answer,
432 size_t len)
433{
434 struct cmd_read_write_memory *cmd;
435 int ret = 0;
436
437 wl1271_debug(DEBUG_CMD, "cmd read memory");
438
439 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
440 if (!cmd) {
441 ret = -ENOMEM;
442 goto out;
443 }
444
445 WARN_ON(len > MAX_READ_SIZE);
446 len = min_t(size_t, len, MAX_READ_SIZE);
447
448 cmd->addr = cpu_to_le32(addr);
449 cmd->size = cpu_to_le32(len);
450
451 ret = wl1271_cmd_send(wl, CMD_READ_MEMORY, cmd, sizeof(*cmd),
452 sizeof(*cmd));
453 if (ret < 0) {
454 wl1271_error("read memory command failed: %d", ret);
455 goto out;
456 }
457
458 /* the read command got in */
459 memcpy(answer, cmd->value, len);
460
461out:
462 kfree(cmd);
463 return ret;
464}
465
466int wl1271_cmd_template_set(struct wl1271 *wl, u16 template_id, 473int wl1271_cmd_template_set(struct wl1271 *wl, u16 template_id,
467 void *buf, size_t buf_len, int index, u32 rates) 474 void *buf, size_t buf_len, int index, u32 rates)
468{ 475{
@@ -523,7 +530,7 @@ int wl1271_cmd_build_null_data(struct wl1271 *wl)
523 } 530 }
524 531
525 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_NULL_DATA, ptr, size, 0, 532 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_NULL_DATA, ptr, size, 0,
526 WL1271_RATE_AUTOMATIC); 533 wl->basic_rate);
527 534
528out: 535out:
529 dev_kfree_skb(skb); 536 dev_kfree_skb(skb);
@@ -546,7 +553,7 @@ int wl1271_cmd_build_klv_null_data(struct wl1271 *wl)
546 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_KLV, 553 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_KLV,
547 skb->data, skb->len, 554 skb->data, skb->len,
548 CMD_TEMPL_KLV_IDX_NULL_DATA, 555 CMD_TEMPL_KLV_IDX_NULL_DATA,
549 WL1271_RATE_AUTOMATIC); 556 wl->basic_rate);
550 557
551out: 558out:
552 dev_kfree_skb(skb); 559 dev_kfree_skb(skb);
@@ -623,7 +630,7 @@ int wl1271_build_qos_null_data(struct wl1271 *wl)
623 630
624 return wl1271_cmd_template_set(wl, CMD_TEMPL_QOS_NULL_DATA, &template, 631 return wl1271_cmd_template_set(wl, CMD_TEMPL_QOS_NULL_DATA, &template,
625 sizeof(template), 0, 632 sizeof(template), 0,
626 WL1271_RATE_AUTOMATIC); 633 wl->basic_rate);
627} 634}
628 635
629int wl1271_cmd_set_default_wep_key(struct wl1271 *wl, u8 id) 636int wl1271_cmd_set_default_wep_key(struct wl1271 *wl, u8 id)
@@ -746,3 +753,31 @@ out_free:
746out: 753out:
747 return ret; 754 return ret;
748} 755}
756
757int wl1271_cmd_set_sta_state(struct wl1271 *wl)
758{
759 struct wl1271_cmd_set_sta_state *cmd;
760 int ret = 0;
761
762 wl1271_debug(DEBUG_CMD, "cmd set sta state");
763
764 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
765 if (!cmd) {
766 ret = -ENOMEM;
767 goto out;
768 }
769
770 cmd->state = WL1271_CMD_STA_STATE_CONNECTED;
771
772 ret = wl1271_cmd_send(wl, CMD_SET_STA_STATE, cmd, sizeof(*cmd), 0);
773 if (ret < 0) {
774 wl1271_error("failed to send set STA state command");
775 goto out_free;
776 }
777
778out_free:
779 kfree(cmd);
780
781out:
782 return ret;
783}
diff --git a/drivers/net/wireless/wl12xx/wl1271_cmd.h b/drivers/net/wireless/wl12xx/wl1271_cmd.h
index af577ee8eb0..a0caf4fc37b 100644
--- a/drivers/net/wireless/wl12xx/wl1271_cmd.h
+++ b/drivers/net/wireless/wl12xx/wl1271_cmd.h
@@ -33,12 +33,13 @@ int wl1271_cmd_send(struct wl1271 *wl, u16 id, void *buf, size_t len,
33 size_t res_len); 33 size_t res_len);
34int wl1271_cmd_general_parms(struct wl1271 *wl); 34int wl1271_cmd_general_parms(struct wl1271 *wl);
35int wl1271_cmd_radio_parms(struct wl1271 *wl); 35int wl1271_cmd_radio_parms(struct wl1271 *wl);
36int wl1271_cmd_ext_radio_parms(struct wl1271 *wl);
36int wl1271_cmd_join(struct wl1271 *wl, u8 bss_type); 37int wl1271_cmd_join(struct wl1271 *wl, u8 bss_type);
37int wl1271_cmd_test(struct wl1271 *wl, void *buf, size_t buf_len, u8 answer); 38int wl1271_cmd_test(struct wl1271 *wl, void *buf, size_t buf_len, u8 answer);
38int wl1271_cmd_interrogate(struct wl1271 *wl, u16 id, void *buf, size_t len); 39int wl1271_cmd_interrogate(struct wl1271 *wl, u16 id, void *buf, size_t len);
39int wl1271_cmd_configure(struct wl1271 *wl, u16 id, void *buf, size_t len); 40int wl1271_cmd_configure(struct wl1271 *wl, u16 id, void *buf, size_t len);
40int wl1271_cmd_data_path(struct wl1271 *wl, bool enable); 41int wl1271_cmd_data_path(struct wl1271 *wl, bool enable);
41int wl1271_cmd_ps_mode(struct wl1271 *wl, u8 ps_mode, bool send); 42int wl1271_cmd_ps_mode(struct wl1271 *wl, u8 ps_mode, u32 rates, bool send);
42int wl1271_cmd_read_memory(struct wl1271 *wl, u32 addr, void *answer, 43int wl1271_cmd_read_memory(struct wl1271 *wl, u32 addr, void *answer,
43 size_t len); 44 size_t len);
44int wl1271_cmd_template_set(struct wl1271 *wl, u16 template_id, 45int wl1271_cmd_template_set(struct wl1271 *wl, u16 template_id,
@@ -55,6 +56,7 @@ int wl1271_cmd_set_key(struct wl1271 *wl, u16 action, u8 id, u8 key_type,
55 u8 key_size, const u8 *key, const u8 *addr, 56 u8 key_size, const u8 *key, const u8 *addr,
56 u32 tx_seq_32, u16 tx_seq_16); 57 u32 tx_seq_32, u16 tx_seq_16);
57int wl1271_cmd_disconnect(struct wl1271 *wl); 58int wl1271_cmd_disconnect(struct wl1271 *wl);
59int wl1271_cmd_set_sta_state(struct wl1271 *wl);
58 60
59enum wl1271_commands { 61enum wl1271_commands {
60 CMD_INTERROGATE = 1, /*use this to read information elements*/ 62 CMD_INTERROGATE = 1, /*use this to read information elements*/
@@ -160,41 +162,6 @@ enum {
160 MAX_COMMAND_STATUS = 0xff 162 MAX_COMMAND_STATUS = 0xff
161}; 163};
162 164
163
164/*
165 * CMD_READ_MEMORY
166 *
167 * The host issues this command to read the WiLink device memory/registers.
168 *
169 * Note: The Base Band address has special handling (16 bits registers and
170 * addresses). For more information, see the hardware specification.
171 */
172/*
173 * CMD_WRITE_MEMORY
174 *
175 * The host issues this command to write the WiLink device memory/registers.
176 *
177 * The Base Band address has special handling (16 bits registers and
178 * addresses). For more information, see the hardware specification.
179 */
180#define MAX_READ_SIZE 256
181
182struct cmd_read_write_memory {
183 struct wl1271_cmd_header header;
184
185 /* The address of the memory to read from or write to.*/
186 __le32 addr;
187
188 /* The amount of data in bytes to read from or write to the WiLink
189 * device.*/
190 __le32 size;
191
192 /* The actual value read from or written to the Wilink. The source
193 of this field is the Host in WRITE command or the Wilink in READ
194 command. */
195 u8 value[MAX_READ_SIZE];
196} __packed;
197
198#define CMDMBOX_HEADER_LEN 4 165#define CMDMBOX_HEADER_LEN 4
199#define CMDMBOX_INFO_ELEM_HEADER_LEN 4 166#define CMDMBOX_INFO_ELEM_HEADER_LEN 4
200 167
@@ -313,7 +280,7 @@ enum wl1271_cmd_key_type {
313 KEY_WEP = 1, 280 KEY_WEP = 1,
314 KEY_TKIP = 2, 281 KEY_TKIP = 2,
315 KEY_AES = 3, 282 KEY_AES = 3,
316 KEY_GEM = 4 283 KEY_GEM = 4,
317}; 284};
318 285
319/* FIXME: Add description for key-types */ 286/* FIXME: Add description for key-types */
@@ -358,13 +325,14 @@ enum wl1271_channel_tune_bands {
358 WL1271_CHANNEL_TUNE_BAND_4_9 325 WL1271_CHANNEL_TUNE_BAND_4_9
359}; 326};
360 327
361#define WL1271_PD_REFERENCE_POINT_BAND_B_G 0 328#define WL1271_PD_REFERENCE_POINT_BAND_B_G 0
362 329
363#define TEST_CMD_P2G_CAL 0x02 330#define TEST_CMD_P2G_CAL 0x02
364#define TEST_CMD_CHANNEL_TUNE 0x0d 331#define TEST_CMD_CHANNEL_TUNE 0x0d
365#define TEST_CMD_UPDATE_PD_REFERENCE_POINT 0x1d 332#define TEST_CMD_UPDATE_PD_REFERENCE_POINT 0x1d
366#define TEST_CMD_INI_FILE_RADIO_PARAM 0x19 333#define TEST_CMD_INI_FILE_RADIO_PARAM 0x19
367#define TEST_CMD_INI_FILE_GENERAL_PARAM 0x1E 334#define TEST_CMD_INI_FILE_GENERAL_PARAM 0x1E
335#define TEST_CMD_INI_FILE_RF_EXTENDED_PARAM 0x26
368 336
369struct wl1271_general_parms_cmd { 337struct wl1271_general_parms_cmd {
370 struct wl1271_cmd_header header; 338 struct wl1271_cmd_header header;
@@ -397,6 +365,16 @@ struct wl1271_radio_parms_cmd {
397 u8 padding3[2]; 365 u8 padding3[2];
398} __packed; 366} __packed;
399 367
368struct wl1271_ext_radio_parms_cmd {
369 struct wl1271_cmd_header header;
370
371 struct wl1271_cmd_test_header test;
372
373 u8 tx_per_channel_power_compensation_2[CONF_TX_PWR_COMPENSATION_LEN_2];
374 u8 tx_per_channel_power_compensation_5[CONF_TX_PWR_COMPENSATION_LEN_5];
375 u8 padding[3];
376} __packed;
377
400struct wl1271_cmd_cal_channel_tune { 378struct wl1271_cmd_cal_channel_tune {
401 struct wl1271_cmd_header header; 379 struct wl1271_cmd_header header;
402 380
@@ -469,4 +447,13 @@ struct wl1271_cmd_disconnect {
469 u8 padding; 447 u8 padding;
470} __packed; 448} __packed;
471 449
450#define WL1271_CMD_STA_STATE_CONNECTED 1
451
452struct wl1271_cmd_set_sta_state {
453 struct wl1271_cmd_header header;
454
455 u8 state;
456 u8 padding[3];
457} __packed;
458
472#endif /* __WL1271_CMD_H__ */ 459#endif /* __WL1271_CMD_H__ */
diff --git a/drivers/net/wireless/wl12xx/wl1271_conf.h b/drivers/net/wireless/wl12xx/wl1271_conf.h
index 0435ffda8f7..5f78a6cb143 100644
--- a/drivers/net/wireless/wl12xx/wl1271_conf.h
+++ b/drivers/net/wireless/wl12xx/wl1271_conf.h
@@ -595,7 +595,7 @@ struct conf_tx_ac_category {
595 u16 tx_op_limit; 595 u16 tx_op_limit;
596}; 596};
597 597
598#define CONF_TX_MAX_TID_COUNT 7 598#define CONF_TX_MAX_TID_COUNT 8
599 599
600enum { 600enum {
601 CONF_CHANNEL_TYPE_DCF = 0, /* DC/LEGACY*/ 601 CONF_CHANNEL_TYPE_DCF = 0, /* DC/LEGACY*/
@@ -912,6 +912,22 @@ struct conf_conn_settings {
912 u8 psm_entry_retries; 912 u8 psm_entry_retries;
913 913
914 /* 914 /*
915 * Specifies the maximum number of times to try transmit the PSM entry
916 * null-func frame for each PSM entry attempt
917 *
918 * Range 0 - 255
919 */
920 u8 psm_entry_nullfunc_retries;
921
922 /*
923 * Specifies the time to linger in active mode after successfully
924 * transmitting the PSM entry null-func frame.
925 *
926 * Range 0 - 255 TU's
927 */
928 u8 psm_entry_hangover_period;
929
930 /*
915 * 931 *
916 * Specifies the interval of the connection keep-alive null-func 932 * Specifies the interval of the connection keep-alive null-func
917 * frame in ms. 933 * frame in ms.
@@ -1016,6 +1032,64 @@ struct conf_roam_trigger_settings {
1016 u8 avg_weight_snr_data; 1032 u8 avg_weight_snr_data;
1017}; 1033};
1018 1034
1035struct conf_scan_settings {
1036 /*
1037 * The minimum time to wait on each channel for active scans
1038 *
1039 * Range: 0 - 65536 tu
1040 */
1041 u16 min_dwell_time_active;
1042
1043 /*
1044 * The maximum time to wait on each channel for active scans
1045 *
1046 * Range: 0 - 65536 tu
1047 */
1048 u16 max_dwell_time_active;
1049
1050 /*
1051 * The maximum time to wait on each channel for passive scans
1052 *
1053 * Range: 0 - 65536 tu
1054 */
1055 u16 min_dwell_time_passive;
1056
1057 /*
1058 * The maximum time to wait on each channel for passive scans
1059 *
1060 * Range: 0 - 65536 tu
1061 */
1062 u16 max_dwell_time_passive;
1063
1064 /*
1065 * Number of probe requests to transmit on each active scan channel
1066 *
1067 * Range: u8
1068 */
1069 u16 num_probe_reqs;
1070
1071};
1072
1073/* these are number of channels on the band divided by two, rounded up */
1074#define CONF_TX_PWR_COMPENSATION_LEN_2 7
1075#define CONF_TX_PWR_COMPENSATION_LEN_5 18
1076
1077struct conf_rf_settings {
1078 /*
1079 * Per channel power compensation for 2.4GHz
1080 *
1081 * Range: s8
1082 */
1083 u8 tx_per_channel_power_compensation_2[CONF_TX_PWR_COMPENSATION_LEN_2];
1084
1085 /*
1086 * Per channel power compensation for 5GHz
1087 *
1088 * Range: s8
1089 */
1090 u8 tx_per_channel_power_compensation_5[CONF_TX_PWR_COMPENSATION_LEN_5];
1091};
1092
1019struct conf_drv_settings { 1093struct conf_drv_settings {
1020 struct conf_sg_settings sg; 1094 struct conf_sg_settings sg;
1021 struct conf_rx_settings rx; 1095 struct conf_rx_settings rx;
@@ -1024,6 +1098,8 @@ struct conf_drv_settings {
1024 struct conf_itrim_settings itrim; 1098 struct conf_itrim_settings itrim;
1025 struct conf_pm_config_settings pm_config; 1099 struct conf_pm_config_settings pm_config;
1026 struct conf_roam_trigger_settings roam_trigger; 1100 struct conf_roam_trigger_settings roam_trigger;
1101 struct conf_scan_settings scan;
1102 struct conf_rf_settings rf;
1027}; 1103};
1028 1104
1029#endif 1105#endif
diff --git a/drivers/net/wireless/wl12xx/wl1271_event.c b/drivers/net/wireless/wl12xx/wl1271_event.c
index 25ce2cd5e3f..7b3f5038296 100644
--- a/drivers/net/wireless/wl12xx/wl1271_event.c
+++ b/drivers/net/wireless/wl12xx/wl1271_event.c
@@ -41,6 +41,9 @@ void wl1271_pspoll_work(struct work_struct *work)
41 41
42 mutex_lock(&wl->mutex); 42 mutex_lock(&wl->mutex);
43 43
44 if (unlikely(wl->state == WL1271_STATE_OFF))
45 goto out;
46
44 if (!test_and_clear_bit(WL1271_FLAG_PSPOLL_FAILURE, &wl->flags)) 47 if (!test_and_clear_bit(WL1271_FLAG_PSPOLL_FAILURE, &wl->flags))
45 goto out; 48 goto out;
46 49
@@ -52,7 +55,7 @@ void wl1271_pspoll_work(struct work_struct *work)
52 * delivery failure occurred, and no-one changed state since, so 55 * delivery failure occurred, and no-one changed state since, so
53 * we should go back to powersave. 56 * we should go back to powersave.
54 */ 57 */
55 wl1271_ps_set_mode(wl, STATION_POWER_SAVE_MODE, true); 58 wl1271_ps_set_mode(wl, STATION_POWER_SAVE_MODE, wl->basic_rate, true);
56 59
57out: 60out:
58 mutex_unlock(&wl->mutex); 61 mutex_unlock(&wl->mutex);
@@ -70,7 +73,8 @@ static void wl1271_event_pspoll_delivery_fail(struct wl1271 *wl)
70 73
71 /* force active mode receive data from the AP */ 74 /* force active mode receive data from the AP */
72 if (test_bit(WL1271_FLAG_PSM, &wl->flags)) { 75 if (test_bit(WL1271_FLAG_PSM, &wl->flags)) {
73 ret = wl1271_ps_set_mode(wl, STATION_ACTIVE_MODE, true); 76 ret = wl1271_ps_set_mode(wl, STATION_ACTIVE_MODE,
77 wl->basic_rate, true);
74 if (ret < 0) 78 if (ret < 0)
75 return; 79 return;
76 set_bit(WL1271_FLAG_PSPOLL_FAILURE, &wl->flags); 80 set_bit(WL1271_FLAG_PSPOLL_FAILURE, &wl->flags);
@@ -91,6 +95,7 @@ static int wl1271_event_ps_report(struct wl1271 *wl,
91 bool *beacon_loss) 95 bool *beacon_loss)
92{ 96{
93 int ret = 0; 97 int ret = 0;
98 u32 total_retries = wl->conf.conn.psm_entry_retries;
94 99
95 wl1271_debug(DEBUG_EVENT, "ps_status: 0x%x", mbox->ps_status); 100 wl1271_debug(DEBUG_EVENT, "ps_status: 0x%x", mbox->ps_status);
96 101
@@ -104,10 +109,10 @@ static int wl1271_event_ps_report(struct wl1271 *wl,
104 break; 109 break;
105 } 110 }
106 111
107 if (wl->psm_entry_retry < wl->conf.conn.psm_entry_retries) { 112 if (wl->psm_entry_retry < total_retries) {
108 wl->psm_entry_retry++; 113 wl->psm_entry_retry++;
109 ret = wl1271_ps_set_mode(wl, STATION_POWER_SAVE_MODE, 114 ret = wl1271_ps_set_mode(wl, STATION_POWER_SAVE_MODE,
110 true); 115 wl->basic_rate, true);
111 } else { 116 } else {
112 wl1271_info("No ack to nullfunc from AP."); 117 wl1271_info("No ack to nullfunc from AP.");
113 wl->psm_entry_retry = 0; 118 wl->psm_entry_retry = 0;
@@ -143,7 +148,7 @@ static int wl1271_event_ps_report(struct wl1271 *wl,
143 /* make sure the firmware goes to active mode - the frame to 148 /* make sure the firmware goes to active mode - the frame to
144 be sent next will indicate to the AP, that we are active. */ 149 be sent next will indicate to the AP, that we are active. */
145 ret = wl1271_ps_set_mode(wl, STATION_ACTIVE_MODE, 150 ret = wl1271_ps_set_mode(wl, STATION_ACTIVE_MODE,
146 false); 151 wl->basic_rate, false);
147 break; 152 break;
148 case EVENT_EXIT_POWER_SAVE_SUCCESS: 153 case EVENT_EXIT_POWER_SAVE_SUCCESS:
149 default: 154 default:
diff --git a/drivers/net/wireless/wl12xx/wl1271_init.c b/drivers/net/wireless/wl12xx/wl1271_init.c
index 4447af1557f..8044bba70ee 100644
--- a/drivers/net/wireless/wl12xx/wl1271_init.c
+++ b/drivers/net/wireless/wl12xx/wl1271_init.c
@@ -53,6 +53,7 @@ static int wl1271_init_hwenc_config(struct wl1271 *wl)
53int wl1271_init_templates_config(struct wl1271 *wl) 53int wl1271_init_templates_config(struct wl1271 *wl)
54{ 54{
55 int ret, i; 55 int ret, i;
56 size_t size;
56 57
57 /* send empty templates for fw memory reservation */ 58 /* send empty templates for fw memory reservation */
58 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_2_4, NULL, 59 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_2_4, NULL,
@@ -61,14 +62,12 @@ int wl1271_init_templates_config(struct wl1271 *wl)
61 if (ret < 0) 62 if (ret < 0)
62 return ret; 63 return ret;
63 64
64 if (wl1271_11a_enabled()) { 65 size = sizeof(struct wl12xx_probe_req_template);
65 size_t size = sizeof(struct wl12xx_probe_req_template); 66 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_5,
66 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_5, 67 NULL, size, 0,
67 NULL, size, 0, 68 WL1271_RATE_AUTOMATIC);
68 WL1271_RATE_AUTOMATIC); 69 if (ret < 0)
69 if (ret < 0) 70 return ret;
70 return ret;
71 }
72 71
73 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_NULL_DATA, NULL, 72 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_NULL_DATA, NULL,
74 sizeof(struct wl12xx_null_data_template), 73 sizeof(struct wl12xx_null_data_template),
@@ -223,6 +222,10 @@ int wl1271_hw_init(struct wl1271 *wl)
223 if (ret < 0) 222 if (ret < 0)
224 return ret; 223 return ret;
225 224
225 ret = wl1271_cmd_ext_radio_parms(wl);
226 if (ret < 0)
227 return ret;
228
226 /* Template settings */ 229 /* Template settings */
227 ret = wl1271_init_templates_config(wl); 230 ret = wl1271_init_templates_config(wl);
228 if (ret < 0) 231 if (ret < 0)
@@ -291,8 +294,16 @@ int wl1271_hw_init(struct wl1271 *wl)
291 if (ret < 0) 294 if (ret < 0)
292 goto out_free_memmap; 295 goto out_free_memmap;
293 296
294 /* Default TID configuration */ 297 /* Default TID/AC configuration */
298 BUG_ON(wl->conf.tx.tid_conf_count != wl->conf.tx.ac_conf_count);
295 for (i = 0; i < wl->conf.tx.tid_conf_count; i++) { 299 for (i = 0; i < wl->conf.tx.tid_conf_count; i++) {
300 conf_ac = &wl->conf.tx.ac_conf[i];
301 ret = wl1271_acx_ac_cfg(wl, conf_ac->ac, conf_ac->cw_min,
302 conf_ac->cw_max, conf_ac->aifsn,
303 conf_ac->tx_op_limit);
304 if (ret < 0)
305 goto out_free_memmap;
306
296 conf_tid = &wl->conf.tx.tid_conf[i]; 307 conf_tid = &wl->conf.tx.tid_conf[i];
297 ret = wl1271_acx_tid_cfg(wl, conf_tid->queue_id, 308 ret = wl1271_acx_tid_cfg(wl, conf_tid->queue_id,
298 conf_tid->channel_type, 309 conf_tid->channel_type,
@@ -305,16 +316,6 @@ int wl1271_hw_init(struct wl1271 *wl)
305 goto out_free_memmap; 316 goto out_free_memmap;
306 } 317 }
307 318
308 /* Default AC configuration */
309 for (i = 0; i < wl->conf.tx.ac_conf_count; i++) {
310 conf_ac = &wl->conf.tx.ac_conf[i];
311 ret = wl1271_acx_ac_cfg(wl, conf_ac->ac, conf_ac->cw_min,
312 conf_ac->cw_max, conf_ac->aifsn,
313 conf_ac->tx_op_limit);
314 if (ret < 0)
315 goto out_free_memmap;
316 }
317
318 /* Configure TX rate classes */ 319 /* Configure TX rate classes */
319 ret = wl1271_acx_rate_policies(wl); 320 ret = wl1271_acx_rate_policies(wl);
320 if (ret < 0) 321 if (ret < 0)
diff --git a/drivers/net/wireless/wl12xx/wl1271_main.c b/drivers/net/wireless/wl12xx/wl1271_main.c
index 776cd7c4114..48a4b9961ae 100644
--- a/drivers/net/wireless/wl12xx/wl1271_main.c
+++ b/drivers/net/wireless/wl12xx/wl1271_main.c
@@ -124,28 +124,28 @@ static struct conf_drv_settings default_conf = {
124 }, 124 },
125 .ac_conf_count = 4, 125 .ac_conf_count = 4,
126 .ac_conf = { 126 .ac_conf = {
127 [0] = { 127 [CONF_TX_AC_BE] = {
128 .ac = CONF_TX_AC_BE, 128 .ac = CONF_TX_AC_BE,
129 .cw_min = 15, 129 .cw_min = 15,
130 .cw_max = 63, 130 .cw_max = 63,
131 .aifsn = 3, 131 .aifsn = 3,
132 .tx_op_limit = 0, 132 .tx_op_limit = 0,
133 }, 133 },
134 [1] = { 134 [CONF_TX_AC_BK] = {
135 .ac = CONF_TX_AC_BK, 135 .ac = CONF_TX_AC_BK,
136 .cw_min = 15, 136 .cw_min = 15,
137 .cw_max = 63, 137 .cw_max = 63,
138 .aifsn = 7, 138 .aifsn = 7,
139 .tx_op_limit = 0, 139 .tx_op_limit = 0,
140 }, 140 },
141 [2] = { 141 [CONF_TX_AC_VI] = {
142 .ac = CONF_TX_AC_VI, 142 .ac = CONF_TX_AC_VI,
143 .cw_min = 15, 143 .cw_min = 15,
144 .cw_max = 63, 144 .cw_max = 63,
145 .aifsn = CONF_TX_AIFS_PIFS, 145 .aifsn = CONF_TX_AIFS_PIFS,
146 .tx_op_limit = 3008, 146 .tx_op_limit = 3008,
147 }, 147 },
148 [3] = { 148 [CONF_TX_AC_VO] = {
149 .ac = CONF_TX_AC_VO, 149 .ac = CONF_TX_AC_VO,
150 .cw_min = 15, 150 .cw_min = 15,
151 .cw_max = 63, 151 .cw_max = 63,
@@ -153,64 +153,40 @@ static struct conf_drv_settings default_conf = {
153 .tx_op_limit = 1504, 153 .tx_op_limit = 1504,
154 }, 154 },
155 }, 155 },
156 .tid_conf_count = 7, 156 .tid_conf_count = 4,
157 .tid_conf = { 157 .tid_conf = {
158 [0] = { 158 [CONF_TX_AC_BE] = {
159 .queue_id = 0, 159 .queue_id = CONF_TX_AC_BE,
160 .channel_type = CONF_CHANNEL_TYPE_DCF, 160 .channel_type = CONF_CHANNEL_TYPE_EDCF,
161 .tsid = CONF_TX_AC_BE,
162 .ps_scheme = CONF_PS_SCHEME_LEGACY,
163 .ack_policy = CONF_ACK_POLICY_LEGACY,
164 .apsd_conf = {0, 0},
165 },
166 [1] = {
167 .queue_id = 1,
168 .channel_type = CONF_CHANNEL_TYPE_DCF,
169 .tsid = CONF_TX_AC_BE, 161 .tsid = CONF_TX_AC_BE,
170 .ps_scheme = CONF_PS_SCHEME_LEGACY, 162 .ps_scheme = CONF_PS_SCHEME_LEGACY,
171 .ack_policy = CONF_ACK_POLICY_LEGACY, 163 .ack_policy = CONF_ACK_POLICY_LEGACY,
172 .apsd_conf = {0, 0}, 164 .apsd_conf = {0, 0},
173 }, 165 },
174 [2] = { 166 [CONF_TX_AC_BK] = {
175 .queue_id = 2, 167 .queue_id = CONF_TX_AC_BK,
176 .channel_type = CONF_CHANNEL_TYPE_DCF, 168 .channel_type = CONF_CHANNEL_TYPE_EDCF,
177 .tsid = CONF_TX_AC_BE, 169 .tsid = CONF_TX_AC_BK,
178 .ps_scheme = CONF_PS_SCHEME_LEGACY, 170 .ps_scheme = CONF_PS_SCHEME_LEGACY,
179 .ack_policy = CONF_ACK_POLICY_LEGACY, 171 .ack_policy = CONF_ACK_POLICY_LEGACY,
180 .apsd_conf = {0, 0}, 172 .apsd_conf = {0, 0},
181 }, 173 },
182 [3] = { 174 [CONF_TX_AC_VI] = {
183 .queue_id = 3, 175 .queue_id = CONF_TX_AC_VI,
184 .channel_type = CONF_CHANNEL_TYPE_DCF, 176 .channel_type = CONF_CHANNEL_TYPE_EDCF,
185 .tsid = CONF_TX_AC_BE, 177 .tsid = CONF_TX_AC_VI,
186 .ps_scheme = CONF_PS_SCHEME_LEGACY,
187 .ack_policy = CONF_ACK_POLICY_LEGACY,
188 .apsd_conf = {0, 0},
189 },
190 [4] = {
191 .queue_id = 4,
192 .channel_type = CONF_CHANNEL_TYPE_DCF,
193 .tsid = CONF_TX_AC_BE,
194 .ps_scheme = CONF_PS_SCHEME_LEGACY, 178 .ps_scheme = CONF_PS_SCHEME_LEGACY,
195 .ack_policy = CONF_ACK_POLICY_LEGACY, 179 .ack_policy = CONF_ACK_POLICY_LEGACY,
196 .apsd_conf = {0, 0}, 180 .apsd_conf = {0, 0},
197 }, 181 },
198 [5] = { 182 [CONF_TX_AC_VO] = {
199 .queue_id = 5, 183 .queue_id = CONF_TX_AC_VO,
200 .channel_type = CONF_CHANNEL_TYPE_DCF, 184 .channel_type = CONF_CHANNEL_TYPE_EDCF,
201 .tsid = CONF_TX_AC_BE, 185 .tsid = CONF_TX_AC_VO,
202 .ps_scheme = CONF_PS_SCHEME_LEGACY, 186 .ps_scheme = CONF_PS_SCHEME_LEGACY,
203 .ack_policy = CONF_ACK_POLICY_LEGACY, 187 .ack_policy = CONF_ACK_POLICY_LEGACY,
204 .apsd_conf = {0, 0}, 188 .apsd_conf = {0, 0},
205 }, 189 },
206 [6] = {
207 .queue_id = 6,
208 .channel_type = CONF_CHANNEL_TYPE_DCF,
209 .tsid = CONF_TX_AC_BE,
210 .ps_scheme = CONF_PS_SCHEME_LEGACY,
211 .ack_policy = CONF_ACK_POLICY_LEGACY,
212 .apsd_conf = {0, 0},
213 }
214 }, 190 },
215 .frag_threshold = IEEE80211_MAX_FRAG_THRESHOLD, 191 .frag_threshold = IEEE80211_MAX_FRAG_THRESHOLD,
216 .tx_compl_timeout = 700, 192 .tx_compl_timeout = 700,
@@ -238,7 +214,9 @@ static struct conf_drv_settings default_conf = {
238 .ps_poll_recovery_period = 700, 214 .ps_poll_recovery_period = 700,
239 .bet_enable = CONF_BET_MODE_ENABLE, 215 .bet_enable = CONF_BET_MODE_ENABLE,
240 .bet_max_consecutive = 10, 216 .bet_max_consecutive = 10,
241 .psm_entry_retries = 3, 217 .psm_entry_retries = 5,
218 .psm_entry_nullfunc_retries = 3,
219 .psm_entry_hangover_period = 1,
242 .keep_alive_interval = 55000, 220 .keep_alive_interval = 55000,
243 .max_listen_interval = 20, 221 .max_listen_interval = 20,
244 }, 222 },
@@ -251,15 +229,34 @@ static struct conf_drv_settings default_conf = {
251 .host_fast_wakeup_support = false 229 .host_fast_wakeup_support = false
252 }, 230 },
253 .roam_trigger = { 231 .roam_trigger = {
254 /* FIXME: due to firmware bug, must use value 1 for now */
255 .trigger_pacing = 1, 232 .trigger_pacing = 1,
256 .avg_weight_rssi_beacon = 20, 233 .avg_weight_rssi_beacon = 20,
257 .avg_weight_rssi_data = 10, 234 .avg_weight_rssi_data = 10,
258 .avg_weight_snr_beacon = 20, 235 .avg_weight_snr_beacon = 20,
259 .avg_weight_snr_data = 10 236 .avg_weight_snr_data = 10
260 } 237 },
238 .scan = {
239 .min_dwell_time_active = 7500,
240 .max_dwell_time_active = 30000,
241 .min_dwell_time_passive = 30000,
242 .max_dwell_time_passive = 60000,
243 .num_probe_reqs = 2,
244 },
245 .rf = {
246 .tx_per_channel_power_compensation_2 = {
247 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
248 },
249 .tx_per_channel_power_compensation_5 = {
250 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
251 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
252 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
253 },
254 },
261}; 255};
262 256
257static void __wl1271_op_remove_interface(struct wl1271 *wl);
258
259
263static void wl1271_device_release(struct device *dev) 260static void wl1271_device_release(struct device *dev)
264{ 261{
265 262
@@ -277,6 +274,67 @@ static struct platform_device wl1271_device = {
277 274
278static LIST_HEAD(wl_list); 275static LIST_HEAD(wl_list);
279 276
277static int wl1271_dev_notify(struct notifier_block *me, unsigned long what,
278 void *arg)
279{
280 struct net_device *dev = arg;
281 struct wireless_dev *wdev;
282 struct wiphy *wiphy;
283 struct ieee80211_hw *hw;
284 struct wl1271 *wl;
285 struct wl1271 *wl_temp;
286 int ret = 0;
287
288 /* Check that this notification is for us. */
289 if (what != NETDEV_CHANGE)
290 return NOTIFY_DONE;
291
292 wdev = dev->ieee80211_ptr;
293 if (wdev == NULL)
294 return NOTIFY_DONE;
295
296 wiphy = wdev->wiphy;
297 if (wiphy == NULL)
298 return NOTIFY_DONE;
299
300 hw = wiphy_priv(wiphy);
301 if (hw == NULL)
302 return NOTIFY_DONE;
303
304 wl_temp = hw->priv;
305 list_for_each_entry(wl, &wl_list, list) {
306 if (wl == wl_temp)
307 break;
308 }
309 if (wl != wl_temp)
310 return NOTIFY_DONE;
311
312 mutex_lock(&wl->mutex);
313
314 if (wl->state == WL1271_STATE_OFF)
315 goto out;
316
317 if (!test_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags))
318 goto out;
319
320 ret = wl1271_ps_elp_wakeup(wl, false);
321 if (ret < 0)
322 goto out;
323
324 if ((dev->operstate == IF_OPER_UP) &&
325 !test_and_set_bit(WL1271_FLAG_STA_STATE_SENT, &wl->flags)) {
326 wl1271_cmd_set_sta_state(wl);
327 wl1271_info("Association completed.");
328 }
329
330 wl1271_ps_elp_sleep(wl);
331
332out:
333 mutex_unlock(&wl->mutex);
334
335 return NOTIFY_OK;
336}
337
280static void wl1271_conf_init(struct wl1271 *wl) 338static void wl1271_conf_init(struct wl1271 *wl)
281{ 339{
282 340
@@ -309,6 +367,10 @@ static int wl1271_plt_init(struct wl1271 *wl)
309 if (ret < 0) 367 if (ret < 0)
310 return ret; 368 return ret;
311 369
370 ret = wl1271_cmd_ext_radio_parms(wl);
371 if (ret < 0)
372 return ret;
373
312 ret = wl1271_init_templates_config(wl); 374 ret = wl1271_init_templates_config(wl);
313 if (ret < 0) 375 if (ret < 0)
314 return ret; 376 return ret;
@@ -346,8 +408,16 @@ static int wl1271_plt_init(struct wl1271 *wl)
346 if (ret < 0) 408 if (ret < 0)
347 goto out_free_memmap; 409 goto out_free_memmap;
348 410
349 /* Default TID configuration */ 411 /* Default TID/AC configuration */
412 BUG_ON(wl->conf.tx.tid_conf_count != wl->conf.tx.ac_conf_count);
350 for (i = 0; i < wl->conf.tx.tid_conf_count; i++) { 413 for (i = 0; i < wl->conf.tx.tid_conf_count; i++) {
414 conf_ac = &wl->conf.tx.ac_conf[i];
415 ret = wl1271_acx_ac_cfg(wl, conf_ac->ac, conf_ac->cw_min,
416 conf_ac->cw_max, conf_ac->aifsn,
417 conf_ac->tx_op_limit);
418 if (ret < 0)
419 goto out_free_memmap;
420
351 conf_tid = &wl->conf.tx.tid_conf[i]; 421 conf_tid = &wl->conf.tx.tid_conf[i];
352 ret = wl1271_acx_tid_cfg(wl, conf_tid->queue_id, 422 ret = wl1271_acx_tid_cfg(wl, conf_tid->queue_id,
353 conf_tid->channel_type, 423 conf_tid->channel_type,
@@ -360,16 +430,6 @@ static int wl1271_plt_init(struct wl1271 *wl)
360 goto out_free_memmap; 430 goto out_free_memmap;
361 } 431 }
362 432
363 /* Default AC configuration */
364 for (i = 0; i < wl->conf.tx.ac_conf_count; i++) {
365 conf_ac = &wl->conf.tx.ac_conf[i];
366 ret = wl1271_acx_ac_cfg(wl, conf_ac->ac, conf_ac->cw_min,
367 conf_ac->cw_max, conf_ac->aifsn,
368 conf_ac->tx_op_limit);
369 if (ret < 0)
370 goto out_free_memmap;
371 }
372
373 /* Enable data path */ 433 /* Enable data path */
374 ret = wl1271_cmd_data_path(wl, 1); 434 ret = wl1271_cmd_data_path(wl, 1);
375 if (ret < 0) 435 if (ret < 0)
@@ -562,20 +622,6 @@ static int wl1271_fetch_nvs(struct wl1271 *wl)
562 return ret; 622 return ret;
563 } 623 }
564 624
565 /*
566 * FIXME: the LEGACY NVS image support (NVS's missing the 5GHz band
567 * configurations) can be removed when those NVS files stop floating
568 * around.
569 */
570 if (fw->size != sizeof(struct wl1271_nvs_file) &&
571 (fw->size != WL1271_INI_LEGACY_NVS_FILE_SIZE ||
572 wl1271_11a_enabled())) {
573 wl1271_error("nvs size is not as expected: %zu != %zu",
574 fw->size, sizeof(struct wl1271_nvs_file));
575 ret = -EILSEQ;
576 goto out;
577 }
578
579 wl->nvs = kmemdup(fw->data, sizeof(struct wl1271_nvs_file), GFP_KERNEL); 625 wl->nvs = kmemdup(fw->data, sizeof(struct wl1271_nvs_file), GFP_KERNEL);
580 626
581 if (!wl->nvs) { 627 if (!wl->nvs) {
@@ -584,12 +630,37 @@ static int wl1271_fetch_nvs(struct wl1271 *wl)
584 goto out; 630 goto out;
585 } 631 }
586 632
633 wl->nvs_len = fw->size;
634
587out: 635out:
588 release_firmware(fw); 636 release_firmware(fw);
589 637
590 return ret; 638 return ret;
591} 639}
592 640
641static void wl1271_recovery_work(struct work_struct *work)
642{
643 struct wl1271 *wl =
644 container_of(work, struct wl1271, recovery_work);
645
646 mutex_lock(&wl->mutex);
647
648 if (wl->state != WL1271_STATE_ON)
649 goto out;
650
651 wl1271_info("Hardware recovery in progress.");
652
653 if (test_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags))
654 ieee80211_connection_loss(wl->vif);
655
656 /* reboot the chipset */
657 __wl1271_op_remove_interface(wl);
658 ieee80211_restart_hw(wl->hw);
659
660out:
661 mutex_unlock(&wl->mutex);
662}
663
593static void wl1271_fw_wakeup(struct wl1271 *wl) 664static void wl1271_fw_wakeup(struct wl1271 *wl)
594{ 665{
595 u32 elp_reg; 666 u32 elp_reg;
@@ -610,8 +681,6 @@ static int wl1271_setup(struct wl1271 *wl)
610 return -ENOMEM; 681 return -ENOMEM;
611 } 682 }
612 683
613 INIT_WORK(&wl->irq_work, wl1271_irq_work);
614 INIT_WORK(&wl->tx_work, wl1271_tx_work);
615 return 0; 684 return 0;
616} 685}
617 686
@@ -768,10 +837,12 @@ int wl1271_plt_stop(struct wl1271 *wl)
768out: 837out:
769 mutex_unlock(&wl->mutex); 838 mutex_unlock(&wl->mutex);
770 839
840 cancel_work_sync(&wl->irq_work);
841 cancel_work_sync(&wl->recovery_work);
842
771 return ret; 843 return ret;
772} 844}
773 845
774
775static int wl1271_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) 846static int wl1271_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
776{ 847{
777 struct wl1271 *wl = hw->priv; 848 struct wl1271 *wl = hw->priv;
@@ -814,6 +885,10 @@ static int wl1271_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
814 return NETDEV_TX_OK; 885 return NETDEV_TX_OK;
815} 886}
816 887
888static struct notifier_block wl1271_dev_notifier = {
889 .notifier_call = wl1271_dev_notify,
890};
891
817static int wl1271_op_start(struct ieee80211_hw *hw) 892static int wl1271_op_start(struct ieee80211_hw *hw)
818{ 893{
819 wl1271_debug(DEBUG_MAC80211, "mac80211 start"); 894 wl1271_debug(DEBUG_MAC80211, "mac80211 start");
@@ -930,13 +1005,10 @@ out:
930 return ret; 1005 return ret;
931} 1006}
932 1007
933static void wl1271_op_remove_interface(struct ieee80211_hw *hw, 1008static void __wl1271_op_remove_interface(struct wl1271 *wl)
934 struct ieee80211_vif *vif)
935{ 1009{
936 struct wl1271 *wl = hw->priv;
937 int i; 1010 int i;
938 1011
939 mutex_lock(&wl->mutex);
940 wl1271_debug(DEBUG_MAC80211, "mac80211 remove interface"); 1012 wl1271_debug(DEBUG_MAC80211, "mac80211 remove interface");
941 1013
942 wl1271_info("down"); 1014 wl1271_info("down");
@@ -950,10 +1022,10 @@ static void wl1271_op_remove_interface(struct ieee80211_hw *hw,
950 ieee80211_enable_dyn_ps(wl->vif); 1022 ieee80211_enable_dyn_ps(wl->vif);
951 1023
952 if (wl->scan.state != WL1271_SCAN_STATE_IDLE) { 1024 if (wl->scan.state != WL1271_SCAN_STATE_IDLE) {
953 ieee80211_scan_completed(wl->hw, true);
954 wl->scan.state = WL1271_SCAN_STATE_IDLE; 1025 wl->scan.state = WL1271_SCAN_STATE_IDLE;
955 kfree(wl->scan.scanned_ch); 1026 kfree(wl->scan.scanned_ch);
956 wl->scan.scanned_ch = NULL; 1027 wl->scan.scanned_ch = NULL;
1028 ieee80211_scan_completed(wl->hw, true);
957 } 1029 }
958 1030
959 wl->state = WL1271_STATE_OFF; 1031 wl->state = WL1271_STATE_OFF;
@@ -962,9 +1034,11 @@ static void wl1271_op_remove_interface(struct ieee80211_hw *hw,
962 1034
963 mutex_unlock(&wl->mutex); 1035 mutex_unlock(&wl->mutex);
964 1036
1037 cancel_delayed_work_sync(&wl->scan_complete_work);
965 cancel_work_sync(&wl->irq_work); 1038 cancel_work_sync(&wl->irq_work);
966 cancel_work_sync(&wl->tx_work); 1039 cancel_work_sync(&wl->tx_work);
967 cancel_delayed_work_sync(&wl->pspoll_work); 1040 cancel_delayed_work_sync(&wl->pspoll_work);
1041 cancel_delayed_work_sync(&wl->elp_work);
968 1042
969 mutex_lock(&wl->mutex); 1043 mutex_lock(&wl->mutex);
970 1044
@@ -1006,8 +1080,19 @@ static void wl1271_op_remove_interface(struct ieee80211_hw *hw,
1006 wl->tx_res_if = NULL; 1080 wl->tx_res_if = NULL;
1007 kfree(wl->target_mem_map); 1081 kfree(wl->target_mem_map);
1008 wl->target_mem_map = NULL; 1082 wl->target_mem_map = NULL;
1083}
1084
1085static void wl1271_op_remove_interface(struct ieee80211_hw *hw,
1086 struct ieee80211_vif *vif)
1087{
1088 struct wl1271 *wl = hw->priv;
1009 1089
1090 mutex_lock(&wl->mutex);
1091 WARN_ON(wl->vif != vif);
1092 __wl1271_op_remove_interface(wl);
1010 mutex_unlock(&wl->mutex); 1093 mutex_unlock(&wl->mutex);
1094
1095 cancel_work_sync(&wl->recovery_work);
1011} 1096}
1012 1097
1013static void wl1271_configure_filters(struct wl1271 *wl, unsigned int filters) 1098static void wl1271_configure_filters(struct wl1271 *wl, unsigned int filters)
@@ -1289,7 +1374,7 @@ static int wl1271_op_config(struct ieee80211_hw *hw, u32 changed)
1289 if (test_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags)) { 1374 if (test_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags)) {
1290 wl1271_debug(DEBUG_PSM, "psm enabled"); 1375 wl1271_debug(DEBUG_PSM, "psm enabled");
1291 ret = wl1271_ps_set_mode(wl, STATION_POWER_SAVE_MODE, 1376 ret = wl1271_ps_set_mode(wl, STATION_POWER_SAVE_MODE,
1292 true); 1377 wl->basic_rate, true);
1293 } 1378 }
1294 } else if (!(conf->flags & IEEE80211_CONF_PS) && 1379 } else if (!(conf->flags & IEEE80211_CONF_PS) &&
1295 test_bit(WL1271_FLAG_PSM_REQUESTED, &wl->flags)) { 1380 test_bit(WL1271_FLAG_PSM_REQUESTED, &wl->flags)) {
@@ -1299,7 +1384,7 @@ static int wl1271_op_config(struct ieee80211_hw *hw, u32 changed)
1299 1384
1300 if (test_bit(WL1271_FLAG_PSM, &wl->flags)) 1385 if (test_bit(WL1271_FLAG_PSM, &wl->flags))
1301 ret = wl1271_ps_set_mode(wl, STATION_ACTIVE_MODE, 1386 ret = wl1271_ps_set_mode(wl, STATION_ACTIVE_MODE,
1302 true); 1387 wl->basic_rate, true);
1303 } 1388 }
1304 1389
1305 if (conf->power_level != wl->power_level) { 1390 if (conf->power_level != wl->power_level) {
@@ -1476,6 +1561,11 @@ static int wl1271_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
1476 tx_seq_32 = WL1271_TX_SECURITY_HI32(wl->tx_security_seq); 1561 tx_seq_32 = WL1271_TX_SECURITY_HI32(wl->tx_security_seq);
1477 tx_seq_16 = WL1271_TX_SECURITY_LO16(wl->tx_security_seq); 1562 tx_seq_16 = WL1271_TX_SECURITY_LO16(wl->tx_security_seq);
1478 break; 1563 break;
1564 case WL1271_CIPHER_SUITE_GEM:
1565 key_type = KEY_GEM;
1566 tx_seq_32 = WL1271_TX_SECURITY_HI32(wl->tx_security_seq);
1567 tx_seq_16 = WL1271_TX_SECURITY_LO16(wl->tx_security_seq);
1568 break;
1479 default: 1569 default:
1480 wl1271_error("Unknown key algo 0x%x", key_conf->cipher); 1570 wl1271_error("Unknown key algo 0x%x", key_conf->cipher);
1481 1571
@@ -1559,10 +1649,7 @@ static int wl1271_op_hw_scan(struct ieee80211_hw *hw,
1559 if (ret < 0) 1649 if (ret < 0)
1560 goto out; 1650 goto out;
1561 1651
1562 if (wl1271_11a_enabled()) 1652 ret = wl1271_scan(hw->priv, ssid, len, req);
1563 ret = wl1271_scan(hw->priv, ssid, len, req);
1564 else
1565 ret = wl1271_scan(hw->priv, ssid, len, req);
1566 1653
1567 wl1271_ps_elp_sleep(wl); 1654 wl1271_ps_elp_sleep(wl);
1568 1655
@@ -1777,12 +1864,15 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw,
1777 if (test_bit(WL1271_FLAG_PSM_REQUESTED, &wl->flags) && 1864 if (test_bit(WL1271_FLAG_PSM_REQUESTED, &wl->flags) &&
1778 !test_bit(WL1271_FLAG_PSM, &wl->flags)) { 1865 !test_bit(WL1271_FLAG_PSM, &wl->flags)) {
1779 mode = STATION_POWER_SAVE_MODE; 1866 mode = STATION_POWER_SAVE_MODE;
1780 ret = wl1271_ps_set_mode(wl, mode, true); 1867 ret = wl1271_ps_set_mode(wl, mode,
1868 wl->basic_rate,
1869 true);
1781 if (ret < 0) 1870 if (ret < 0)
1782 goto out_sleep; 1871 goto out_sleep;
1783 } 1872 }
1784 } else { 1873 } else {
1785 /* use defaults when not associated */ 1874 /* use defaults when not associated */
1875 clear_bit(WL1271_FLAG_STA_STATE_SENT, &wl->flags);
1786 clear_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags); 1876 clear_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags);
1787 wl->aid = 0; 1877 wl->aid = 0;
1788 1878
@@ -1994,21 +2084,24 @@ static struct ieee80211_rate wl1271_rates[] = {
1994 .hw_value_short = CONF_HW_BIT_RATE_54MBPS, }, 2084 .hw_value_short = CONF_HW_BIT_RATE_54MBPS, },
1995}; 2085};
1996 2086
1997/* can't be const, mac80211 writes to this */ 2087/*
2088 * Can't be const, mac80211 writes to this. The order of the channels here
2089 * is designed to improve scanning.
2090 */
1998static struct ieee80211_channel wl1271_channels[] = { 2091static struct ieee80211_channel wl1271_channels[] = {
1999 { .hw_value = 1, .center_freq = 2412, .max_power = 25 }, 2092 { .hw_value = 1, .center_freq = 2412, .max_power = 25 },
2000 { .hw_value = 2, .center_freq = 2417, .max_power = 25 },
2001 { .hw_value = 3, .center_freq = 2422, .max_power = 25 },
2002 { .hw_value = 4, .center_freq = 2427, .max_power = 25 },
2003 { .hw_value = 5, .center_freq = 2432, .max_power = 25 }, 2093 { .hw_value = 5, .center_freq = 2432, .max_power = 25 },
2004 { .hw_value = 6, .center_freq = 2437, .max_power = 25 },
2005 { .hw_value = 7, .center_freq = 2442, .max_power = 25 },
2006 { .hw_value = 8, .center_freq = 2447, .max_power = 25 },
2007 { .hw_value = 9, .center_freq = 2452, .max_power = 25 }, 2094 { .hw_value = 9, .center_freq = 2452, .max_power = 25 },
2008 { .hw_value = 10, .center_freq = 2457, .max_power = 25 },
2009 { .hw_value = 11, .center_freq = 2462, .max_power = 25 },
2010 { .hw_value = 12, .center_freq = 2467, .max_power = 25 },
2011 { .hw_value = 13, .center_freq = 2472, .max_power = 25 }, 2095 { .hw_value = 13, .center_freq = 2472, .max_power = 25 },
2096 { .hw_value = 4, .center_freq = 2427, .max_power = 25 },
2097 { .hw_value = 8, .center_freq = 2447, .max_power = 25 },
2098 { .hw_value = 12, .center_freq = 2467, .max_power = 25 },
2099 { .hw_value = 3, .center_freq = 2422, .max_power = 25 },
2100 { .hw_value = 7, .center_freq = 2442, .max_power = 25 },
2101 { .hw_value = 11, .center_freq = 2462, .max_power = 25 },
2102 { .hw_value = 2, .center_freq = 2417, .max_power = 25 },
2103 { .hw_value = 6, .center_freq = 2437, .max_power = 25 },
2104 { .hw_value = 10, .center_freq = 2457, .max_power = 25 },
2012}; 2105};
2013 2106
2014/* mapping to indexes for wl1271_rates */ 2107/* mapping to indexes for wl1271_rates */
@@ -2077,49 +2170,52 @@ static struct ieee80211_rate wl1271_rates_5ghz[] = {
2077 .hw_value_short = CONF_HW_BIT_RATE_54MBPS, }, 2170 .hw_value_short = CONF_HW_BIT_RATE_54MBPS, },
2078}; 2171};
2079 2172
2080/* 5 GHz band channels for WL1273 */ 2173/*
2174 * 5 GHz band channels for WL1273 - can't be const, mac80211 writes to this.
2175 * The order of the channels here is designed to improve scanning.
2176 */
2081static struct ieee80211_channel wl1271_channels_5ghz[] = { 2177static struct ieee80211_channel wl1271_channels_5ghz[] = {
2082 { .hw_value = 183, .center_freq = 4915}, 2178 { .hw_value = 183, .center_freq = 4915},
2083 { .hw_value = 184, .center_freq = 4920},
2084 { .hw_value = 185, .center_freq = 4925},
2085 { .hw_value = 187, .center_freq = 4935},
2086 { .hw_value = 188, .center_freq = 4940}, 2179 { .hw_value = 188, .center_freq = 4940},
2087 { .hw_value = 189, .center_freq = 4945},
2088 { .hw_value = 192, .center_freq = 4960},
2089 { .hw_value = 196, .center_freq = 4980},
2090 { .hw_value = 7, .center_freq = 5035},
2091 { .hw_value = 8, .center_freq = 5040}, 2180 { .hw_value = 8, .center_freq = 5040},
2092 { .hw_value = 9, .center_freq = 5045},
2093 { .hw_value = 11, .center_freq = 5055},
2094 { .hw_value = 12, .center_freq = 5060},
2095 { .hw_value = 16, .center_freq = 5080},
2096 { .hw_value = 34, .center_freq = 5170}, 2181 { .hw_value = 34, .center_freq = 5170},
2097 { .hw_value = 36, .center_freq = 5180},
2098 { .hw_value = 38, .center_freq = 5190},
2099 { .hw_value = 40, .center_freq = 5200},
2100 { .hw_value = 42, .center_freq = 5210},
2101 { .hw_value = 44, .center_freq = 5220}, 2182 { .hw_value = 44, .center_freq = 5220},
2102 { .hw_value = 46, .center_freq = 5230},
2103 { .hw_value = 48, .center_freq = 5240},
2104 { .hw_value = 52, .center_freq = 5260},
2105 { .hw_value = 56, .center_freq = 5280},
2106 { .hw_value = 60, .center_freq = 5300}, 2183 { .hw_value = 60, .center_freq = 5300},
2107 { .hw_value = 64, .center_freq = 5320},
2108 { .hw_value = 100, .center_freq = 5500},
2109 { .hw_value = 104, .center_freq = 5520},
2110 { .hw_value = 108, .center_freq = 5540},
2111 { .hw_value = 112, .center_freq = 5560}, 2184 { .hw_value = 112, .center_freq = 5560},
2112 { .hw_value = 116, .center_freq = 5580},
2113 { .hw_value = 120, .center_freq = 5600},
2114 { .hw_value = 124, .center_freq = 5620},
2115 { .hw_value = 128, .center_freq = 5640},
2116 { .hw_value = 132, .center_freq = 5660}, 2185 { .hw_value = 132, .center_freq = 5660},
2186 { .hw_value = 157, .center_freq = 5785},
2187 { .hw_value = 184, .center_freq = 4920},
2188 { .hw_value = 189, .center_freq = 4945},
2189 { .hw_value = 9, .center_freq = 5045},
2190 { .hw_value = 36, .center_freq = 5180},
2191 { .hw_value = 46, .center_freq = 5230},
2192 { .hw_value = 64, .center_freq = 5320},
2193 { .hw_value = 116, .center_freq = 5580},
2117 { .hw_value = 136, .center_freq = 5680}, 2194 { .hw_value = 136, .center_freq = 5680},
2195 { .hw_value = 192, .center_freq = 4960},
2196 { .hw_value = 11, .center_freq = 5055},
2197 { .hw_value = 38, .center_freq = 5190},
2198 { .hw_value = 48, .center_freq = 5240},
2199 { .hw_value = 100, .center_freq = 5500},
2200 { .hw_value = 120, .center_freq = 5600},
2118 { .hw_value = 140, .center_freq = 5700}, 2201 { .hw_value = 140, .center_freq = 5700},
2202 { .hw_value = 185, .center_freq = 4925},
2203 { .hw_value = 196, .center_freq = 4980},
2204 { .hw_value = 12, .center_freq = 5060},
2205 { .hw_value = 40, .center_freq = 5200},
2206 { .hw_value = 52, .center_freq = 5260},
2207 { .hw_value = 104, .center_freq = 5520},
2208 { .hw_value = 124, .center_freq = 5620},
2119 { .hw_value = 149, .center_freq = 5745}, 2209 { .hw_value = 149, .center_freq = 5745},
2120 { .hw_value = 153, .center_freq = 5765},
2121 { .hw_value = 157, .center_freq = 5785},
2122 { .hw_value = 161, .center_freq = 5805}, 2210 { .hw_value = 161, .center_freq = 5805},
2211 { .hw_value = 187, .center_freq = 4935},
2212 { .hw_value = 7, .center_freq = 5035},
2213 { .hw_value = 16, .center_freq = 5080},
2214 { .hw_value = 42, .center_freq = 5210},
2215 { .hw_value = 56, .center_freq = 5280},
2216 { .hw_value = 108, .center_freq = 5540},
2217 { .hw_value = 128, .center_freq = 5640},
2218 { .hw_value = 153, .center_freq = 5765},
2123 { .hw_value = 165, .center_freq = 5825}, 2219 { .hw_value = 165, .center_freq = 5825},
2124}; 2220};
2125 2221
@@ -2212,8 +2308,7 @@ static ssize_t wl1271_sysfs_show_bt_coex_state(struct device *dev,
2212 struct wl1271 *wl = dev_get_drvdata(dev); 2308 struct wl1271 *wl = dev_get_drvdata(dev);
2213 ssize_t len; 2309 ssize_t len;
2214 2310
2215 /* FIXME: what's the maximum length of buf? page size?*/ 2311 len = PAGE_SIZE;
2216 len = 500;
2217 2312
2218 mutex_lock(&wl->mutex); 2313 mutex_lock(&wl->mutex);
2219 len = snprintf(buf, len, "%d\n\n0 - off\n1 - on\n", 2314 len = snprintf(buf, len, "%d\n\n0 - off\n1 - on\n",
@@ -2274,8 +2369,7 @@ static ssize_t wl1271_sysfs_show_hw_pg_ver(struct device *dev,
2274 struct wl1271 *wl = dev_get_drvdata(dev); 2369 struct wl1271 *wl = dev_get_drvdata(dev);
2275 ssize_t len; 2370 ssize_t len;
2276 2371
2277 /* FIXME: what's the maximum length of buf? page size?*/ 2372 len = PAGE_SIZE;
2278 len = 500;
2279 2373
2280 mutex_lock(&wl->mutex); 2374 mutex_lock(&wl->mutex);
2281 if (wl->hw_pg_ver >= 0) 2375 if (wl->hw_pg_ver >= 0)
@@ -2307,6 +2401,8 @@ int wl1271_register_hw(struct wl1271 *wl)
2307 2401
2308 wl->mac80211_registered = true; 2402 wl->mac80211_registered = true;
2309 2403
2404 register_netdevice_notifier(&wl1271_dev_notifier);
2405
2310 wl1271_notice("loaded"); 2406 wl1271_notice("loaded");
2311 2407
2312 return 0; 2408 return 0;
@@ -2315,6 +2411,7 @@ EXPORT_SYMBOL_GPL(wl1271_register_hw);
2315 2411
2316void wl1271_unregister_hw(struct wl1271 *wl) 2412void wl1271_unregister_hw(struct wl1271 *wl)
2317{ 2413{
2414 unregister_netdevice_notifier(&wl1271_dev_notifier);
2318 ieee80211_unregister_hw(wl->hw); 2415 ieee80211_unregister_hw(wl->hw);
2319 wl->mac80211_registered = false; 2416 wl->mac80211_registered = false;
2320 2417
@@ -2323,6 +2420,14 @@ EXPORT_SYMBOL_GPL(wl1271_unregister_hw);
2323 2420
2324int wl1271_init_ieee80211(struct wl1271 *wl) 2421int wl1271_init_ieee80211(struct wl1271 *wl)
2325{ 2422{
2423 static const u32 cipher_suites[] = {
2424 WLAN_CIPHER_SUITE_WEP40,
2425 WLAN_CIPHER_SUITE_WEP104,
2426 WLAN_CIPHER_SUITE_TKIP,
2427 WLAN_CIPHER_SUITE_CCMP,
2428 WL1271_CIPHER_SUITE_GEM,
2429 };
2430
2326 /* The tx descriptor buffer and the TKIP space. */ 2431 /* The tx descriptor buffer and the TKIP space. */
2327 wl->hw->extra_tx_headroom = WL1271_TKIP_IV_SPACE + 2432 wl->hw->extra_tx_headroom = WL1271_TKIP_IV_SPACE +
2328 sizeof(struct wl1271_tx_hw_descr); 2433 sizeof(struct wl1271_tx_hw_descr);
@@ -2340,13 +2445,14 @@ int wl1271_init_ieee80211(struct wl1271 *wl)
2340 IEEE80211_HW_CONNECTION_MONITOR | 2445 IEEE80211_HW_CONNECTION_MONITOR |
2341 IEEE80211_HW_SUPPORTS_CQM_RSSI; 2446 IEEE80211_HW_SUPPORTS_CQM_RSSI;
2342 2447
2448 wl->hw->wiphy->cipher_suites = cipher_suites;
2449 wl->hw->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
2450
2343 wl->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | 2451 wl->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
2344 BIT(NL80211_IFTYPE_ADHOC); 2452 BIT(NL80211_IFTYPE_ADHOC);
2345 wl->hw->wiphy->max_scan_ssids = 1; 2453 wl->hw->wiphy->max_scan_ssids = 1;
2346 wl->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &wl1271_band_2ghz; 2454 wl->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &wl1271_band_2ghz;
2347 2455 wl->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = &wl1271_band_5ghz;
2348 if (wl1271_11a_enabled())
2349 wl->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = &wl1271_band_5ghz;
2350 2456
2351 wl->hw->queues = 4; 2457 wl->hw->queues = 4;
2352 wl->hw->max_rates = 1; 2458 wl->hw->max_rates = 1;
@@ -2365,6 +2471,7 @@ struct ieee80211_hw *wl1271_alloc_hw(void)
2365 struct platform_device *plat_dev = NULL; 2471 struct platform_device *plat_dev = NULL;
2366 struct wl1271 *wl; 2472 struct wl1271 *wl;
2367 int i, ret; 2473 int i, ret;
2474 unsigned int order;
2368 2475
2369 hw = ieee80211_alloc_hw(sizeof(*wl), &wl1271_ops); 2476 hw = ieee80211_alloc_hw(sizeof(*wl), &wl1271_ops);
2370 if (!hw) { 2477 if (!hw) {
@@ -2392,6 +2499,10 @@ struct ieee80211_hw *wl1271_alloc_hw(void)
2392 2499
2393 INIT_DELAYED_WORK(&wl->elp_work, wl1271_elp_work); 2500 INIT_DELAYED_WORK(&wl->elp_work, wl1271_elp_work);
2394 INIT_DELAYED_WORK(&wl->pspoll_work, wl1271_pspoll_work); 2501 INIT_DELAYED_WORK(&wl->pspoll_work, wl1271_pspoll_work);
2502 INIT_WORK(&wl->irq_work, wl1271_irq_work);
2503 INIT_WORK(&wl->tx_work, wl1271_tx_work);
2504 INIT_WORK(&wl->recovery_work, wl1271_recovery_work);
2505 INIT_DELAYED_WORK(&wl->scan_complete_work, wl1271_scan_complete_work);
2395 wl->channel = WL1271_DEFAULT_CHANNEL; 2506 wl->channel = WL1271_DEFAULT_CHANNEL;
2396 wl->beacon_int = WL1271_DEFAULT_BEACON_INT; 2507 wl->beacon_int = WL1271_DEFAULT_BEACON_INT;
2397 wl->default_key = 0; 2508 wl->default_key = 0;
@@ -2423,11 +2534,18 @@ struct ieee80211_hw *wl1271_alloc_hw(void)
2423 2534
2424 wl1271_debugfs_init(wl); 2535 wl1271_debugfs_init(wl);
2425 2536
2537 order = get_order(WL1271_AGGR_BUFFER_SIZE);
2538 wl->aggr_buf = (u8 *)__get_free_pages(GFP_KERNEL, order);
2539 if (!wl->aggr_buf) {
2540 ret = -ENOMEM;
2541 goto err_hw;
2542 }
2543
2426 /* Register platform device */ 2544 /* Register platform device */
2427 ret = platform_device_register(wl->plat_dev); 2545 ret = platform_device_register(wl->plat_dev);
2428 if (ret) { 2546 if (ret) {
2429 wl1271_error("couldn't register platform device"); 2547 wl1271_error("couldn't register platform device");
2430 goto err_hw; 2548 goto err_aggr;
2431 } 2549 }
2432 dev_set_drvdata(&wl->plat_dev->dev, wl); 2550 dev_set_drvdata(&wl->plat_dev->dev, wl);
2433 2551
@@ -2453,6 +2571,9 @@ err_bt_coex_state:
2453err_platform: 2571err_platform:
2454 platform_device_unregister(wl->plat_dev); 2572 platform_device_unregister(wl->plat_dev);
2455 2573
2574err_aggr:
2575 free_pages((unsigned long)wl->aggr_buf, order);
2576
2456err_hw: 2577err_hw:
2457 wl1271_debugfs_exit(wl); 2578 wl1271_debugfs_exit(wl);
2458 kfree(plat_dev); 2579 kfree(plat_dev);
@@ -2469,6 +2590,8 @@ EXPORT_SYMBOL_GPL(wl1271_alloc_hw);
2469int wl1271_free_hw(struct wl1271 *wl) 2590int wl1271_free_hw(struct wl1271 *wl)
2470{ 2591{
2471 platform_device_unregister(wl->plat_dev); 2592 platform_device_unregister(wl->plat_dev);
2593 free_pages((unsigned long)wl->aggr_buf,
2594 get_order(WL1271_AGGR_BUFFER_SIZE));
2472 kfree(wl->plat_dev); 2595 kfree(wl->plat_dev);
2473 2596
2474 wl1271_debugfs_exit(wl); 2597 wl1271_debugfs_exit(wl);
diff --git a/drivers/net/wireless/wl12xx/wl1271_ps.c b/drivers/net/wireless/wl12xx/wl1271_ps.c
index a5e60e0403e..e3c332e2f97 100644
--- a/drivers/net/wireless/wl12xx/wl1271_ps.c
+++ b/drivers/net/wireless/wl12xx/wl1271_ps.c
@@ -39,6 +39,9 @@ void wl1271_elp_work(struct work_struct *work)
39 39
40 mutex_lock(&wl->mutex); 40 mutex_lock(&wl->mutex);
41 41
42 if (unlikely(wl->state == WL1271_STATE_OFF))
43 goto out;
44
42 if (test_bit(WL1271_FLAG_IN_ELP, &wl->flags) || 45 if (test_bit(WL1271_FLAG_IN_ELP, &wl->flags) ||
43 (!test_bit(WL1271_FLAG_PSM, &wl->flags) && 46 (!test_bit(WL1271_FLAG_PSM, &wl->flags) &&
44 !test_bit(WL1271_FLAG_IDLE, &wl->flags))) 47 !test_bit(WL1271_FLAG_IDLE, &wl->flags)))
@@ -61,7 +64,7 @@ void wl1271_ps_elp_sleep(struct wl1271 *wl)
61 test_bit(WL1271_FLAG_IDLE, &wl->flags)) { 64 test_bit(WL1271_FLAG_IDLE, &wl->flags)) {
62 cancel_delayed_work(&wl->elp_work); 65 cancel_delayed_work(&wl->elp_work);
63 ieee80211_queue_delayed_work(wl->hw, &wl->elp_work, 66 ieee80211_queue_delayed_work(wl->hw, &wl->elp_work,
64 msecs_to_jiffies(ELP_ENTRY_DELAY)); 67 msecs_to_jiffies(ELP_ENTRY_DELAY));
65 } 68 }
66} 69}
67 70
@@ -96,6 +99,7 @@ int wl1271_ps_elp_wakeup(struct wl1271 *wl, bool chip_awake)
96 &compl, msecs_to_jiffies(WL1271_WAKEUP_TIMEOUT)); 99 &compl, msecs_to_jiffies(WL1271_WAKEUP_TIMEOUT));
97 if (ret == 0) { 100 if (ret == 0) {
98 wl1271_error("ELP wakeup timeout!"); 101 wl1271_error("ELP wakeup timeout!");
102 ieee80211_queue_work(wl->hw, &wl->recovery_work);
99 ret = -ETIMEDOUT; 103 ret = -ETIMEDOUT;
100 goto err; 104 goto err;
101 } else if (ret < 0) { 105 } else if (ret < 0) {
@@ -121,7 +125,7 @@ out:
121} 125}
122 126
123int wl1271_ps_set_mode(struct wl1271 *wl, enum wl1271_cmd_ps_mode mode, 127int wl1271_ps_set_mode(struct wl1271 *wl, enum wl1271_cmd_ps_mode mode,
124 bool send) 128 u32 rates, bool send)
125{ 129{
126 int ret; 130 int ret;
127 131
@@ -129,7 +133,14 @@ int wl1271_ps_set_mode(struct wl1271 *wl, enum wl1271_cmd_ps_mode mode,
129 case STATION_POWER_SAVE_MODE: 133 case STATION_POWER_SAVE_MODE:
130 wl1271_debug(DEBUG_PSM, "entering psm"); 134 wl1271_debug(DEBUG_PSM, "entering psm");
131 135
132 ret = wl1271_cmd_ps_mode(wl, STATION_POWER_SAVE_MODE, send); 136 ret = wl1271_acx_wake_up_conditions(wl);
137 if (ret < 0) {
138 wl1271_error("couldn't set wake up conditions");
139 return ret;
140 }
141
142 ret = wl1271_cmd_ps_mode(wl, STATION_POWER_SAVE_MODE,
143 rates, send);
133 if (ret < 0) 144 if (ret < 0)
134 return ret; 145 return ret;
135 146
@@ -152,7 +163,8 @@ int wl1271_ps_set_mode(struct wl1271 *wl, enum wl1271_cmd_ps_mode mode,
152 if (ret < 0) 163 if (ret < 0)
153 return ret; 164 return ret;
154 165
155 ret = wl1271_cmd_ps_mode(wl, STATION_ACTIVE_MODE, send); 166 ret = wl1271_cmd_ps_mode(wl, STATION_ACTIVE_MODE,
167 rates, send);
156 if (ret < 0) 168 if (ret < 0)
157 return ret; 169 return ret;
158 170
diff --git a/drivers/net/wireless/wl12xx/wl1271_ps.h b/drivers/net/wireless/wl12xx/wl1271_ps.h
index 940276f517a..6ba7b032736 100644
--- a/drivers/net/wireless/wl12xx/wl1271_ps.h
+++ b/drivers/net/wireless/wl12xx/wl1271_ps.h
@@ -28,7 +28,7 @@
28#include "wl1271_acx.h" 28#include "wl1271_acx.h"
29 29
30int wl1271_ps_set_mode(struct wl1271 *wl, enum wl1271_cmd_ps_mode mode, 30int wl1271_ps_set_mode(struct wl1271 *wl, enum wl1271_cmd_ps_mode mode,
31 bool send); 31 u32 rates, bool send);
32void wl1271_ps_elp_sleep(struct wl1271 *wl); 32void wl1271_ps_elp_sleep(struct wl1271 *wl);
33int wl1271_ps_elp_wakeup(struct wl1271 *wl, bool chip_awake); 33int wl1271_ps_elp_wakeup(struct wl1271 *wl, bool chip_awake);
34void wl1271_elp_work(struct work_struct *work); 34void wl1271_elp_work(struct work_struct *work);
diff --git a/drivers/net/wireless/wl12xx/wl1271_rx.c b/drivers/net/wireless/wl12xx/wl1271_rx.c
index 94da5dd7723..bea133b6e48 100644
--- a/drivers/net/wireless/wl12xx/wl1271_rx.c
+++ b/drivers/net/wireless/wl12xx/wl1271_rx.c
@@ -74,7 +74,7 @@ static void wl1271_rx_status(struct wl1271 *wl,
74 } 74 }
75} 75}
76 76
77static void wl1271_rx_handle_data(struct wl1271 *wl, u32 length) 77static int wl1271_rx_handle_data(struct wl1271 *wl, u8 *data, u32 length)
78{ 78{
79 struct wl1271_rx_descriptor *desc; 79 struct wl1271_rx_descriptor *desc;
80 struct sk_buff *skb; 80 struct sk_buff *skb;
@@ -87,16 +87,16 @@ static void wl1271_rx_handle_data(struct wl1271 *wl, u32 length)
87 * workaround this by not retrieving them at all. 87 * workaround this by not retrieving them at all.
88 */ 88 */
89 if (unlikely(wl->state == WL1271_STATE_PLT)) 89 if (unlikely(wl->state == WL1271_STATE_PLT))
90 return; 90 return -EINVAL;
91 91
92 skb = __dev_alloc_skb(length, GFP_KERNEL); 92 skb = __dev_alloc_skb(length, GFP_KERNEL);
93 if (!skb) { 93 if (!skb) {
94 wl1271_error("Couldn't allocate RX frame"); 94 wl1271_error("Couldn't allocate RX frame");
95 return; 95 return -ENOMEM;
96 } 96 }
97 97
98 buf = skb_put(skb, length); 98 buf = skb_put(skb, length);
99 wl1271_read(wl, WL1271_SLV_MEM_DATA, buf, length, true); 99 memcpy(buf, data, length);
100 100
101 /* the data read starts with the descriptor */ 101 /* the data read starts with the descriptor */
102 desc = (struct wl1271_rx_descriptor *) buf; 102 desc = (struct wl1271_rx_descriptor *) buf;
@@ -116,6 +116,8 @@ static void wl1271_rx_handle_data(struct wl1271 *wl, u32 length)
116 skb_trim(skb, skb->len - desc->pad_len); 116 skb_trim(skb, skb->len - desc->pad_len);
117 117
118 ieee80211_rx_ni(wl->hw, skb); 118 ieee80211_rx_ni(wl->hw, skb);
119
120 return 0;
119} 121}
120 122
121void wl1271_rx(struct wl1271 *wl, struct wl1271_fw_status *status) 123void wl1271_rx(struct wl1271 *wl, struct wl1271_fw_status *status)
@@ -124,31 +126,60 @@ void wl1271_rx(struct wl1271 *wl, struct wl1271_fw_status *status)
124 u32 buf_size; 126 u32 buf_size;
125 u32 fw_rx_counter = status->fw_rx_counter & NUM_RX_PKT_DESC_MOD_MASK; 127 u32 fw_rx_counter = status->fw_rx_counter & NUM_RX_PKT_DESC_MOD_MASK;
126 u32 drv_rx_counter = wl->rx_counter & NUM_RX_PKT_DESC_MOD_MASK; 128 u32 drv_rx_counter = wl->rx_counter & NUM_RX_PKT_DESC_MOD_MASK;
129 u32 rx_counter;
127 u32 mem_block; 130 u32 mem_block;
131 u32 pkt_length;
132 u32 pkt_offset;
128 133
129 while (drv_rx_counter != fw_rx_counter) { 134 while (drv_rx_counter != fw_rx_counter) {
130 mem_block = wl1271_rx_get_mem_block(status, drv_rx_counter); 135 buf_size = 0;
131 buf_size = wl1271_rx_get_buf_size(status, drv_rx_counter); 136 rx_counter = drv_rx_counter;
137 while (rx_counter != fw_rx_counter) {
138 pkt_length = wl1271_rx_get_buf_size(status, rx_counter);
139 if (buf_size + pkt_length > WL1271_AGGR_BUFFER_SIZE)
140 break;
141 buf_size += pkt_length;
142 rx_counter++;
143 rx_counter &= NUM_RX_PKT_DESC_MOD_MASK;
144 }
132 145
133 if (buf_size == 0) { 146 if (buf_size == 0) {
134 wl1271_warning("received empty data"); 147 wl1271_warning("received empty data");
135 break; 148 break;
136 } 149 }
137 150
151 /*
152 * Choose the block we want to read
153 * For aggregated packets, only the first memory block should
154 * be retrieved. The FW takes care of the rest.
155 */
156 mem_block = wl1271_rx_get_mem_block(status, drv_rx_counter);
138 wl->rx_mem_pool_addr.addr = (mem_block << 8) + 157 wl->rx_mem_pool_addr.addr = (mem_block << 8) +
139 le32_to_cpu(wl_mem_map->packet_memory_pool_start); 158 le32_to_cpu(wl_mem_map->packet_memory_pool_start);
140 wl->rx_mem_pool_addr.addr_extra = 159 wl->rx_mem_pool_addr.addr_extra =
141 wl->rx_mem_pool_addr.addr + 4; 160 wl->rx_mem_pool_addr.addr + 4;
142
143 /* Choose the block we want to read */
144 wl1271_write(wl, WL1271_SLV_REG_DATA, &wl->rx_mem_pool_addr, 161 wl1271_write(wl, WL1271_SLV_REG_DATA, &wl->rx_mem_pool_addr,
145 sizeof(wl->rx_mem_pool_addr), false); 162 sizeof(wl->rx_mem_pool_addr), false);
146 163
147 wl1271_rx_handle_data(wl, buf_size); 164 /* Read all available packets at once */
148 165 wl1271_read(wl, WL1271_SLV_MEM_DATA, wl->aggr_buf,
149 wl->rx_counter++; 166 buf_size, true);
150 drv_rx_counter = wl->rx_counter & NUM_RX_PKT_DESC_MOD_MASK; 167
168 /* Split data into separate packets */
169 pkt_offset = 0;
170 while (pkt_offset < buf_size) {
171 pkt_length = wl1271_rx_get_buf_size(status,
172 drv_rx_counter);
173 if (wl1271_rx_handle_data(wl,
174 wl->aggr_buf + pkt_offset,
175 pkt_length) < 0)
176 break;
177 wl->rx_counter++;
178 drv_rx_counter++;
179 drv_rx_counter &= NUM_RX_PKT_DESC_MOD_MASK;
180 pkt_offset += pkt_length;
181 }
151 } 182 }
152 183 wl1271_write32(wl, RX_DRIVER_COUNTER_ADDRESS,
153 wl1271_write32(wl, RX_DRIVER_COUNTER_ADDRESS, wl->rx_counter); 184 cpu_to_le32(wl->rx_counter));
154} 185}
diff --git a/drivers/net/wireless/wl12xx/wl1271_scan.c b/drivers/net/wireless/wl12xx/wl1271_scan.c
index e4950c8e396..909bb47995b 100644
--- a/drivers/net/wireless/wl12xx/wl1271_scan.c
+++ b/drivers/net/wireless/wl12xx/wl1271_scan.c
@@ -28,11 +28,43 @@
28#include "wl1271_scan.h" 28#include "wl1271_scan.h"
29#include "wl1271_acx.h" 29#include "wl1271_acx.h"
30 30
31void wl1271_scan_complete_work(struct work_struct *work)
32{
33 struct delayed_work *dwork;
34 struct wl1271 *wl;
35
36 dwork = container_of(work, struct delayed_work, work);
37 wl = container_of(dwork, struct wl1271, scan_complete_work);
38
39 wl1271_debug(DEBUG_SCAN, "Scanning complete");
40
41 mutex_lock(&wl->mutex);
42
43 if (wl->scan.state == WL1271_SCAN_STATE_IDLE) {
44 mutex_unlock(&wl->mutex);
45 return;
46 }
47
48 wl->scan.state = WL1271_SCAN_STATE_IDLE;
49 kfree(wl->scan.scanned_ch);
50 wl->scan.scanned_ch = NULL;
51 mutex_unlock(&wl->mutex);
52
53 ieee80211_scan_completed(wl->hw, false);
54
55 if (wl->scan.failed) {
56 wl1271_info("Scan completed due to error.");
57 ieee80211_queue_work(wl->hw, &wl->recovery_work);
58 }
59}
60
61
31static int wl1271_get_scan_channels(struct wl1271 *wl, 62static int wl1271_get_scan_channels(struct wl1271 *wl,
32 struct cfg80211_scan_request *req, 63 struct cfg80211_scan_request *req,
33 struct basic_scan_channel_params *channels, 64 struct basic_scan_channel_params *channels,
34 enum ieee80211_band band, bool passive) 65 enum ieee80211_band band, bool passive)
35{ 66{
67 struct conf_scan_settings *c = &wl->conf.scan;
36 int i, j; 68 int i, j;
37 u32 flags; 69 u32 flags;
38 70
@@ -60,10 +92,17 @@ static int wl1271_get_scan_channels(struct wl1271 *wl,
60 wl1271_debug(DEBUG_SCAN, "beacon_found %d", 92 wl1271_debug(DEBUG_SCAN, "beacon_found %d",
61 req->channels[i]->beacon_found); 93 req->channels[i]->beacon_found);
62 94
63 channels[j].min_duration = 95 if (!passive) {
64 cpu_to_le32(WL1271_SCAN_CHAN_MIN_DURATION); 96 channels[j].min_duration =
65 channels[j].max_duration = 97 cpu_to_le32(c->min_dwell_time_active);
66 cpu_to_le32(WL1271_SCAN_CHAN_MAX_DURATION); 98 channels[j].max_duration =
99 cpu_to_le32(c->max_dwell_time_active);
100 } else {
101 channels[j].min_duration =
102 cpu_to_le32(c->min_dwell_time_passive);
103 channels[j].max_duration =
104 cpu_to_le32(c->max_dwell_time_passive);
105 }
67 channels[j].early_termination = 0; 106 channels[j].early_termination = 0;
68 channels[j].tx_power_att = req->channels[i]->max_power; 107 channels[j].tx_power_att = req->channels[i]->max_power;
69 channels[j].channel = req->channels[i]->hw_value; 108 channels[j].channel = req->channels[i]->hw_value;
@@ -100,8 +139,11 @@ static int wl1271_scan_send(struct wl1271 *wl, enum ieee80211_band band,
100 139
101 /* We always use high priority scans */ 140 /* We always use high priority scans */
102 scan_options = WL1271_SCAN_OPT_PRIORITY_HIGH; 141 scan_options = WL1271_SCAN_OPT_PRIORITY_HIGH;
103 if(passive) 142
143 /* No SSIDs means that we have a forced passive scan */
144 if (passive || wl->scan.req->n_ssids == 0)
104 scan_options |= WL1271_SCAN_OPT_PASSIVE; 145 scan_options |= WL1271_SCAN_OPT_PASSIVE;
146
105 cmd->params.scan_options = cpu_to_le16(scan_options); 147 cmd->params.scan_options = cpu_to_le16(scan_options);
106 148
107 cmd->params.n_ch = wl1271_get_scan_channels(wl, wl->scan.req, 149 cmd->params.n_ch = wl1271_get_scan_channels(wl, wl->scan.req,
@@ -117,7 +159,7 @@ static int wl1271_scan_send(struct wl1271 *wl, enum ieee80211_band band,
117 cmd->params.rx_filter_options = 159 cmd->params.rx_filter_options =
118 cpu_to_le32(CFG_RX_PRSP_EN | CFG_RX_MGMT_EN | CFG_RX_BCN_EN); 160 cpu_to_le32(CFG_RX_PRSP_EN | CFG_RX_MGMT_EN | CFG_RX_BCN_EN);
119 161
120 cmd->params.n_probe_reqs = WL1271_SCAN_PROBE_REQS; 162 cmd->params.n_probe_reqs = wl->conf.scan.num_probe_reqs;
121 cmd->params.tx_rate = cpu_to_le32(basic_rate); 163 cmd->params.tx_rate = cpu_to_le32(basic_rate);
122 cmd->params.tid_trigger = 0; 164 cmd->params.tid_trigger = 0;
123 cmd->params.scan_tag = WL1271_SCAN_DEFAULT_TAG; 165 cmd->params.scan_tag = WL1271_SCAN_DEFAULT_TAG;
@@ -165,7 +207,7 @@ out:
165 207
166void wl1271_scan_stm(struct wl1271 *wl) 208void wl1271_scan_stm(struct wl1271 *wl)
167{ 209{
168 int ret; 210 int ret = 0;
169 211
170 switch (wl->scan.state) { 212 switch (wl->scan.state) {
171 case WL1271_SCAN_STATE_IDLE: 213 case WL1271_SCAN_STATE_IDLE:
@@ -185,7 +227,7 @@ void wl1271_scan_stm(struct wl1271 *wl)
185 ret = wl1271_scan_send(wl, IEEE80211_BAND_2GHZ, true, 227 ret = wl1271_scan_send(wl, IEEE80211_BAND_2GHZ, true,
186 wl->conf.tx.basic_rate); 228 wl->conf.tx.basic_rate);
187 if (ret == WL1271_NOTHING_TO_SCAN) { 229 if (ret == WL1271_NOTHING_TO_SCAN) {
188 if (wl1271_11a_enabled()) 230 if (wl->enable_11a)
189 wl->scan.state = WL1271_SCAN_STATE_5GHZ_ACTIVE; 231 wl->scan.state = WL1271_SCAN_STATE_5GHZ_ACTIVE;
190 else 232 else
191 wl->scan.state = WL1271_SCAN_STATE_DONE; 233 wl->scan.state = WL1271_SCAN_STATE_DONE;
@@ -215,18 +257,22 @@ void wl1271_scan_stm(struct wl1271 *wl)
215 break; 257 break;
216 258
217 case WL1271_SCAN_STATE_DONE: 259 case WL1271_SCAN_STATE_DONE:
218 ieee80211_scan_completed(wl->hw, false); 260 wl->scan.failed = false;
219 261 cancel_delayed_work(&wl->scan_complete_work);
220 kfree(wl->scan.scanned_ch); 262 ieee80211_queue_delayed_work(wl->hw, &wl->scan_complete_work,
221 wl->scan.scanned_ch = NULL; 263 msecs_to_jiffies(0));
222
223 wl->scan.state = WL1271_SCAN_STATE_IDLE;
224 break; 264 break;
225 265
226 default: 266 default:
227 wl1271_error("invalid scan state"); 267 wl1271_error("invalid scan state");
228 break; 268 break;
229 } 269 }
270
271 if (ret < 0) {
272 cancel_delayed_work(&wl->scan_complete_work);
273 ieee80211_queue_delayed_work(wl->hw, &wl->scan_complete_work,
274 msecs_to_jiffies(0));
275 }
230} 276}
231 277
232int wl1271_scan(struct wl1271 *wl, const u8 *ssid, size_t ssid_len, 278int wl1271_scan(struct wl1271 *wl, const u8 *ssid, size_t ssid_len,
@@ -249,6 +295,11 @@ int wl1271_scan(struct wl1271 *wl, const u8 *ssid, size_t ssid_len,
249 wl->scan.scanned_ch = kcalloc(req->n_channels, 295 wl->scan.scanned_ch = kcalloc(req->n_channels,
250 sizeof(*wl->scan.scanned_ch), 296 sizeof(*wl->scan.scanned_ch),
251 GFP_KERNEL); 297 GFP_KERNEL);
298 /* we assume failure so that timeout scenarios are handled correctly */
299 wl->scan.failed = true;
300 ieee80211_queue_delayed_work(wl->hw, &wl->scan_complete_work,
301 msecs_to_jiffies(WL1271_SCAN_TIMEOUT));
302
252 wl1271_scan_stm(wl); 303 wl1271_scan_stm(wl);
253 304
254 return 0; 305 return 0;
diff --git a/drivers/net/wireless/wl12xx/wl1271_scan.h b/drivers/net/wireless/wl12xx/wl1271_scan.h
index f1815700f5f..6d57127b5e6 100644
--- a/drivers/net/wireless/wl12xx/wl1271_scan.h
+++ b/drivers/net/wireless/wl12xx/wl1271_scan.h
@@ -32,6 +32,7 @@ int wl1271_scan_build_probe_req(struct wl1271 *wl,
32 const u8 *ssid, size_t ssid_len, 32 const u8 *ssid, size_t ssid_len,
33 const u8 *ie, size_t ie_len, u8 band); 33 const u8 *ie, size_t ie_len, u8 band);
34void wl1271_scan_stm(struct wl1271 *wl); 34void wl1271_scan_stm(struct wl1271 *wl);
35void wl1271_scan_complete_work(struct work_struct *work);
35 36
36#define WL1271_SCAN_MAX_CHANNELS 24 37#define WL1271_SCAN_MAX_CHANNELS 24
37#define WL1271_SCAN_DEFAULT_TAG 1 38#define WL1271_SCAN_DEFAULT_TAG 1
@@ -39,11 +40,10 @@ void wl1271_scan_stm(struct wl1271 *wl);
39#define WL1271_SCAN_OPT_ACTIVE 0 40#define WL1271_SCAN_OPT_ACTIVE 0
40#define WL1271_SCAN_OPT_PASSIVE 1 41#define WL1271_SCAN_OPT_PASSIVE 1
41#define WL1271_SCAN_OPT_PRIORITY_HIGH 4 42#define WL1271_SCAN_OPT_PRIORITY_HIGH 4
42#define WL1271_SCAN_CHAN_MIN_DURATION 30000 /* TU */
43#define WL1271_SCAN_CHAN_MAX_DURATION 60000 /* TU */
44#define WL1271_SCAN_BAND_2_4_GHZ 0 43#define WL1271_SCAN_BAND_2_4_GHZ 0
45#define WL1271_SCAN_BAND_5_GHZ 1 44#define WL1271_SCAN_BAND_5_GHZ 1
46#define WL1271_SCAN_PROBE_REQS 3 45
46#define WL1271_SCAN_TIMEOUT 10000 /* msec */
47 47
48enum { 48enum {
49 WL1271_SCAN_STATE_IDLE, 49 WL1271_SCAN_STATE_IDLE,
diff --git a/drivers/net/wireless/wl12xx/wl1271_sdio.c b/drivers/net/wireless/wl12xx/wl1271_sdio.c
index f2f04663627..4c250d7dc3f 100644
--- a/drivers/net/wireless/wl12xx/wl1271_sdio.c
+++ b/drivers/net/wireless/wl12xx/wl1271_sdio.c
@@ -274,9 +274,8 @@ static void __devexit wl1271_remove(struct sdio_func *func)
274{ 274{
275 struct wl1271 *wl = sdio_get_drvdata(func); 275 struct wl1271 *wl = sdio_get_drvdata(func);
276 276
277 free_irq(wl->irq, wl);
278
279 wl1271_unregister_hw(wl); 277 wl1271_unregister_hw(wl);
278 free_irq(wl->irq, wl);
280 wl1271_free_hw(wl); 279 wl1271_free_hw(wl);
281} 280}
282 281
diff --git a/drivers/net/wireless/wl12xx/wl1271_spi.c b/drivers/net/wireless/wl12xx/wl1271_spi.c
index ced0a9e2c7e..ef801680773 100644
--- a/drivers/net/wireless/wl12xx/wl1271_spi.c
+++ b/drivers/net/wireless/wl12xx/wl1271_spi.c
@@ -63,6 +63,11 @@
63 ((WL1271_BUSY_WORD_LEN - 4) / sizeof(u32)) 63 ((WL1271_BUSY_WORD_LEN - 4) / sizeof(u32))
64#define HW_ACCESS_WSPI_INIT_CMD_MASK 0 64#define HW_ACCESS_WSPI_INIT_CMD_MASK 0
65 65
66/* HW limitation: maximum possible chunk size is 4095 bytes */
67#define WSPI_MAX_CHUNK_SIZE 4092
68
69#define WSPI_MAX_NUM_OF_CHUNKS (WL1271_AGGR_BUFFER_SIZE / WSPI_MAX_CHUNK_SIZE)
70
66static inline struct spi_device *wl_to_spi(struct wl1271 *wl) 71static inline struct spi_device *wl_to_spi(struct wl1271 *wl)
67{ 72{
68 return wl->if_priv; 73 return wl->if_priv;
@@ -202,90 +207,117 @@ static int wl1271_spi_read_busy(struct wl1271 *wl)
202static void wl1271_spi_raw_read(struct wl1271 *wl, int addr, void *buf, 207static void wl1271_spi_raw_read(struct wl1271 *wl, int addr, void *buf,
203 size_t len, bool fixed) 208 size_t len, bool fixed)
204{ 209{
205 struct spi_transfer t[3]; 210 struct spi_transfer t[2];
206 struct spi_message m; 211 struct spi_message m;
207 u32 *busy_buf; 212 u32 *busy_buf;
208 u32 *cmd; 213 u32 *cmd;
214 u32 chunk_len;
209 215
210 cmd = &wl->buffer_cmd; 216 while (len > 0) {
211 busy_buf = wl->buffer_busyword; 217 chunk_len = min((size_t)WSPI_MAX_CHUNK_SIZE, len);
212 218
213 *cmd = 0; 219 cmd = &wl->buffer_cmd;
214 *cmd |= WSPI_CMD_READ; 220 busy_buf = wl->buffer_busyword;
215 *cmd |= (len << WSPI_CMD_BYTE_LENGTH_OFFSET) & WSPI_CMD_BYTE_LENGTH;
216 *cmd |= addr & WSPI_CMD_BYTE_ADDR;
217 221
218 if (fixed) 222 *cmd = 0;
219 *cmd |= WSPI_CMD_FIXED; 223 *cmd |= WSPI_CMD_READ;
224 *cmd |= (chunk_len << WSPI_CMD_BYTE_LENGTH_OFFSET) &
225 WSPI_CMD_BYTE_LENGTH;
226 *cmd |= addr & WSPI_CMD_BYTE_ADDR;
220 227
221 spi_message_init(&m); 228 if (fixed)
222 memset(t, 0, sizeof(t)); 229 *cmd |= WSPI_CMD_FIXED;
223 230
224 t[0].tx_buf = cmd; 231 spi_message_init(&m);
225 t[0].len = 4; 232 memset(t, 0, sizeof(t));
226 t[0].cs_change = true;
227 spi_message_add_tail(&t[0], &m);
228 233
229 /* Busy and non busy words read */ 234 t[0].tx_buf = cmd;
230 t[1].rx_buf = busy_buf; 235 t[0].len = 4;
231 t[1].len = WL1271_BUSY_WORD_LEN; 236 t[0].cs_change = true;
232 t[1].cs_change = true; 237 spi_message_add_tail(&t[0], &m);
233 spi_message_add_tail(&t[1], &m);
234 238
235 spi_sync(wl_to_spi(wl), &m); 239 /* Busy and non busy words read */
240 t[1].rx_buf = busy_buf;
241 t[1].len = WL1271_BUSY_WORD_LEN;
242 t[1].cs_change = true;
243 spi_message_add_tail(&t[1], &m);
236 244
237 if (!(busy_buf[WL1271_BUSY_WORD_CNT - 1] & 0x1) && 245 spi_sync(wl_to_spi(wl), &m);
238 wl1271_spi_read_busy(wl)) {
239 memset(buf, 0, len);
240 return;
241 }
242 246
243 spi_message_init(&m); 247 if (!(busy_buf[WL1271_BUSY_WORD_CNT - 1] & 0x1) &&
244 memset(t, 0, sizeof(t)); 248 wl1271_spi_read_busy(wl)) {
249 memset(buf, 0, chunk_len);
250 return;
251 }
245 252
246 t[0].rx_buf = buf; 253 spi_message_init(&m);
247 t[0].len = len; 254 memset(t, 0, sizeof(t));
248 t[0].cs_change = true;
249 spi_message_add_tail(&t[0], &m);
250 255
251 spi_sync(wl_to_spi(wl), &m); 256 t[0].rx_buf = buf;
257 t[0].len = chunk_len;
258 t[0].cs_change = true;
259 spi_message_add_tail(&t[0], &m);
260
261 spi_sync(wl_to_spi(wl), &m);
262
263 wl1271_dump(DEBUG_SPI, "spi_read cmd -> ", cmd, sizeof(*cmd));
264 wl1271_dump(DEBUG_SPI, "spi_read buf <- ", buf, chunk_len);
252 265
253 wl1271_dump(DEBUG_SPI, "spi_read cmd -> ", cmd, sizeof(*cmd)); 266 if (!fixed)
254 wl1271_dump(DEBUG_SPI, "spi_read buf <- ", buf, len); 267 addr += chunk_len;
268 buf += chunk_len;
269 len -= chunk_len;
270 }
255} 271}
256 272
257static void wl1271_spi_raw_write(struct wl1271 *wl, int addr, void *buf, 273static void wl1271_spi_raw_write(struct wl1271 *wl, int addr, void *buf,
258 size_t len, bool fixed) 274 size_t len, bool fixed)
259{ 275{
260 struct spi_transfer t[2]; 276 struct spi_transfer t[2 * WSPI_MAX_NUM_OF_CHUNKS];
261 struct spi_message m; 277 struct spi_message m;
278 u32 commands[WSPI_MAX_NUM_OF_CHUNKS];
262 u32 *cmd; 279 u32 *cmd;
280 u32 chunk_len;
281 int i;
263 282
264 cmd = &wl->buffer_cmd; 283 WARN_ON(len > WL1271_AGGR_BUFFER_SIZE);
265
266 *cmd = 0;
267 *cmd |= WSPI_CMD_WRITE;
268 *cmd |= (len << WSPI_CMD_BYTE_LENGTH_OFFSET) & WSPI_CMD_BYTE_LENGTH;
269 *cmd |= addr & WSPI_CMD_BYTE_ADDR;
270
271 if (fixed)
272 *cmd |= WSPI_CMD_FIXED;
273 284
274 spi_message_init(&m); 285 spi_message_init(&m);
275 memset(t, 0, sizeof(t)); 286 memset(t, 0, sizeof(t));
276 287
277 t[0].tx_buf = cmd; 288 cmd = &commands[0];
278 t[0].len = sizeof(*cmd); 289 i = 0;
279 spi_message_add_tail(&t[0], &m); 290 while (len > 0) {
291 chunk_len = min((size_t)WSPI_MAX_CHUNK_SIZE, len);
280 292
281 t[1].tx_buf = buf; 293 *cmd = 0;
282 t[1].len = len; 294 *cmd |= WSPI_CMD_WRITE;
283 spi_message_add_tail(&t[1], &m); 295 *cmd |= (chunk_len << WSPI_CMD_BYTE_LENGTH_OFFSET) &
296 WSPI_CMD_BYTE_LENGTH;
297 *cmd |= addr & WSPI_CMD_BYTE_ADDR;
284 298
285 spi_sync(wl_to_spi(wl), &m); 299 if (fixed)
300 *cmd |= WSPI_CMD_FIXED;
286 301
287 wl1271_dump(DEBUG_SPI, "spi_write cmd -> ", cmd, sizeof(*cmd)); 302 t[i].tx_buf = cmd;
288 wl1271_dump(DEBUG_SPI, "spi_write buf -> ", buf, len); 303 t[i].len = sizeof(*cmd);
304 spi_message_add_tail(&t[i++], &m);
305
306 t[i].tx_buf = buf;
307 t[i].len = chunk_len;
308 spi_message_add_tail(&t[i++], &m);
309
310 wl1271_dump(DEBUG_SPI, "spi_write cmd -> ", cmd, sizeof(*cmd));
311 wl1271_dump(DEBUG_SPI, "spi_write buf -> ", buf, chunk_len);
312
313 if (!fixed)
314 addr += chunk_len;
315 buf += chunk_len;
316 len -= chunk_len;
317 cmd++;
318 }
319
320 spi_sync(wl_to_spi(wl), &m);
289} 321}
290 322
291static irqreturn_t wl1271_irq(int irq, void *cookie) 323static irqreturn_t wl1271_irq(int irq, void *cookie)
@@ -416,9 +448,8 @@ static int __devexit wl1271_remove(struct spi_device *spi)
416{ 448{
417 struct wl1271 *wl = dev_get_drvdata(&spi->dev); 449 struct wl1271 *wl = dev_get_drvdata(&spi->dev);
418 450
419 free_irq(wl->irq, wl);
420
421 wl1271_unregister_hw(wl); 451 wl1271_unregister_hw(wl);
452 free_irq(wl->irq, wl);
422 wl1271_free_hw(wl); 453 wl1271_free_hw(wl);
423 454
424 return 0; 455 return 0;
diff --git a/drivers/net/wireless/wl12xx/wl1271_testmode.c b/drivers/net/wireless/wl12xx/wl1271_testmode.c
index 6e0952f79e9..a3aa84386c8 100644
--- a/drivers/net/wireless/wl12xx/wl1271_testmode.c
+++ b/drivers/net/wireless/wl12xx/wl1271_testmode.c
@@ -199,19 +199,6 @@ static int wl1271_tm_cmd_nvs_push(struct wl1271 *wl, struct nlattr *tb[])
199 buf = nla_data(tb[WL1271_TM_ATTR_DATA]); 199 buf = nla_data(tb[WL1271_TM_ATTR_DATA]);
200 len = nla_len(tb[WL1271_TM_ATTR_DATA]); 200 len = nla_len(tb[WL1271_TM_ATTR_DATA]);
201 201
202 /*
203 * FIXME: the LEGACY NVS image support (NVS's missing the 5GHz band
204 * configurations) can be removed when those NVS files stop floating
205 * around.
206 */
207 if (len != sizeof(struct wl1271_nvs_file) &&
208 (len != WL1271_INI_LEGACY_NVS_FILE_SIZE ||
209 wl1271_11a_enabled())) {
210 wl1271_error("nvs size is not as expected: %zu != %zu",
211 len, sizeof(struct wl1271_nvs_file));
212 return -EMSGSIZE;
213 }
214
215 mutex_lock(&wl->mutex); 202 mutex_lock(&wl->mutex);
216 203
217 kfree(wl->nvs); 204 kfree(wl->nvs);
@@ -224,6 +211,7 @@ static int wl1271_tm_cmd_nvs_push(struct wl1271 *wl, struct nlattr *tb[])
224 } 211 }
225 212
226 memcpy(wl->nvs, buf, len); 213 memcpy(wl->nvs, buf, len);
214 wl->nvs_len = len;
227 215
228 wl1271_debug(DEBUG_TESTMODE, "testmode pushed nvs"); 216 wl1271_debug(DEBUG_TESTMODE, "testmode pushed nvs");
229 217
diff --git a/drivers/net/wireless/wl12xx/wl1271_tx.c b/drivers/net/wireless/wl12xx/wl1271_tx.c
index dc0b46c93c4..e3dc13c4d01 100644
--- a/drivers/net/wireless/wl12xx/wl1271_tx.c
+++ b/drivers/net/wireless/wl12xx/wl1271_tx.c
@@ -43,13 +43,17 @@ static int wl1271_tx_id(struct wl1271 *wl, struct sk_buff *skb)
43 return -EBUSY; 43 return -EBUSY;
44} 44}
45 45
46static int wl1271_tx_allocate(struct wl1271 *wl, struct sk_buff *skb, u32 extra) 46static int wl1271_tx_allocate(struct wl1271 *wl, struct sk_buff *skb, u32 extra,
47 u32 buf_offset)
47{ 48{
48 struct wl1271_tx_hw_descr *desc; 49 struct wl1271_tx_hw_descr *desc;
49 u32 total_len = skb->len + sizeof(struct wl1271_tx_hw_descr) + extra; 50 u32 total_len = skb->len + sizeof(struct wl1271_tx_hw_descr) + extra;
50 u32 total_blocks; 51 u32 total_blocks;
51 int id, ret = -EBUSY; 52 int id, ret = -EBUSY;
52 53
54 if (buf_offset + total_len > WL1271_AGGR_BUFFER_SIZE)
55 return -EBUSY;
56
53 /* allocate free identifier for the packet */ 57 /* allocate free identifier for the packet */
54 id = wl1271_tx_id(wl, skb); 58 id = wl1271_tx_id(wl, skb);
55 if (id < 0) 59 if (id < 0)
@@ -82,7 +86,7 @@ static int wl1271_tx_allocate(struct wl1271 *wl, struct sk_buff *skb, u32 extra)
82 return ret; 86 return ret;
83} 87}
84 88
85static int wl1271_tx_fill_hdr(struct wl1271 *wl, struct sk_buff *skb, 89static void wl1271_tx_fill_hdr(struct wl1271 *wl, struct sk_buff *skb,
86 u32 extra, struct ieee80211_tx_info *control) 90 u32 extra, struct ieee80211_tx_info *control)
87{ 91{
88 struct timespec ts; 92 struct timespec ts;
@@ -110,9 +114,9 @@ static int wl1271_tx_fill_hdr(struct wl1271 *wl, struct sk_buff *skb,
110 /* configure the tx attributes */ 114 /* configure the tx attributes */
111 tx_attr = wl->session_counter << TX_HW_ATTR_OFST_SESSION_COUNTER; 115 tx_attr = wl->session_counter << TX_HW_ATTR_OFST_SESSION_COUNTER;
112 116
113 /* queue */ 117 /* queue (we use same identifiers for tid's and ac's */
114 ac = wl1271_tx_get_queue(skb_get_queue_mapping(skb)); 118 ac = wl1271_tx_get_queue(skb_get_queue_mapping(skb));
115 desc->tid = wl1271_tx_ac_to_tid(ac); 119 desc->tid = ac;
116 120
117 desc->aid = TX_HW_DEFAULT_AID; 121 desc->aid = TX_HW_DEFAULT_AID;
118 desc->reserved = 0; 122 desc->reserved = 0;
@@ -133,59 +137,17 @@ static int wl1271_tx_fill_hdr(struct wl1271 *wl, struct sk_buff *skb,
133 desc->tx_attr = cpu_to_le16(tx_attr); 137 desc->tx_attr = cpu_to_le16(tx_attr);
134 138
135 wl1271_debug(DEBUG_TX, "tx_fill_hdr: pad: %d", pad); 139 wl1271_debug(DEBUG_TX, "tx_fill_hdr: pad: %d", pad);
136 return 0;
137}
138
139static int wl1271_tx_send_packet(struct wl1271 *wl, struct sk_buff *skb,
140 struct ieee80211_tx_info *control)
141{
142
143 struct wl1271_tx_hw_descr *desc;
144 int len;
145
146 /* FIXME: This is a workaround for getting non-aligned packets.
147 This happens at least with EAPOL packets from the user space.
148 Our DMA requires packets to be aligned on a 4-byte boundary.
149 */
150 if (unlikely((long)skb->data & 0x03)) {
151 int offset = (4 - (long)skb->data) & 0x03;
152 wl1271_debug(DEBUG_TX, "skb offset %d", offset);
153
154 /* check whether the current skb can be used */
155 if (!skb_cloned(skb) && (skb_tailroom(skb) >= offset)) {
156 unsigned char *src = skb->data;
157
158 /* align the buffer on a 4-byte boundary */
159 skb_reserve(skb, offset);
160 memmove(skb->data, src, skb->len);
161 } else {
162 wl1271_info("No handler, fixme!");
163 return -EINVAL;
164 }
165 }
166
167 len = WL1271_TX_ALIGN(skb->len);
168
169 /* perform a fixed address block write with the packet */
170 wl1271_write(wl, WL1271_SLV_MEM_DATA, skb->data, len, true);
171
172 /* write packet new counter into the write access register */
173 wl->tx_packets_count++;
174
175 desc = (struct wl1271_tx_hw_descr *) skb->data;
176 wl1271_debug(DEBUG_TX, "tx id %u skb 0x%p payload %u (%u words)",
177 desc->id, skb, len, desc->length);
178
179 return 0;
180} 140}
181 141
182/* caller must hold wl->mutex */ 142/* caller must hold wl->mutex */
183static int wl1271_tx_frame(struct wl1271 *wl, struct sk_buff *skb) 143static int wl1271_prepare_tx_frame(struct wl1271 *wl, struct sk_buff *skb,
144 u32 buf_offset)
184{ 145{
185 struct ieee80211_tx_info *info; 146 struct ieee80211_tx_info *info;
186 u32 extra = 0; 147 u32 extra = 0;
187 int ret = 0; 148 int ret = 0;
188 u8 idx; 149 u8 idx;
150 u32 total_len;
189 151
190 if (!skb) 152 if (!skb)
191 return -EINVAL; 153 return -EINVAL;
@@ -208,19 +170,22 @@ static int wl1271_tx_frame(struct wl1271 *wl, struct sk_buff *skb)
208 } 170 }
209 } 171 }
210 172
211 ret = wl1271_tx_allocate(wl, skb, extra); 173 ret = wl1271_tx_allocate(wl, skb, extra, buf_offset);
212 if (ret < 0) 174 if (ret < 0)
213 return ret; 175 return ret;
214 176
215 ret = wl1271_tx_fill_hdr(wl, skb, extra, info); 177 wl1271_tx_fill_hdr(wl, skb, extra, info);
216 if (ret < 0)
217 return ret;
218 178
219 ret = wl1271_tx_send_packet(wl, skb, info); 179 /*
220 if (ret < 0) 180 * The length of each packet is stored in terms of words. Thus, we must
221 return ret; 181 * pad the skb data to make sure its length is aligned.
182 * The number of padding bytes is computed and set in wl1271_tx_fill_hdr
183 */
184 total_len = WL1271_TX_ALIGN(skb->len);
185 memcpy(wl->aggr_buf + buf_offset, skb->data, skb->len);
186 memset(wl->aggr_buf + buf_offset + skb->len, 0, total_len - skb->len);
222 187
223 return ret; 188 return total_len;
224} 189}
225 190
226u32 wl1271_tx_enabled_rates_get(struct wl1271 *wl, u32 rate_set) 191u32 wl1271_tx_enabled_rates_get(struct wl1271 *wl, u32 rate_set)
@@ -245,7 +210,7 @@ void wl1271_tx_work(struct work_struct *work)
245 struct sk_buff *skb; 210 struct sk_buff *skb;
246 bool woken_up = false; 211 bool woken_up = false;
247 u32 sta_rates = 0; 212 u32 sta_rates = 0;
248 u32 prev_tx_packets_count; 213 u32 buf_offset;
249 int ret; 214 int ret;
250 215
251 /* check if the rates supported by the AP have changed */ 216 /* check if the rates supported by the AP have changed */
@@ -262,14 +227,15 @@ void wl1271_tx_work(struct work_struct *work)
262 if (unlikely(wl->state == WL1271_STATE_OFF)) 227 if (unlikely(wl->state == WL1271_STATE_OFF))
263 goto out; 228 goto out;
264 229
265 prev_tx_packets_count = wl->tx_packets_count;
266
267 /* if rates have changed, re-configure the rate policy */ 230 /* if rates have changed, re-configure the rate policy */
268 if (unlikely(sta_rates)) { 231 if (unlikely(sta_rates)) {
269 wl->rate_set = wl1271_tx_enabled_rates_get(wl, sta_rates); 232 wl->rate_set = wl1271_tx_enabled_rates_get(wl, sta_rates);
270 wl1271_acx_rate_policies(wl); 233 wl1271_acx_rate_policies(wl);
271 } 234 }
272 235
236 /* Prepare the transfer buffer, by aggregating all
237 * available packets */
238 buf_offset = 0;
273 while ((skb = skb_dequeue(&wl->tx_queue))) { 239 while ((skb = skb_dequeue(&wl->tx_queue))) {
274 if (!woken_up) { 240 if (!woken_up) {
275 ret = wl1271_ps_elp_wakeup(wl, false); 241 ret = wl1271_ps_elp_wakeup(wl, false);
@@ -278,21 +244,30 @@ void wl1271_tx_work(struct work_struct *work)
278 woken_up = true; 244 woken_up = true;
279 } 245 }
280 246
281 ret = wl1271_tx_frame(wl, skb); 247 ret = wl1271_prepare_tx_frame(wl, skb, buf_offset);
282 if (ret == -EBUSY) { 248 if (ret == -EBUSY) {
283 /* firmware buffer is full, lets stop transmitting. */ 249 /*
250 * Either the firmware buffer is full, or the
251 * aggregation buffer is.
252 * Queue back last skb, and stop aggregating.
253 */
284 skb_queue_head(&wl->tx_queue, skb); 254 skb_queue_head(&wl->tx_queue, skb);
285 goto out_ack; 255 goto out_ack;
286 } else if (ret < 0) { 256 } else if (ret < 0) {
287 dev_kfree_skb(skb); 257 dev_kfree_skb(skb);
288 goto out_ack; 258 goto out_ack;
289 } 259 }
260 buf_offset += ret;
261 wl->tx_packets_count++;
290 } 262 }
291 263
292out_ack: 264out_ack:
293 /* interrupt the firmware with the new packets */ 265 if (buf_offset) {
294 if (prev_tx_packets_count != wl->tx_packets_count) 266 wl1271_write(wl, WL1271_SLV_MEM_DATA, wl->aggr_buf,
267 buf_offset, true);
268 /* interrupt the firmware with the new packets */
295 wl1271_write32(wl, WL1271_HOST_WR_ACCESS, wl->tx_packets_count); 269 wl1271_write32(wl, WL1271_HOST_WR_ACCESS, wl->tx_packets_count);
270 }
296 271
297out: 272out:
298 if (woken_up) 273 if (woken_up)
@@ -422,8 +397,6 @@ void wl1271_tx_reset(struct wl1271 *wl)
422 struct sk_buff *skb; 397 struct sk_buff *skb;
423 398
424 /* TX failure */ 399 /* TX failure */
425/* control->flags = 0; FIXME */
426
427 while ((skb = skb_dequeue(&wl->tx_queue))) { 400 while ((skb = skb_dequeue(&wl->tx_queue))) {
428 wl1271_debug(DEBUG_TX, "freeing skb 0x%p", skb); 401 wl1271_debug(DEBUG_TX, "freeing skb 0x%p", skb);
429 ieee80211_tx_status(wl->hw, skb); 402 ieee80211_tx_status(wl->hw, skb);
diff --git a/drivers/net/wireless/wl12xx/wl1271_tx.h b/drivers/net/wireless/wl12xx/wl1271_tx.h
index 48bf92621c0..d12a129ad11 100644
--- a/drivers/net/wireless/wl12xx/wl1271_tx.h
+++ b/drivers/net/wireless/wl12xx/wl1271_tx.h
@@ -139,23 +139,6 @@ static inline int wl1271_tx_get_queue(int queue)
139 } 139 }
140} 140}
141 141
142/* wl1271 tx descriptor needs the tid and we need to convert it from ac */
143static inline int wl1271_tx_ac_to_tid(int ac)
144{
145 switch (ac) {
146 case 0:
147 return 0;
148 case 1:
149 return 2;
150 case 2:
151 return 4;
152 case 3:
153 return 6;
154 default:
155 return 0;
156 }
157}
158
159void wl1271_tx_work(struct work_struct *work); 142void wl1271_tx_work(struct work_struct *work);
160void wl1271_tx_complete(struct wl1271 *wl); 143void wl1271_tx_complete(struct wl1271 *wl);
161void wl1271_tx_reset(struct wl1271 *wl); 144void wl1271_tx_reset(struct wl1271 *wl);
diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h
index f0518b0278a..c08709fe36f 100644
--- a/include/linux/nl80211.h
+++ b/include/linux/nl80211.h
@@ -315,8 +315,8 @@
315 * channel for the specified amount of time. This can be used to do 315 * channel for the specified amount of time. This can be used to do
316 * off-channel operations like transmit a Public Action frame and wait for 316 * off-channel operations like transmit a Public Action frame and wait for
317 * a response while being associated to an AP on another channel. 317 * a response while being associated to an AP on another channel.
318 * %NL80211_ATTR_WIPHY or %NL80211_ATTR_IFINDEX is used to specify which 318 * %NL80211_ATTR_IFINDEX is used to specify which interface (and thus
319 * radio is used. %NL80211_ATTR_WIPHY_FREQ is used to specify the 319 * radio) is used. %NL80211_ATTR_WIPHY_FREQ is used to specify the
320 * frequency for the operation and %NL80211_ATTR_WIPHY_CHANNEL_TYPE may be 320 * frequency for the operation and %NL80211_ATTR_WIPHY_CHANNEL_TYPE may be
321 * optionally used to specify additional channel parameters. 321 * optionally used to specify additional channel parameters.
322 * %NL80211_ATTR_DURATION is used to specify the duration in milliseconds 322 * %NL80211_ATTR_DURATION is used to specify the duration in milliseconds
@@ -387,6 +387,8 @@
387 * of any other interfaces, and other interfaces will again take 387 * of any other interfaces, and other interfaces will again take
388 * precedence when they are used. 388 * precedence when they are used.
389 * 389 *
390 * @NL80211_CMD_SET_WDS_PEER: Set the MAC address of the peer on a WDS interface.
391 *
390 * @NL80211_CMD_MAX: highest used command number 392 * @NL80211_CMD_MAX: highest used command number
391 * @__NL80211_CMD_AFTER_LAST: internal use 393 * @__NL80211_CMD_AFTER_LAST: internal use
392 */ 394 */
@@ -489,6 +491,7 @@ enum nl80211_commands {
489 NL80211_CMD_NOTIFY_CQM, 491 NL80211_CMD_NOTIFY_CQM,
490 492
491 NL80211_CMD_SET_CHANNEL, 493 NL80211_CMD_SET_CHANNEL,
494 NL80211_CMD_SET_WDS_PEER,
492 495
493 /* add new commands above here */ 496 /* add new commands above here */
494 497
@@ -798,6 +801,9 @@ enum nl80211_commands {
798 * This is used in association with @NL80211_ATTR_WIPHY_TX_POWER_SETTING 801 * This is used in association with @NL80211_ATTR_WIPHY_TX_POWER_SETTING
799 * for non-automatic settings. 802 * for non-automatic settings.
800 * 803 *
804 * @NL80211_ATTR_SUPPORT_IBSS_RSN: The device supports IBSS RSN, which mostly
805 * means support for per-station GTKs.
806 *
801 * @NL80211_ATTR_MAX: highest attribute number currently defined 807 * @NL80211_ATTR_MAX: highest attribute number currently defined
802 * @__NL80211_ATTR_AFTER_LAST: internal use 808 * @__NL80211_ATTR_AFTER_LAST: internal use
803 */ 809 */
@@ -965,6 +971,8 @@ enum nl80211_attrs {
965 NL80211_ATTR_CONTROL_PORT_ETHERTYPE, 971 NL80211_ATTR_CONTROL_PORT_ETHERTYPE,
966 NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT, 972 NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT,
967 973
974 NL80211_ATTR_SUPPORT_IBSS_RSN,
975
968 /* add attributes here, update the policy in nl80211.c */ 976 /* add attributes here, update the policy in nl80211.c */
969 977
970 __NL80211_ATTR_AFTER_LAST, 978 __NL80211_ATTR_AFTER_LAST,
@@ -1129,6 +1137,8 @@ enum nl80211_rate_info {
1129 * @NL80211_STA_INFO_RX_PACKETS: total received packet (u32, from this station) 1137 * @NL80211_STA_INFO_RX_PACKETS: total received packet (u32, from this station)
1130 * @NL80211_STA_INFO_TX_PACKETS: total transmitted packets (u32, to this 1138 * @NL80211_STA_INFO_TX_PACKETS: total transmitted packets (u32, to this
1131 * station) 1139 * station)
1140 * @NL80211_STA_INFO_TX_RETRIES: total retries (u32, to this station)
1141 * @NL80211_STA_INFO_TX_FAILED: total failed packets (u32, to this station)
1132 */ 1142 */
1133enum nl80211_sta_info { 1143enum nl80211_sta_info {
1134 __NL80211_STA_INFO_INVALID, 1144 __NL80211_STA_INFO_INVALID,
@@ -1142,6 +1152,8 @@ enum nl80211_sta_info {
1142 NL80211_STA_INFO_TX_BITRATE, 1152 NL80211_STA_INFO_TX_BITRATE,
1143 NL80211_STA_INFO_RX_PACKETS, 1153 NL80211_STA_INFO_RX_PACKETS,
1144 NL80211_STA_INFO_TX_PACKETS, 1154 NL80211_STA_INFO_TX_PACKETS,
1155 NL80211_STA_INFO_TX_RETRIES,
1156 NL80211_STA_INFO_TX_FAILED,
1145 1157
1146 /* keep last */ 1158 /* keep last */
1147 __NL80211_STA_INFO_AFTER_LAST, 1159 __NL80211_STA_INFO_AFTER_LAST,
@@ -1400,6 +1412,7 @@ enum nl80211_reg_rule_flags {
1400 * @__NL80211_SURVEY_INFO_INVALID: attribute number 0 is reserved 1412 * @__NL80211_SURVEY_INFO_INVALID: attribute number 0 is reserved
1401 * @NL80211_SURVEY_INFO_FREQUENCY: center frequency of channel 1413 * @NL80211_SURVEY_INFO_FREQUENCY: center frequency of channel
1402 * @NL80211_SURVEY_INFO_NOISE: noise level of channel (u8, dBm) 1414 * @NL80211_SURVEY_INFO_NOISE: noise level of channel (u8, dBm)
1415 * @NL80211_SURVEY_INFO_IN_USE: channel is currently being used
1403 * @NL80211_SURVEY_INFO_MAX: highest survey info attribute number 1416 * @NL80211_SURVEY_INFO_MAX: highest survey info attribute number
1404 * currently defined 1417 * currently defined
1405 * @__NL80211_SURVEY_INFO_AFTER_LAST: internal use 1418 * @__NL80211_SURVEY_INFO_AFTER_LAST: internal use
@@ -1408,6 +1421,7 @@ enum nl80211_survey_info {
1408 __NL80211_SURVEY_INFO_INVALID, 1421 __NL80211_SURVEY_INFO_INVALID,
1409 NL80211_SURVEY_INFO_FREQUENCY, 1422 NL80211_SURVEY_INFO_FREQUENCY,
1410 NL80211_SURVEY_INFO_NOISE, 1423 NL80211_SURVEY_INFO_NOISE,
1424 NL80211_SURVEY_INFO_IN_USE,
1411 1425
1412 /* keep last */ 1426 /* keep last */
1413 __NL80211_SURVEY_INFO_AFTER_LAST, 1427 __NL80211_SURVEY_INFO_AFTER_LAST,
@@ -1654,11 +1668,14 @@ enum nl80211_auth_type {
1654 * @NL80211_KEYTYPE_GROUP: Group (broadcast/multicast) key 1668 * @NL80211_KEYTYPE_GROUP: Group (broadcast/multicast) key
1655 * @NL80211_KEYTYPE_PAIRWISE: Pairwise (unicast/individual) key 1669 * @NL80211_KEYTYPE_PAIRWISE: Pairwise (unicast/individual) key
1656 * @NL80211_KEYTYPE_PEERKEY: PeerKey (DLS) 1670 * @NL80211_KEYTYPE_PEERKEY: PeerKey (DLS)
1671 * @NUM_NL80211_KEYTYPES: number of defined key types
1657 */ 1672 */
1658enum nl80211_key_type { 1673enum nl80211_key_type {
1659 NL80211_KEYTYPE_GROUP, 1674 NL80211_KEYTYPE_GROUP,
1660 NL80211_KEYTYPE_PAIRWISE, 1675 NL80211_KEYTYPE_PAIRWISE,
1661 NL80211_KEYTYPE_PEERKEY, 1676 NL80211_KEYTYPE_PEERKEY,
1677
1678 NUM_NL80211_KEYTYPES
1662}; 1679};
1663 1680
1664/** 1681/**
@@ -1689,6 +1706,9 @@ enum nl80211_wpa_versions {
1689 * CCMP keys, each six bytes in little endian 1706 * CCMP keys, each six bytes in little endian
1690 * @NL80211_KEY_DEFAULT: flag indicating default key 1707 * @NL80211_KEY_DEFAULT: flag indicating default key
1691 * @NL80211_KEY_DEFAULT_MGMT: flag indicating default management key 1708 * @NL80211_KEY_DEFAULT_MGMT: flag indicating default management key
1709 * @NL80211_KEY_TYPE: the key type from enum nl80211_key_type, if not
1710 * specified the default depends on whether a MAC address was
1711 * given with the command using the key or not (u32)
1692 * @__NL80211_KEY_AFTER_LAST: internal 1712 * @__NL80211_KEY_AFTER_LAST: internal
1693 * @NL80211_KEY_MAX: highest key attribute 1713 * @NL80211_KEY_MAX: highest key attribute
1694 */ 1714 */
@@ -1700,6 +1720,7 @@ enum nl80211_key_attributes {
1700 NL80211_KEY_SEQ, 1720 NL80211_KEY_SEQ,
1701 NL80211_KEY_DEFAULT, 1721 NL80211_KEY_DEFAULT,
1702 NL80211_KEY_DEFAULT_MGMT, 1722 NL80211_KEY_DEFAULT_MGMT,
1723 NL80211_KEY_TYPE,
1703 1724
1704 /* keep last */ 1725 /* keep last */
1705 __NL80211_KEY_AFTER_LAST, 1726 __NL80211_KEY_AFTER_LAST,
diff --git a/include/linux/wl12xx.h b/include/linux/wl12xx.h
index 95deae3968f..4f902e1908a 100644
--- a/include/linux/wl12xx.h
+++ b/include/linux/wl12xx.h
@@ -32,7 +32,20 @@ struct wl12xx_platform_data {
32 int board_ref_clock; 32 int board_ref_clock;
33}; 33};
34 34
35#ifdef CONFIG_WL12XX_PLATFORM_DATA
36
35int wl12xx_set_platform_data(const struct wl12xx_platform_data *data); 37int wl12xx_set_platform_data(const struct wl12xx_platform_data *data);
38
39#else
40
41static inline
42int wl12xx_set_platform_data(const struct wl12xx_platform_data *data)
43{
44 return -ENOSYS;
45}
46
47#endif
48
36const struct wl12xx_platform_data *wl12xx_get_platform_data(void); 49const struct wl12xx_platform_data *wl12xx_get_platform_data(void);
37 50
38#endif 51#endif
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index a0613ff62c9..0778d04b3bb 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -293,12 +293,14 @@ struct key_params {
293 * enum survey_info_flags - survey information flags 293 * enum survey_info_flags - survey information flags
294 * 294 *
295 * @SURVEY_INFO_NOISE_DBM: noise (in dBm) was filled in 295 * @SURVEY_INFO_NOISE_DBM: noise (in dBm) was filled in
296 * @SURVEY_INFO_IN_USE: channel is currently being used
296 * 297 *
297 * Used by the driver to indicate which info in &struct survey_info 298 * Used by the driver to indicate which info in &struct survey_info
298 * it has filled in during the get_survey(). 299 * it has filled in during the get_survey().
299 */ 300 */
300enum survey_info_flags { 301enum survey_info_flags {
301 SURVEY_INFO_NOISE_DBM = 1<<0, 302 SURVEY_INFO_NOISE_DBM = 1<<0,
303 SURVEY_INFO_IN_USE = 1<<1,
302}; 304};
303 305
304/** 306/**
@@ -399,6 +401,8 @@ struct station_parameters {
399 * (tx_bitrate, tx_bitrate_flags and tx_bitrate_mcs) 401 * (tx_bitrate, tx_bitrate_flags and tx_bitrate_mcs)
400 * @STATION_INFO_RX_PACKETS: @rx_packets filled 402 * @STATION_INFO_RX_PACKETS: @rx_packets filled
401 * @STATION_INFO_TX_PACKETS: @tx_packets filled 403 * @STATION_INFO_TX_PACKETS: @tx_packets filled
404 * @STATION_INFO_TX_RETRIES: @tx_retries filled
405 * @STATION_INFO_TX_FAILED: @tx_failed filled
402 */ 406 */
403enum station_info_flags { 407enum station_info_flags {
404 STATION_INFO_INACTIVE_TIME = 1<<0, 408 STATION_INFO_INACTIVE_TIME = 1<<0,
@@ -411,6 +415,8 @@ enum station_info_flags {
411 STATION_INFO_TX_BITRATE = 1<<7, 415 STATION_INFO_TX_BITRATE = 1<<7,
412 STATION_INFO_RX_PACKETS = 1<<8, 416 STATION_INFO_RX_PACKETS = 1<<8,
413 STATION_INFO_TX_PACKETS = 1<<9, 417 STATION_INFO_TX_PACKETS = 1<<9,
418 STATION_INFO_TX_RETRIES = 1<<10,
419 STATION_INFO_TX_FAILED = 1<<11,
414}; 420};
415 421
416/** 422/**
@@ -460,6 +466,8 @@ struct rate_info {
460 * @txrate: current unicast bitrate to this station 466 * @txrate: current unicast bitrate to this station
461 * @rx_packets: packets received from this station 467 * @rx_packets: packets received from this station
462 * @tx_packets: packets transmitted to this station 468 * @tx_packets: packets transmitted to this station
469 * @tx_retries: cumulative retry counts
470 * @tx_failed: number of failed transmissions (retries exceeded, no ACK)
463 * @generation: generation number for nl80211 dumps. 471 * @generation: generation number for nl80211 dumps.
464 * This number should increase every time the list of stations 472 * This number should increase every time the list of stations
465 * changes, i.e. when a station is added or removed, so that 473 * changes, i.e. when a station is added or removed, so that
@@ -477,6 +485,8 @@ struct station_info {
477 struct rate_info txrate; 485 struct rate_info txrate;
478 u32 rx_packets; 486 u32 rx_packets;
479 u32 tx_packets; 487 u32 tx_packets;
488 u32 tx_retries;
489 u32 tx_failed;
480 490
481 int generation; 491 int generation;
482}; 492};
@@ -1128,13 +1138,14 @@ struct cfg80211_ops {
1128 struct vif_params *params); 1138 struct vif_params *params);
1129 1139
1130 int (*add_key)(struct wiphy *wiphy, struct net_device *netdev, 1140 int (*add_key)(struct wiphy *wiphy, struct net_device *netdev,
1131 u8 key_index, const u8 *mac_addr, 1141 u8 key_index, bool pairwise, const u8 *mac_addr,
1132 struct key_params *params); 1142 struct key_params *params);
1133 int (*get_key)(struct wiphy *wiphy, struct net_device *netdev, 1143 int (*get_key)(struct wiphy *wiphy, struct net_device *netdev,
1134 u8 key_index, const u8 *mac_addr, void *cookie, 1144 u8 key_index, bool pairwise, const u8 *mac_addr,
1145 void *cookie,
1135 void (*callback)(void *cookie, struct key_params*)); 1146 void (*callback)(void *cookie, struct key_params*));
1136 int (*del_key)(struct wiphy *wiphy, struct net_device *netdev, 1147 int (*del_key)(struct wiphy *wiphy, struct net_device *netdev,
1137 u8 key_index, const u8 *mac_addr); 1148 u8 key_index, bool pairwise, const u8 *mac_addr);
1138 int (*set_default_key)(struct wiphy *wiphy, 1149 int (*set_default_key)(struct wiphy *wiphy,
1139 struct net_device *netdev, 1150 struct net_device *netdev,
1140 u8 key_index); 1151 u8 key_index);
@@ -1218,7 +1229,7 @@ struct cfg80211_ops {
1218 int (*get_tx_power)(struct wiphy *wiphy, int *dbm); 1229 int (*get_tx_power)(struct wiphy *wiphy, int *dbm);
1219 1230
1220 int (*set_wds_peer)(struct wiphy *wiphy, struct net_device *dev, 1231 int (*set_wds_peer)(struct wiphy *wiphy, struct net_device *dev,
1221 u8 *addr); 1232 const u8 *addr);
1222 1233
1223 void (*rfkill_poll)(struct wiphy *wiphy); 1234 void (*rfkill_poll)(struct wiphy *wiphy);
1224 1235
@@ -1302,6 +1313,7 @@ struct cfg80211_ops {
1302 * @WIPHY_FLAG_CONTROL_PORT_PROTOCOL: This device supports setting the 1313 * @WIPHY_FLAG_CONTROL_PORT_PROTOCOL: This device supports setting the
1303 * control port protocol ethertype. The device also honours the 1314 * control port protocol ethertype. The device also honours the
1304 * control_port_no_encrypt flag. 1315 * control_port_no_encrypt flag.
1316 * @WIPHY_FLAG_IBSS_RSN: The device supports IBSS RSN.
1305 */ 1317 */
1306enum wiphy_flags { 1318enum wiphy_flags {
1307 WIPHY_FLAG_CUSTOM_REGULATORY = BIT(0), 1319 WIPHY_FLAG_CUSTOM_REGULATORY = BIT(0),
@@ -1312,6 +1324,7 @@ enum wiphy_flags {
1312 WIPHY_FLAG_4ADDR_AP = BIT(5), 1324 WIPHY_FLAG_4ADDR_AP = BIT(5),
1313 WIPHY_FLAG_4ADDR_STATION = BIT(6), 1325 WIPHY_FLAG_4ADDR_STATION = BIT(6),
1314 WIPHY_FLAG_CONTROL_PORT_PROTOCOL = BIT(7), 1326 WIPHY_FLAG_CONTROL_PORT_PROTOCOL = BIT(7),
1327 WIPHY_FLAG_IBSS_RSN = BIT(7),
1315}; 1328};
1316 1329
1317struct mac_address { 1330struct mac_address {
@@ -2551,8 +2564,6 @@ void cfg80211_cqm_rssi_notify(struct net_device *dev,
2551 enum nl80211_cqm_rssi_threshold_event rssi_event, 2564 enum nl80211_cqm_rssi_threshold_event rssi_event,
2552 gfp_t gfp); 2565 gfp_t gfp);
2553 2566
2554#ifdef __KERNEL__
2555
2556/* Logging, debugging and troubleshooting/diagnostic helpers. */ 2567/* Logging, debugging and troubleshooting/diagnostic helpers. */
2557 2568
2558/* wiphy_printk helpers, similar to dev_printk */ 2569/* wiphy_printk helpers, similar to dev_printk */
@@ -2599,6 +2610,4 @@ void cfg80211_cqm_rssi_notify(struct net_device *dev,
2599#define wiphy_WARN(wiphy, format, args...) \ 2610#define wiphy_WARN(wiphy, format, args...) \
2600 WARN(1, "wiphy: %s\n" format, wiphy_name(wiphy), ##args); 2611 WARN(1, "wiphy: %s\n" format, wiphy_name(wiphy), ##args);
2601 2612
2602#endif
2603
2604#endif /* __NET_CFG80211_H */ 2613#endif /* __NET_CFG80211_H */
diff --git a/include/net/genetlink.h b/include/net/genetlink.h
index f7dcd2c7041..8a64b811a39 100644
--- a/include/net/genetlink.h
+++ b/include/net/genetlink.h
@@ -20,6 +20,9 @@ struct genl_multicast_group {
20 u32 id; 20 u32 id;
21}; 21};
22 22
23struct genl_ops;
24struct genl_info;
25
23/** 26/**
24 * struct genl_family - generic netlink family 27 * struct genl_family - generic netlink family
25 * @id: protocol family idenfitier 28 * @id: protocol family idenfitier
@@ -29,6 +32,10 @@ struct genl_multicast_group {
29 * @maxattr: maximum number of attributes supported 32 * @maxattr: maximum number of attributes supported
30 * @netnsok: set to true if the family can handle network 33 * @netnsok: set to true if the family can handle network
31 * namespaces and should be presented in all of them 34 * namespaces and should be presented in all of them
35 * @pre_doit: called before an operation's doit callback, it may
36 * do additional, common, filtering and return an error
37 * @post_doit: called after an operation's doit callback, it may
38 * undo operations done by pre_doit, for example release locks
32 * @attrbuf: buffer to store parsed attributes 39 * @attrbuf: buffer to store parsed attributes
33 * @ops_list: list of all assigned operations 40 * @ops_list: list of all assigned operations
34 * @family_list: family list 41 * @family_list: family list
@@ -41,6 +48,12 @@ struct genl_family {
41 unsigned int version; 48 unsigned int version;
42 unsigned int maxattr; 49 unsigned int maxattr;
43 bool netnsok; 50 bool netnsok;
51 int (*pre_doit)(struct genl_ops *ops,
52 struct sk_buff *skb,
53 struct genl_info *info);
54 void (*post_doit)(struct genl_ops *ops,
55 struct sk_buff *skb,
56 struct genl_info *info);
44 struct nlattr ** attrbuf; /* private */ 57 struct nlattr ** attrbuf; /* private */
45 struct list_head ops_list; /* private */ 58 struct list_head ops_list; /* private */
46 struct list_head family_list; /* private */ 59 struct list_head family_list; /* private */
@@ -55,6 +68,8 @@ struct genl_family {
55 * @genlhdr: generic netlink message header 68 * @genlhdr: generic netlink message header
56 * @userhdr: user specific header 69 * @userhdr: user specific header
57 * @attrs: netlink attributes 70 * @attrs: netlink attributes
71 * @_net: network namespace
72 * @user_ptr: user pointers
58 */ 73 */
59struct genl_info { 74struct genl_info {
60 u32 snd_seq; 75 u32 snd_seq;
@@ -66,6 +81,7 @@ struct genl_info {
66#ifdef CONFIG_NET_NS 81#ifdef CONFIG_NET_NS
67 struct net * _net; 82 struct net * _net;
68#endif 83#endif
84 void * user_ptr[2];
69}; 85};
70 86
71static inline struct net *genl_info_net(struct genl_info *info) 87static inline struct net *genl_info_net(struct genl_info *info)
@@ -81,6 +97,7 @@ static inline void genl_info_net_set(struct genl_info *info, struct net *net)
81/** 97/**
82 * struct genl_ops - generic netlink operations 98 * struct genl_ops - generic netlink operations
83 * @cmd: command identifier 99 * @cmd: command identifier
100 * @internal_flags: flags used by the family
84 * @flags: flags 101 * @flags: flags
85 * @policy: attribute validation policy 102 * @policy: attribute validation policy
86 * @doit: standard command callback 103 * @doit: standard command callback
@@ -90,6 +107,7 @@ static inline void genl_info_net_set(struct genl_info *info, struct net *net)
90 */ 107 */
91struct genl_ops { 108struct genl_ops {
92 u8 cmd; 109 u8 cmd;
110 u8 internal_flags;
93 unsigned int flags; 111 unsigned int flags;
94 const struct nla_policy *policy; 112 const struct nla_policy *policy;
95 int (*doit)(struct sk_buff *skb, 113 int (*doit)(struct sk_buff *skb,
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index fe8b9dae4de..33aa2e39147 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -1041,6 +1041,13 @@ enum ieee80211_tkip_key_type {
1041 * @IEEE80211_HW_NEED_DTIM_PERIOD: 1041 * @IEEE80211_HW_NEED_DTIM_PERIOD:
1042 * This device needs to know the DTIM period for the BSS before 1042 * This device needs to know the DTIM period for the BSS before
1043 * associating. 1043 * associating.
1044 *
1045 * @IEEE80211_HW_SUPPORTS_PER_STA_GTK: The device's crypto engine supports
1046 * per-station GTKs as used by IBSS RSN or during fast transition. If
1047 * the device doesn't support per-station GTKs, but can be asked not
1048 * to decrypt group addressed frames, then IBSS RSN support is still
1049 * possible but software crypto will be used. Advertise the wiphy flag
1050 * only in that case.
1044 */ 1051 */
1045enum ieee80211_hw_flags { 1052enum ieee80211_hw_flags {
1046 IEEE80211_HW_HAS_RATE_CONTROL = 1<<0, 1053 IEEE80211_HW_HAS_RATE_CONTROL = 1<<0,
@@ -1064,6 +1071,7 @@ enum ieee80211_hw_flags {
1064 IEEE80211_HW_REPORTS_TX_ACK_STATUS = 1<<18, 1071 IEEE80211_HW_REPORTS_TX_ACK_STATUS = 1<<18,
1065 IEEE80211_HW_CONNECTION_MONITOR = 1<<19, 1072 IEEE80211_HW_CONNECTION_MONITOR = 1<<19,
1066 IEEE80211_HW_SUPPORTS_CQM_RSSI = 1<<20, 1073 IEEE80211_HW_SUPPORTS_CQM_RSSI = 1<<20,
1074 IEEE80211_HW_SUPPORTS_PER_STA_GTK = 1<<21,
1067}; 1075};
1068 1076
1069/** 1077/**
@@ -1109,7 +1117,10 @@ enum ieee80211_hw_flags {
1109 * @sta_data_size: size (in bytes) of the drv_priv data area 1117 * @sta_data_size: size (in bytes) of the drv_priv data area
1110 * within &struct ieee80211_sta. 1118 * within &struct ieee80211_sta.
1111 * 1119 *
1112 * @max_rates: maximum number of alternate rate retry stages 1120 * @max_rates: maximum number of alternate rate retry stages the hw
1121 * can handle.
1122 * @max_report_rates: maximum number of alternate rate retry stages
1123 * the hw can report back.
1113 * @max_rate_tries: maximum number of tries for each stage 1124 * @max_rate_tries: maximum number of tries for each stage
1114 * 1125 *
1115 * @napi_weight: weight used for NAPI polling. You must specify an 1126 * @napi_weight: weight used for NAPI polling. You must specify an
@@ -1131,6 +1142,7 @@ struct ieee80211_hw {
1131 u16 max_listen_interval; 1142 u16 max_listen_interval;
1132 s8 max_signal; 1143 s8 max_signal;
1133 u8 max_rates; 1144 u8 max_rates;
1145 u8 max_report_rates;
1134 u8 max_rate_tries; 1146 u8 max_rate_tries;
1135}; 1147};
1136 1148
@@ -2578,6 +2590,22 @@ void ieee80211_chswitch_done(struct ieee80211_vif *vif, bool success);
2578void ieee80211_request_smps(struct ieee80211_vif *vif, 2590void ieee80211_request_smps(struct ieee80211_vif *vif,
2579 enum ieee80211_smps_mode smps_mode); 2591 enum ieee80211_smps_mode smps_mode);
2580 2592
2593/**
2594 * ieee80211_key_removed - disable hw acceleration for key
2595 * @key_conf: The key hw acceleration should be disabled for
2596 *
2597 * This allows drivers to indicate that the given key has been
2598 * removed from hardware acceleration, due to a new key that
2599 * was added. Don't use this if the key can continue to be used
2600 * for TX, if the key restriction is on RX only it is permitted
2601 * to keep the key for TX only and not call this function.
2602 *
2603 * Due to locking constraints, it may only be called during
2604 * @set_key. This function must be allowed to sleep, and the
2605 * key it tries to disable may still be used until it returns.
2606 */
2607void ieee80211_key_removed(struct ieee80211_key_conf *key_conf);
2608
2581/* Rate control API */ 2609/* Rate control API */
2582 2610
2583/** 2611/**
diff --git a/net/mac80211/agg-rx.c b/net/mac80211/agg-rx.c
index 58eab9e8e4e..720b7a84af5 100644
--- a/net/mac80211/agg-rx.c
+++ b/net/mac80211/agg-rx.c
@@ -56,7 +56,7 @@ static void ieee80211_free_tid_rx(struct rcu_head *h)
56} 56}
57 57
58void ___ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid, 58void ___ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid,
59 u16 initiator, u16 reason) 59 u16 initiator, u16 reason, bool tx)
60{ 60{
61 struct ieee80211_local *local = sta->local; 61 struct ieee80211_local *local = sta->local;
62 struct tid_ampdu_rx *tid_rx; 62 struct tid_ampdu_rx *tid_rx;
@@ -81,7 +81,7 @@ void ___ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid,
81 "aggregation for tid %d\n", tid); 81 "aggregation for tid %d\n", tid);
82 82
83 /* check if this is a self generated aggregation halt */ 83 /* check if this is a self generated aggregation halt */
84 if (initiator == WLAN_BACK_RECIPIENT) 84 if (initiator == WLAN_BACK_RECIPIENT && tx)
85 ieee80211_send_delba(sta->sdata, sta->sta.addr, 85 ieee80211_send_delba(sta->sdata, sta->sta.addr,
86 tid, 0, reason); 86 tid, 0, reason);
87 87
@@ -92,10 +92,10 @@ void ___ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid,
92} 92}
93 93
94void __ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid, 94void __ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid,
95 u16 initiator, u16 reason) 95 u16 initiator, u16 reason, bool tx)
96{ 96{
97 mutex_lock(&sta->ampdu_mlme.mtx); 97 mutex_lock(&sta->ampdu_mlme.mtx);
98 ___ieee80211_stop_rx_ba_session(sta, tid, initiator, reason); 98 ___ieee80211_stop_rx_ba_session(sta, tid, initiator, reason, tx);
99 mutex_unlock(&sta->ampdu_mlme.mtx); 99 mutex_unlock(&sta->ampdu_mlme.mtx);
100} 100}
101 101
diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c
index c893f236ace..d4679b265ba 100644
--- a/net/mac80211/agg-tx.c
+++ b/net/mac80211/agg-tx.c
@@ -145,7 +145,8 @@ static void kfree_tid_tx(struct rcu_head *rcu_head)
145} 145}
146 146
147int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid, 147int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid,
148 enum ieee80211_back_parties initiator) 148 enum ieee80211_back_parties initiator,
149 bool tx)
149{ 150{
150 struct ieee80211_local *local = sta->local; 151 struct ieee80211_local *local = sta->local;
151 struct tid_ampdu_tx *tid_tx = sta->ampdu_mlme.tid_tx[tid]; 152 struct tid_ampdu_tx *tid_tx = sta->ampdu_mlme.tid_tx[tid];
@@ -175,6 +176,8 @@ int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid,
175 176
176 set_bit(HT_AGG_STATE_STOPPING, &tid_tx->state); 177 set_bit(HT_AGG_STATE_STOPPING, &tid_tx->state);
177 178
179 del_timer_sync(&tid_tx->addba_resp_timer);
180
178 /* 181 /*
179 * After this packets are no longer handed right through 182 * After this packets are no longer handed right through
180 * to the driver but are put onto tid_tx->pending instead, 183 * to the driver but are put onto tid_tx->pending instead,
@@ -183,6 +186,7 @@ int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid,
183 clear_bit(HT_AGG_STATE_OPERATIONAL, &tid_tx->state); 186 clear_bit(HT_AGG_STATE_OPERATIONAL, &tid_tx->state);
184 187
185 tid_tx->stop_initiator = initiator; 188 tid_tx->stop_initiator = initiator;
189 tid_tx->tx_stop = tx;
186 190
187 ret = drv_ampdu_action(local, sta->sdata, 191 ret = drv_ampdu_action(local, sta->sdata,
188 IEEE80211_AMPDU_TX_STOP, 192 IEEE80211_AMPDU_TX_STOP,
@@ -575,13 +579,14 @@ void ieee80211_start_tx_ba_cb_irqsafe(struct ieee80211_vif *vif,
575EXPORT_SYMBOL(ieee80211_start_tx_ba_cb_irqsafe); 579EXPORT_SYMBOL(ieee80211_start_tx_ba_cb_irqsafe);
576 580
577int __ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid, 581int __ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid,
578 enum ieee80211_back_parties initiator) 582 enum ieee80211_back_parties initiator,
583 bool tx)
579{ 584{
580 int ret; 585 int ret;
581 586
582 mutex_lock(&sta->ampdu_mlme.mtx); 587 mutex_lock(&sta->ampdu_mlme.mtx);
583 588
584 ret = ___ieee80211_stop_tx_ba_session(sta, tid, initiator); 589 ret = ___ieee80211_stop_tx_ba_session(sta, tid, initiator, tx);
585 590
586 mutex_unlock(&sta->ampdu_mlme.mtx); 591 mutex_unlock(&sta->ampdu_mlme.mtx);
587 592
@@ -670,7 +675,7 @@ void ieee80211_stop_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u8 tid)
670 goto unlock_sta; 675 goto unlock_sta;
671 } 676 }
672 677
673 if (tid_tx->stop_initiator == WLAN_BACK_INITIATOR) 678 if (tid_tx->stop_initiator == WLAN_BACK_INITIATOR && tid_tx->tx_stop)
674 ieee80211_send_delba(sta->sdata, ra, tid, 679 ieee80211_send_delba(sta->sdata, ra, tid,
675 WLAN_BACK_INITIATOR, WLAN_REASON_QSTA_NOT_USE); 680 WLAN_BACK_INITIATOR, WLAN_REASON_QSTA_NOT_USE);
676 681
@@ -770,7 +775,8 @@ void ieee80211_process_addba_resp(struct ieee80211_local *local,
770 775
771 sta->ampdu_mlme.addba_req_num[tid] = 0; 776 sta->ampdu_mlme.addba_req_num[tid] = 0;
772 } else { 777 } else {
773 ___ieee80211_stop_tx_ba_session(sta, tid, WLAN_BACK_INITIATOR); 778 ___ieee80211_stop_tx_ba_session(sta, tid, WLAN_BACK_INITIATOR,
779 true);
774 } 780 }
775 781
776 out: 782 out:
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index c981604b71e..ecf9b7166ed 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -68,14 +68,42 @@ static int ieee80211_change_iface(struct wiphy *wiphy,
68 params && params->use_4addr >= 0) 68 params && params->use_4addr >= 0)
69 sdata->u.mgd.use_4addr = params->use_4addr; 69 sdata->u.mgd.use_4addr = params->use_4addr;
70 70
71 if (sdata->vif.type == NL80211_IFTYPE_MONITOR && flags) 71 if (sdata->vif.type == NL80211_IFTYPE_MONITOR && flags) {
72 sdata->u.mntr_flags = *flags; 72 struct ieee80211_local *local = sdata->local;
73
74 if (ieee80211_sdata_running(sdata)) {
75 /*
76 * Prohibit MONITOR_FLAG_COOK_FRAMES to be
77 * changed while the interface is up.
78 * Else we would need to add a lot of cruft
79 * to update everything:
80 * cooked_mntrs, monitor and all fif_* counters
81 * reconfigure hardware
82 */
83 if ((*flags & MONITOR_FLAG_COOK_FRAMES) !=
84 (sdata->u.mntr_flags & MONITOR_FLAG_COOK_FRAMES))
85 return -EBUSY;
86
87 ieee80211_adjust_monitor_flags(sdata, -1);
88 sdata->u.mntr_flags = *flags;
89 ieee80211_adjust_monitor_flags(sdata, 1);
90
91 ieee80211_configure_filter(local);
92 } else {
93 /*
94 * Because the interface is down, ieee80211_do_stop
95 * and ieee80211_do_open take care of "everything"
96 * mentioned in the comment above.
97 */
98 sdata->u.mntr_flags = *flags;
99 }
100 }
73 101
74 return 0; 102 return 0;
75} 103}
76 104
77static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev, 105static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev,
78 u8 key_idx, const u8 *mac_addr, 106 u8 key_idx, bool pairwise, const u8 *mac_addr,
79 struct key_params *params) 107 struct key_params *params)
80{ 108{
81 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 109 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
@@ -103,6 +131,9 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev,
103 if (IS_ERR(key)) 131 if (IS_ERR(key))
104 return PTR_ERR(key); 132 return PTR_ERR(key);
105 133
134 if (pairwise)
135 key->conf.flags |= IEEE80211_KEY_FLAG_PAIRWISE;
136
106 mutex_lock(&sdata->local->sta_mtx); 137 mutex_lock(&sdata->local->sta_mtx);
107 138
108 if (mac_addr) { 139 if (mac_addr) {
@@ -125,7 +156,7 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev,
125} 156}
126 157
127static int ieee80211_del_key(struct wiphy *wiphy, struct net_device *dev, 158static int ieee80211_del_key(struct wiphy *wiphy, struct net_device *dev,
128 u8 key_idx, const u8 *mac_addr) 159 u8 key_idx, bool pairwise, const u8 *mac_addr)
129{ 160{
130 struct ieee80211_sub_if_data *sdata; 161 struct ieee80211_sub_if_data *sdata;
131 struct sta_info *sta; 162 struct sta_info *sta;
@@ -142,10 +173,17 @@ static int ieee80211_del_key(struct wiphy *wiphy, struct net_device *dev,
142 if (!sta) 173 if (!sta)
143 goto out_unlock; 174 goto out_unlock;
144 175
145 if (sta->key) { 176 if (pairwise) {
146 ieee80211_key_free(sdata->local, sta->key); 177 if (sta->ptk) {
147 WARN_ON(sta->key); 178 ieee80211_key_free(sdata->local, sta->ptk);
148 ret = 0; 179 ret = 0;
180 }
181 } else {
182 if (sta->gtk[key_idx]) {
183 ieee80211_key_free(sdata->local,
184 sta->gtk[key_idx]);
185 ret = 0;
186 }
149 } 187 }
150 188
151 goto out_unlock; 189 goto out_unlock;
@@ -167,7 +205,8 @@ static int ieee80211_del_key(struct wiphy *wiphy, struct net_device *dev,
167} 205}
168 206
169static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev, 207static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev,
170 u8 key_idx, const u8 *mac_addr, void *cookie, 208 u8 key_idx, bool pairwise, const u8 *mac_addr,
209 void *cookie,
171 void (*callback)(void *cookie, 210 void (*callback)(void *cookie,
172 struct key_params *params)) 211 struct key_params *params))
173{ 212{
@@ -175,7 +214,7 @@ static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev,
175 struct sta_info *sta = NULL; 214 struct sta_info *sta = NULL;
176 u8 seq[6] = {0}; 215 u8 seq[6] = {0};
177 struct key_params params; 216 struct key_params params;
178 struct ieee80211_key *key; 217 struct ieee80211_key *key = NULL;
179 u32 iv32; 218 u32 iv32;
180 u16 iv16; 219 u16 iv16;
181 int err = -ENOENT; 220 int err = -ENOENT;
@@ -189,7 +228,10 @@ static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev,
189 if (!sta) 228 if (!sta)
190 goto out; 229 goto out;
191 230
192 key = sta->key; 231 if (pairwise)
232 key = sta->ptk;
233 else if (key_idx < NUM_DEFAULT_KEYS)
234 key = sta->gtk[key_idx];
193 } else 235 } else
194 key = sdata->keys[key_idx]; 236 key = sdata->keys[key_idx];
195 237
@@ -285,6 +327,8 @@ static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo)
285 STATION_INFO_TX_BYTES | 327 STATION_INFO_TX_BYTES |
286 STATION_INFO_RX_PACKETS | 328 STATION_INFO_RX_PACKETS |
287 STATION_INFO_TX_PACKETS | 329 STATION_INFO_TX_PACKETS |
330 STATION_INFO_TX_RETRIES |
331 STATION_INFO_TX_FAILED |
288 STATION_INFO_TX_BITRATE; 332 STATION_INFO_TX_BITRATE;
289 333
290 sinfo->inactive_time = jiffies_to_msecs(jiffies - sta->last_rx); 334 sinfo->inactive_time = jiffies_to_msecs(jiffies - sta->last_rx);
@@ -292,6 +336,8 @@ static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo)
292 sinfo->tx_bytes = sta->tx_bytes; 336 sinfo->tx_bytes = sta->tx_bytes;
293 sinfo->rx_packets = sta->rx_packets; 337 sinfo->rx_packets = sta->rx_packets;
294 sinfo->tx_packets = sta->tx_packets; 338 sinfo->tx_packets = sta->tx_packets;
339 sinfo->tx_retries = sta->tx_retry_count;
340 sinfo->tx_failed = sta->tx_retry_failed;
295 341
296 if ((sta->local->hw.flags & IEEE80211_HW_SIGNAL_DBM) || 342 if ((sta->local->hw.flags & IEEE80211_HW_SIGNAL_DBM) ||
297 (sta->local->hw.flags & IEEE80211_HW_SIGNAL_UNSPEC)) { 343 (sta->local->hw.flags & IEEE80211_HW_SIGNAL_UNSPEC)) {
@@ -1317,7 +1363,7 @@ static int ieee80211_get_tx_power(struct wiphy *wiphy, int *dbm)
1317} 1363}
1318 1364
1319static int ieee80211_set_wds_peer(struct wiphy *wiphy, struct net_device *dev, 1365static int ieee80211_set_wds_peer(struct wiphy *wiphy, struct net_device *dev,
1320 u8 *addr) 1366 const u8 *addr)
1321{ 1367{
1322 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 1368 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1323 1369
@@ -1366,7 +1412,7 @@ int __ieee80211_request_smps(struct ieee80211_sub_if_data *sdata,
1366 if (!sdata->u.mgd.associated || 1412 if (!sdata->u.mgd.associated ||
1367 sdata->vif.bss_conf.channel_type == NL80211_CHAN_NO_HT) { 1413 sdata->vif.bss_conf.channel_type == NL80211_CHAN_NO_HT) {
1368 mutex_lock(&sdata->local->iflist_mtx); 1414 mutex_lock(&sdata->local->iflist_mtx);
1369 ieee80211_recalc_smps(sdata->local, sdata); 1415 ieee80211_recalc_smps(sdata->local);
1370 mutex_unlock(&sdata->local->iflist_mtx); 1416 mutex_unlock(&sdata->local->iflist_mtx);
1371 return 0; 1417 return 0;
1372 } 1418 }
@@ -1521,7 +1567,11 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct net_device *dev,
1521 1567
1522 switch (sdata->vif.type) { 1568 switch (sdata->vif.type) {
1523 case NL80211_IFTYPE_ADHOC: 1569 case NL80211_IFTYPE_ADHOC:
1524 if (mgmt->u.action.category == WLAN_CATEGORY_PUBLIC) 1570 case NL80211_IFTYPE_AP:
1571 case NL80211_IFTYPE_AP_VLAN:
1572 case NL80211_IFTYPE_P2P_GO:
1573 if (!ieee80211_is_action(mgmt->frame_control) ||
1574 mgmt->u.action.category == WLAN_CATEGORY_PUBLIC)
1525 break; 1575 break;
1526 rcu_read_lock(); 1576 rcu_read_lock();
1527 sta = sta_info_get(sdata, mgmt->da); 1577 sta = sta_info_get(sdata, mgmt->da);
@@ -1530,6 +1580,7 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct net_device *dev,
1530 return -ENOLINK; 1580 return -ENOLINK;
1531 break; 1581 break;
1532 case NL80211_IFTYPE_STATION: 1582 case NL80211_IFTYPE_STATION:
1583 case NL80211_IFTYPE_P2P_CLIENT:
1533 break; 1584 break;
1534 default: 1585 default:
1535 return -EOPNOTSUPP; 1586 return -EOPNOTSUPP;
diff --git a/net/mac80211/debugfs_sta.c b/net/mac80211/debugfs_sta.c
index 6b7ff9fb460..50c40ea3cb4 100644
--- a/net/mac80211/debugfs_sta.c
+++ b/net/mac80211/debugfs_sta.c
@@ -196,7 +196,8 @@ static ssize_t sta_agg_status_write(struct file *file, const char __user *userbu
196 else 196 else
197 ret = ieee80211_stop_tx_ba_session(&sta->sta, tid); 197 ret = ieee80211_stop_tx_ba_session(&sta->sta, tid);
198 } else { 198 } else {
199 __ieee80211_stop_rx_ba_session(sta, tid, WLAN_BACK_RECIPIENT, 3); 199 __ieee80211_stop_rx_ba_session(sta, tid, WLAN_BACK_RECIPIENT,
200 3, true);
200 ret = 0; 201 ret = 0;
201 } 202 }
202 203
diff --git a/net/mac80211/ht.c b/net/mac80211/ht.c
index 11f74f5f7b2..4214bb6e12f 100644
--- a/net/mac80211/ht.c
+++ b/net/mac80211/ht.c
@@ -101,16 +101,16 @@ void ieee80211_ht_cap_ie_to_sta_ht_cap(struct ieee80211_supported_band *sband,
101 ht_cap->mcs.rx_mask[32/8] |= 1; 101 ht_cap->mcs.rx_mask[32/8] |= 1;
102} 102}
103 103
104void ieee80211_sta_tear_down_BA_sessions(struct sta_info *sta) 104void ieee80211_sta_tear_down_BA_sessions(struct sta_info *sta, bool tx)
105{ 105{
106 int i; 106 int i;
107 107
108 cancel_work_sync(&sta->ampdu_mlme.work); 108 cancel_work_sync(&sta->ampdu_mlme.work);
109 109
110 for (i = 0; i < STA_TID_NUM; i++) { 110 for (i = 0; i < STA_TID_NUM; i++) {
111 __ieee80211_stop_tx_ba_session(sta, i, WLAN_BACK_INITIATOR); 111 __ieee80211_stop_tx_ba_session(sta, i, WLAN_BACK_INITIATOR, tx);
112 __ieee80211_stop_rx_ba_session(sta, i, WLAN_BACK_RECIPIENT, 112 __ieee80211_stop_rx_ba_session(sta, i, WLAN_BACK_RECIPIENT,
113 WLAN_REASON_QSTA_LEAVE_QBSS); 113 WLAN_REASON_QSTA_LEAVE_QBSS, tx);
114 } 114 }
115} 115}
116 116
@@ -135,7 +135,7 @@ void ieee80211_ba_session_work(struct work_struct *work)
135 if (test_and_clear_bit(tid, sta->ampdu_mlme.tid_rx_timer_expired)) 135 if (test_and_clear_bit(tid, sta->ampdu_mlme.tid_rx_timer_expired))
136 ___ieee80211_stop_rx_ba_session( 136 ___ieee80211_stop_rx_ba_session(
137 sta, tid, WLAN_BACK_RECIPIENT, 137 sta, tid, WLAN_BACK_RECIPIENT,
138 WLAN_REASON_QSTA_TIMEOUT); 138 WLAN_REASON_QSTA_TIMEOUT, true);
139 139
140 tid_tx = sta->ampdu_mlme.tid_tx[tid]; 140 tid_tx = sta->ampdu_mlme.tid_tx[tid];
141 if (!tid_tx) 141 if (!tid_tx)
@@ -146,7 +146,8 @@ void ieee80211_ba_session_work(struct work_struct *work)
146 else if (test_and_clear_bit(HT_AGG_STATE_WANT_STOP, 146 else if (test_and_clear_bit(HT_AGG_STATE_WANT_STOP,
147 &tid_tx->state)) 147 &tid_tx->state))
148 ___ieee80211_stop_tx_ba_session(sta, tid, 148 ___ieee80211_stop_tx_ba_session(sta, tid,
149 WLAN_BACK_INITIATOR); 149 WLAN_BACK_INITIATOR,
150 true);
150 } 151 }
151 mutex_unlock(&sta->ampdu_mlme.mtx); 152 mutex_unlock(&sta->ampdu_mlme.mtx);
152} 153}
@@ -214,9 +215,11 @@ void ieee80211_process_delba(struct ieee80211_sub_if_data *sdata,
214#endif /* CONFIG_MAC80211_HT_DEBUG */ 215#endif /* CONFIG_MAC80211_HT_DEBUG */
215 216
216 if (initiator == WLAN_BACK_INITIATOR) 217 if (initiator == WLAN_BACK_INITIATOR)
217 __ieee80211_stop_rx_ba_session(sta, tid, WLAN_BACK_INITIATOR, 0); 218 __ieee80211_stop_rx_ba_session(sta, tid, WLAN_BACK_INITIATOR, 0,
219 true);
218 else 220 else
219 __ieee80211_stop_tx_ba_session(sta, tid, WLAN_BACK_RECIPIENT); 221 __ieee80211_stop_tx_ba_session(sta, tid, WLAN_BACK_RECIPIENT,
222 true);
220} 223}
221 224
222int ieee80211_send_smps_action(struct ieee80211_sub_if_data *sdata, 225int ieee80211_send_smps_action(struct ieee80211_sub_if_data *sdata,
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
index 1a3aae54f0c..ff60c022f51 100644
--- a/net/mac80211/ibss.c
+++ b/net/mac80211/ibss.c
@@ -173,6 +173,19 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
173 memcpy(skb_put(skb, ifibss->ie_len), 173 memcpy(skb_put(skb, ifibss->ie_len),
174 ifibss->ie, ifibss->ie_len); 174 ifibss->ie, ifibss->ie_len);
175 175
176 if (local->hw.queues >= 4) {
177 pos = skb_put(skb, 9);
178 *pos++ = WLAN_EID_VENDOR_SPECIFIC;
179 *pos++ = 7; /* len */
180 *pos++ = 0x00; /* Microsoft OUI 00:50:F2 */
181 *pos++ = 0x50;
182 *pos++ = 0xf2;
183 *pos++ = 2; /* WME */
184 *pos++ = 0; /* WME info */
185 *pos++ = 1; /* WME ver */
186 *pos++ = 0; /* U-APSD no in use */
187 }
188
176 rcu_assign_pointer(ifibss->presp, skb); 189 rcu_assign_pointer(ifibss->presp, skb);
177 190
178 sdata->vif.bss_conf.beacon_int = beacon_int; 191 sdata->vif.bss_conf.beacon_int = beacon_int;
@@ -266,37 +279,45 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
266 if (!channel || channel->flags & IEEE80211_CHAN_DISABLED) 279 if (!channel || channel->flags & IEEE80211_CHAN_DISABLED)
267 return; 280 return;
268 281
269 if (sdata->vif.type == NL80211_IFTYPE_ADHOC && elems->supp_rates && 282 if (sdata->vif.type == NL80211_IFTYPE_ADHOC &&
270 memcmp(mgmt->bssid, sdata->u.ibss.bssid, ETH_ALEN) == 0) { 283 memcmp(mgmt->bssid, sdata->u.ibss.bssid, ETH_ALEN) == 0) {
271 supp_rates = ieee80211_sta_get_rates(local, elems, band);
272 284
273 rcu_read_lock(); 285 rcu_read_lock();
274
275 sta = sta_info_get(sdata, mgmt->sa); 286 sta = sta_info_get(sdata, mgmt->sa);
276 if (sta) {
277 u32 prev_rates;
278 287
279 prev_rates = sta->sta.supp_rates[band]; 288 if (elems->supp_rates) {
280 /* make sure mandatory rates are always added */ 289 supp_rates = ieee80211_sta_get_rates(local, elems,
281 sta->sta.supp_rates[band] = supp_rates | 290 band);
282 ieee80211_mandatory_rates(local, band); 291 if (sta) {
292 u32 prev_rates;
283 293
284 if (sta->sta.supp_rates[band] != prev_rates) { 294 prev_rates = sta->sta.supp_rates[band];
295 /* make sure mandatory rates are always added */
296 sta->sta.supp_rates[band] = supp_rates |
297 ieee80211_mandatory_rates(local, band);
298
299 if (sta->sta.supp_rates[band] != prev_rates) {
285#ifdef CONFIG_MAC80211_IBSS_DEBUG 300#ifdef CONFIG_MAC80211_IBSS_DEBUG
286 printk(KERN_DEBUG "%s: updated supp_rates set " 301 printk(KERN_DEBUG
287 "for %pM based on beacon/probe_response " 302 "%s: updated supp_rates set "
288 "(0x%x -> 0x%x)\n", 303 "for %pM based on beacon"
289 sdata->name, sta->sta.addr, 304 "/probe_resp (0x%x -> 0x%x)\n",
290 prev_rates, sta->sta.supp_rates[band]); 305 sdata->name, sta->sta.addr,
306 prev_rates,
307 sta->sta.supp_rates[band]);
291#endif 308#endif
292 rate_control_rate_init(sta); 309 rate_control_rate_init(sta);
293 } 310 }
294 rcu_read_unlock(); 311 } else
295 } else { 312 sta = ieee80211_ibss_add_sta(sdata, mgmt->bssid,
296 rcu_read_unlock(); 313 mgmt->sa, supp_rates,
297 ieee80211_ibss_add_sta(sdata, mgmt->bssid, mgmt->sa, 314 GFP_ATOMIC);
298 supp_rates, GFP_KERNEL);
299 } 315 }
316
317 if (sta && elems->wmm_info)
318 set_sta_flags(sta, WLAN_STA_WME);
319
320 rcu_read_unlock();
300 } 321 }
301 322
302 bss = ieee80211_bss_info_update(local, rx_status, mgmt, len, elems, 323 bss = ieee80211_bss_info_update(local, rx_status, mgmt, len, elems,
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 945fbf29719..f0610fa4fbe 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -369,6 +369,7 @@ struct ieee80211_if_managed {
369 369
370 unsigned int flags; 370 unsigned int flags;
371 371
372 bool beacon_crc_valid;
372 u32 beacon_crc; 373 u32 beacon_crc;
373 374
374 enum { 375 enum {
@@ -548,8 +549,6 @@ struct ieee80211_sub_if_data {
548 struct ieee80211_fragment_entry fragments[IEEE80211_FRAGMENT_MAX]; 549 struct ieee80211_fragment_entry fragments[IEEE80211_FRAGMENT_MAX];
549 unsigned int fragment_next; 550 unsigned int fragment_next;
550 551
551#define NUM_DEFAULT_KEYS 4
552#define NUM_DEFAULT_MGMT_KEYS 2
553 struct ieee80211_key *keys[NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS]; 552 struct ieee80211_key *keys[NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS];
554 struct ieee80211_key *default_key; 553 struct ieee80211_key *default_key;
555 struct ieee80211_key *default_mgmt_key; 554 struct ieee80211_key *default_mgmt_key;
@@ -1132,6 +1131,8 @@ void ieee80211_if_remove(struct ieee80211_sub_if_data *sdata);
1132void ieee80211_remove_interfaces(struct ieee80211_local *local); 1131void ieee80211_remove_interfaces(struct ieee80211_local *local);
1133u32 __ieee80211_recalc_idle(struct ieee80211_local *local); 1132u32 __ieee80211_recalc_idle(struct ieee80211_local *local);
1134void ieee80211_recalc_idle(struct ieee80211_local *local); 1133void ieee80211_recalc_idle(struct ieee80211_local *local);
1134void ieee80211_adjust_monitor_flags(struct ieee80211_sub_if_data *sdata,
1135 const int offset);
1135 1136
1136static inline bool ieee80211_sdata_running(struct ieee80211_sub_if_data *sdata) 1137static inline bool ieee80211_sdata_running(struct ieee80211_sub_if_data *sdata)
1137{ 1138{
@@ -1172,10 +1173,10 @@ int ieee80211_send_smps_action(struct ieee80211_sub_if_data *sdata,
1172void ieee80211_request_smps_work(struct work_struct *work); 1173void ieee80211_request_smps_work(struct work_struct *work);
1173 1174
1174void ___ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid, 1175void ___ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid,
1175 u16 initiator, u16 reason); 1176 u16 initiator, u16 reason, bool stop);
1176void __ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid, 1177void __ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid,
1177 u16 initiator, u16 reason); 1178 u16 initiator, u16 reason, bool stop);
1178void ieee80211_sta_tear_down_BA_sessions(struct sta_info *sta); 1179void ieee80211_sta_tear_down_BA_sessions(struct sta_info *sta, bool tx);
1179void ieee80211_process_delba(struct ieee80211_sub_if_data *sdata, 1180void ieee80211_process_delba(struct ieee80211_sub_if_data *sdata,
1180 struct sta_info *sta, 1181 struct sta_info *sta,
1181 struct ieee80211_mgmt *mgmt, size_t len); 1182 struct ieee80211_mgmt *mgmt, size_t len);
@@ -1189,9 +1190,11 @@ void ieee80211_process_addba_request(struct ieee80211_local *local,
1189 size_t len); 1190 size_t len);
1190 1191
1191int __ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid, 1192int __ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid,
1192 enum ieee80211_back_parties initiator); 1193 enum ieee80211_back_parties initiator,
1194 bool tx);
1193int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid, 1195int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid,
1194 enum ieee80211_back_parties initiator); 1196 enum ieee80211_back_parties initiator,
1197 bool tx);
1195void ieee80211_start_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u16 tid); 1198void ieee80211_start_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u16 tid);
1196void ieee80211_stop_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u8 tid); 1199void ieee80211_stop_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u8 tid);
1197void ieee80211_ba_session_work(struct work_struct *work); 1200void ieee80211_ba_session_work(struct work_struct *work);
@@ -1294,8 +1297,7 @@ u32 ieee80211_sta_get_rates(struct ieee80211_local *local,
1294 enum ieee80211_band band); 1297 enum ieee80211_band band);
1295int __ieee80211_request_smps(struct ieee80211_sub_if_data *sdata, 1298int __ieee80211_request_smps(struct ieee80211_sub_if_data *sdata,
1296 enum ieee80211_smps_mode smps_mode); 1299 enum ieee80211_smps_mode smps_mode);
1297void ieee80211_recalc_smps(struct ieee80211_local *local, 1300void ieee80211_recalc_smps(struct ieee80211_local *local);
1298 struct ieee80211_sub_if_data *forsdata);
1299 1301
1300size_t ieee80211_ie_split(const u8 *ies, size_t ielen, 1302size_t ieee80211_ie_split(const u8 *ies, size_t ielen,
1301 const u8 *ids, int n_ids, size_t offset); 1303 const u8 *ids, int n_ids, size_t offset);
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index 66785739dad..e99d1b60557 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -24,6 +24,7 @@
24#include "led.h" 24#include "led.h"
25#include "driver-ops.h" 25#include "driver-ops.h"
26#include "wme.h" 26#include "wme.h"
27#include "rate.h"
27 28
28/** 29/**
29 * DOC: Interface list locking 30 * DOC: Interface list locking
@@ -148,6 +149,26 @@ static int ieee80211_check_concurrent_iface(struct ieee80211_sub_if_data *sdata,
148 return 0; 149 return 0;
149} 150}
150 151
152void ieee80211_adjust_monitor_flags(struct ieee80211_sub_if_data *sdata,
153 const int offset)
154{
155 struct ieee80211_local *local = sdata->local;
156 u32 flags = sdata->u.mntr_flags;
157
158#define ADJUST(_f, _s) do { \
159 if (flags & MONITOR_FLAG_##_f) \
160 local->fif_##_s += offset; \
161 } while (0)
162
163 ADJUST(FCSFAIL, fcsfail);
164 ADJUST(PLCPFAIL, plcpfail);
165 ADJUST(CONTROL, control);
166 ADJUST(CONTROL, pspoll);
167 ADJUST(OTHER_BSS, other_bss);
168
169#undef ADJUST
170}
171
151/* 172/*
152 * NOTE: Be very careful when changing this function, it must NOT return 173 * NOTE: Be very careful when changing this function, it must NOT return
153 * an error on interface type changes that have been pre-checked, so most 174 * an error on interface type changes that have been pre-checked, so most
@@ -240,17 +261,7 @@ static int ieee80211_do_open(struct net_device *dev, bool coming_up)
240 hw_reconf_flags |= IEEE80211_CONF_CHANGE_MONITOR; 261 hw_reconf_flags |= IEEE80211_CONF_CHANGE_MONITOR;
241 } 262 }
242 263
243 if (sdata->u.mntr_flags & MONITOR_FLAG_FCSFAIL) 264 ieee80211_adjust_monitor_flags(sdata, 1);
244 local->fif_fcsfail++;
245 if (sdata->u.mntr_flags & MONITOR_FLAG_PLCPFAIL)
246 local->fif_plcpfail++;
247 if (sdata->u.mntr_flags & MONITOR_FLAG_CONTROL) {
248 local->fif_control++;
249 local->fif_pspoll++;
250 }
251 if (sdata->u.mntr_flags & MONITOR_FLAG_OTHER_BSS)
252 local->fif_other_bss++;
253
254 ieee80211_configure_filter(local); 265 ieee80211_configure_filter(local);
255 266
256 netif_carrier_on(dev); 267 netif_carrier_on(dev);
@@ -301,6 +312,8 @@ static int ieee80211_do_open(struct net_device *dev, bool coming_up)
301 /* STA has been freed */ 312 /* STA has been freed */
302 goto err_del_interface; 313 goto err_del_interface;
303 } 314 }
315
316 rate_control_rate_init(sta);
304 } 317 }
305 318
306 /* 319 /*
@@ -477,17 +490,7 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
477 hw_reconf_flags |= IEEE80211_CONF_CHANGE_MONITOR; 490 hw_reconf_flags |= IEEE80211_CONF_CHANGE_MONITOR;
478 } 491 }
479 492
480 if (sdata->u.mntr_flags & MONITOR_FLAG_FCSFAIL) 493 ieee80211_adjust_monitor_flags(sdata, -1);
481 local->fif_fcsfail--;
482 if (sdata->u.mntr_flags & MONITOR_FLAG_PLCPFAIL)
483 local->fif_plcpfail--;
484 if (sdata->u.mntr_flags & MONITOR_FLAG_CONTROL) {
485 local->fif_pspoll--;
486 local->fif_control--;
487 }
488 if (sdata->u.mntr_flags & MONITOR_FLAG_OTHER_BSS)
489 local->fif_other_bss--;
490
491 ieee80211_configure_filter(local); 494 ieee80211_configure_filter(local);
492 break; 495 break;
493 case NL80211_IFTYPE_MESH_POINT: 496 case NL80211_IFTYPE_MESH_POINT:
@@ -793,7 +796,8 @@ static void ieee80211_iface_work(struct work_struct *work)
793 796
794 __ieee80211_stop_rx_ba_session( 797 __ieee80211_stop_rx_ba_session(
795 sta, tid, WLAN_BACK_RECIPIENT, 798 sta, tid, WLAN_BACK_RECIPIENT,
796 WLAN_REASON_QSTA_REQUIRE_SETUP); 799 WLAN_REASON_QSTA_REQUIRE_SETUP,
800 true);
797 } 801 }
798 mutex_unlock(&local->sta_mtx); 802 mutex_unlock(&local->sta_mtx);
799 } else switch (sdata->vif.type) { 803 } else switch (sdata->vif.type) {
diff --git a/net/mac80211/key.c b/net/mac80211/key.c
index 6a63d1abd14..ccd676b2f59 100644
--- a/net/mac80211/key.c
+++ b/net/mac80211/key.c
@@ -68,15 +68,21 @@ static int ieee80211_key_enable_hw_accel(struct ieee80211_key *key)
68 68
69 might_sleep(); 69 might_sleep();
70 70
71 if (!key->local->ops->set_key) { 71 if (!key->local->ops->set_key)
72 ret = -EOPNOTSUPP;
73 goto out_unsupported; 72 goto out_unsupported;
74 }
75 73
76 assert_key_lock(key->local); 74 assert_key_lock(key->local);
77 75
78 sta = get_sta_for_key(key); 76 sta = get_sta_for_key(key);
79 77
78 /*
79 * If this is a per-STA GTK, check if it
80 * is supported; if not, return.
81 */
82 if (sta && !(key->conf.flags & IEEE80211_KEY_FLAG_PAIRWISE) &&
83 !(key->local->hw.flags & IEEE80211_HW_SUPPORTS_PER_STA_GTK))
84 goto out_unsupported;
85
80 sdata = key->sdata; 86 sdata = key->sdata;
81 if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) 87 if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
82 sdata = container_of(sdata->bss, 88 sdata = container_of(sdata->bss,
@@ -85,31 +91,28 @@ static int ieee80211_key_enable_hw_accel(struct ieee80211_key *key)
85 91
86 ret = drv_set_key(key->local, SET_KEY, sdata, sta, &key->conf); 92 ret = drv_set_key(key->local, SET_KEY, sdata, sta, &key->conf);
87 93
88 if (!ret) 94 if (!ret) {
89 key->flags |= KEY_FLAG_UPLOADED_TO_HARDWARE; 95 key->flags |= KEY_FLAG_UPLOADED_TO_HARDWARE;
96 return 0;
97 }
90 98
91 if (ret && ret != -ENOSPC && ret != -EOPNOTSUPP) 99 if (ret != -ENOSPC && ret != -EOPNOTSUPP)
92 wiphy_err(key->local->hw.wiphy, 100 wiphy_err(key->local->hw.wiphy,
93 "failed to set key (%d, %pM) to hardware (%d)\n", 101 "failed to set key (%d, %pM) to hardware (%d)\n",
94 key->conf.keyidx, sta ? sta->addr : bcast_addr, ret); 102 key->conf.keyidx, sta ? sta->addr : bcast_addr, ret);
95 103
96out_unsupported: 104 out_unsupported:
97 if (ret) { 105 switch (key->conf.cipher) {
98 switch (key->conf.cipher) { 106 case WLAN_CIPHER_SUITE_WEP40:
99 case WLAN_CIPHER_SUITE_WEP40: 107 case WLAN_CIPHER_SUITE_WEP104:
100 case WLAN_CIPHER_SUITE_WEP104: 108 case WLAN_CIPHER_SUITE_TKIP:
101 case WLAN_CIPHER_SUITE_TKIP: 109 case WLAN_CIPHER_SUITE_CCMP:
102 case WLAN_CIPHER_SUITE_CCMP: 110 case WLAN_CIPHER_SUITE_AES_CMAC:
103 case WLAN_CIPHER_SUITE_AES_CMAC: 111 /* all of these we can do in software */
104 /* all of these we can do in software */ 112 return 0;
105 ret = 0; 113 default:
106 break; 114 return -EINVAL;
107 default:
108 ret = -EINVAL;
109 }
110 } 115 }
111
112 return ret;
113} 116}
114 117
115static void ieee80211_key_disable_hw_accel(struct ieee80211_key *key) 118static void ieee80211_key_disable_hw_accel(struct ieee80211_key *key)
@@ -147,6 +150,26 @@ static void ieee80211_key_disable_hw_accel(struct ieee80211_key *key)
147 key->flags &= ~KEY_FLAG_UPLOADED_TO_HARDWARE; 150 key->flags &= ~KEY_FLAG_UPLOADED_TO_HARDWARE;
148} 151}
149 152
153void ieee80211_key_removed(struct ieee80211_key_conf *key_conf)
154{
155 struct ieee80211_key *key;
156
157 key = container_of(key_conf, struct ieee80211_key, conf);
158
159 might_sleep();
160 assert_key_lock(key->local);
161
162 key->flags &= ~KEY_FLAG_UPLOADED_TO_HARDWARE;
163
164 /*
165 * Flush TX path to avoid attempts to use this key
166 * after this function returns. Until then, drivers
167 * must be prepared to handle the key.
168 */
169 synchronize_rcu();
170}
171EXPORT_SYMBOL_GPL(ieee80211_key_removed);
172
150static void __ieee80211_set_default_key(struct ieee80211_sub_if_data *sdata, 173static void __ieee80211_set_default_key(struct ieee80211_sub_if_data *sdata,
151 int idx) 174 int idx)
152{ 175{
@@ -202,6 +225,7 @@ void ieee80211_set_default_mgmt_key(struct ieee80211_sub_if_data *sdata,
202 225
203static void __ieee80211_key_replace(struct ieee80211_sub_if_data *sdata, 226static void __ieee80211_key_replace(struct ieee80211_sub_if_data *sdata,
204 struct sta_info *sta, 227 struct sta_info *sta,
228 bool pairwise,
205 struct ieee80211_key *old, 229 struct ieee80211_key *old,
206 struct ieee80211_key *new) 230 struct ieee80211_key *new)
207{ 231{
@@ -210,8 +234,14 @@ static void __ieee80211_key_replace(struct ieee80211_sub_if_data *sdata,
210 if (new) 234 if (new)
211 list_add(&new->list, &sdata->key_list); 235 list_add(&new->list, &sdata->key_list);
212 236
213 if (sta) { 237 if (sta && pairwise) {
214 rcu_assign_pointer(sta->key, new); 238 rcu_assign_pointer(sta->ptk, new);
239 } else if (sta) {
240 if (old)
241 idx = old->conf.keyidx;
242 else
243 idx = new->conf.keyidx;
244 rcu_assign_pointer(sta->gtk[idx], new);
215 } else { 245 } else {
216 WARN_ON(new && old && new->conf.keyidx != old->conf.keyidx); 246 WARN_ON(new && old && new->conf.keyidx != old->conf.keyidx);
217 247
@@ -355,6 +385,7 @@ int ieee80211_key_link(struct ieee80211_key *key,
355{ 385{
356 struct ieee80211_key *old_key; 386 struct ieee80211_key *old_key;
357 int idx, ret; 387 int idx, ret;
388 bool pairwise = key->conf.flags & IEEE80211_KEY_FLAG_PAIRWISE;
358 389
359 BUG_ON(!sdata); 390 BUG_ON(!sdata);
360 BUG_ON(!key); 391 BUG_ON(!key);
@@ -371,13 +402,6 @@ int ieee80211_key_link(struct ieee80211_key *key,
371 */ 402 */
372 if (test_sta_flags(sta, WLAN_STA_WME)) 403 if (test_sta_flags(sta, WLAN_STA_WME))
373 key->conf.flags |= IEEE80211_KEY_FLAG_WMM_STA; 404 key->conf.flags |= IEEE80211_KEY_FLAG_WMM_STA;
374
375 /*
376 * This key is for a specific sta interface,
377 * inform the driver that it should try to store
378 * this key as pairwise key.
379 */
380 key->conf.flags |= IEEE80211_KEY_FLAG_PAIRWISE;
381 } else { 405 } else {
382 if (sdata->vif.type == NL80211_IFTYPE_STATION) { 406 if (sdata->vif.type == NL80211_IFTYPE_STATION) {
383 struct sta_info *ap; 407 struct sta_info *ap;
@@ -399,12 +423,14 @@ int ieee80211_key_link(struct ieee80211_key *key,
399 423
400 mutex_lock(&sdata->local->key_mtx); 424 mutex_lock(&sdata->local->key_mtx);
401 425
402 if (sta) 426 if (sta && pairwise)
403 old_key = sta->key; 427 old_key = sta->ptk;
428 else if (sta)
429 old_key = sta->gtk[idx];
404 else 430 else
405 old_key = sdata->keys[idx]; 431 old_key = sdata->keys[idx];
406 432
407 __ieee80211_key_replace(sdata, sta, old_key, key); 433 __ieee80211_key_replace(sdata, sta, pairwise, old_key, key);
408 __ieee80211_key_destroy(old_key); 434 __ieee80211_key_destroy(old_key);
409 435
410 ieee80211_debugfs_key_add(key); 436 ieee80211_debugfs_key_add(key);
@@ -423,7 +449,8 @@ static void __ieee80211_key_free(struct ieee80211_key *key)
423 */ 449 */
424 if (key->sdata) 450 if (key->sdata)
425 __ieee80211_key_replace(key->sdata, key->sta, 451 __ieee80211_key_replace(key->sdata, key->sta,
426 key, NULL); 452 key->conf.flags & IEEE80211_KEY_FLAG_PAIRWISE,
453 key, NULL);
427 __ieee80211_key_destroy(key); 454 __ieee80211_key_destroy(key);
428} 455}
429 456
diff --git a/net/mac80211/key.h b/net/mac80211/key.h
index cb9a4a65cc6..0db1c0f5f69 100644
--- a/net/mac80211/key.h
+++ b/net/mac80211/key.h
@@ -16,6 +16,9 @@
16#include <linux/rcupdate.h> 16#include <linux/rcupdate.h>
17#include <net/mac80211.h> 17#include <net/mac80211.h>
18 18
19#define NUM_DEFAULT_KEYS 4
20#define NUM_DEFAULT_MGMT_KEYS 2
21
19#define WEP_IV_LEN 4 22#define WEP_IV_LEN 4
20#define WEP_ICV_LEN 4 23#define WEP_ICV_LEN 4
21#define ALG_TKIP_KEY_LEN 32 24#define ALG_TKIP_KEY_LEN 32
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index db341a99c7c..eb0f5997767 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -201,6 +201,8 @@ void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata,
201 sdata->vif.bss_conf.bssid = sdata->u.ibss.bssid; 201 sdata->vif.bss_conf.bssid = sdata->u.ibss.bssid;
202 else if (sdata->vif.type == NL80211_IFTYPE_AP) 202 else if (sdata->vif.type == NL80211_IFTYPE_AP)
203 sdata->vif.bss_conf.bssid = sdata->vif.addr; 203 sdata->vif.bss_conf.bssid = sdata->vif.addr;
204 else if (sdata->vif.type == NL80211_IFTYPE_WDS)
205 sdata->vif.bss_conf.bssid = NULL;
204 else if (ieee80211_vif_is_mesh(&sdata->vif)) { 206 else if (ieee80211_vif_is_mesh(&sdata->vif)) {
205 sdata->vif.bss_conf.bssid = zero; 207 sdata->vif.bss_conf.bssid = zero;
206 } else { 208 } else {
@@ -211,6 +213,7 @@ void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata,
211 switch (sdata->vif.type) { 213 switch (sdata->vif.type) {
212 case NL80211_IFTYPE_AP: 214 case NL80211_IFTYPE_AP:
213 case NL80211_IFTYPE_ADHOC: 215 case NL80211_IFTYPE_ADHOC:
216 case NL80211_IFTYPE_WDS:
214 case NL80211_IFTYPE_MESH_POINT: 217 case NL80211_IFTYPE_MESH_POINT:
215 break; 218 break;
216 default: 219 default:
@@ -295,7 +298,16 @@ static void ieee80211_restart_work(struct work_struct *work)
295 struct ieee80211_local *local = 298 struct ieee80211_local *local =
296 container_of(work, struct ieee80211_local, restart_work); 299 container_of(work, struct ieee80211_local, restart_work);
297 300
301 /* wait for scan work complete */
302 flush_workqueue(local->workqueue);
303
304 mutex_lock(&local->mtx);
305 WARN(test_bit(SCAN_HW_SCANNING, &local->scanning),
306 "%s called with hardware scan in progress\n", __func__);
307 mutex_unlock(&local->mtx);
308
298 rtnl_lock(); 309 rtnl_lock();
310 ieee80211_scan_cancel(local);
299 ieee80211_reconfig(local); 311 ieee80211_reconfig(local);
300 rtnl_unlock(); 312 rtnl_unlock();
301} 313}
@@ -306,15 +318,6 @@ void ieee80211_restart_hw(struct ieee80211_hw *hw)
306 318
307 trace_api_restart_hw(local); 319 trace_api_restart_hw(local);
308 320
309 /* wait for scan work complete */
310 flush_workqueue(local->workqueue);
311
312 WARN(test_bit(SCAN_HW_SCANNING, &local->scanning),
313 "%s called with hardware scan in progress\n", __func__);
314
315 if (unlikely(test_bit(SCAN_SW_SCANNING, &local->scanning)))
316 ieee80211_scan_cancel(local);
317
318 /* use this reason, ieee80211_reconfig will unblock it */ 321 /* use this reason, ieee80211_reconfig will unblock it */
319 ieee80211_stop_queues_by_reason(hw, 322 ieee80211_stop_queues_by_reason(hw,
320 IEEE80211_QUEUE_STOP_REASON_SUSPEND); 323 IEEE80211_QUEUE_STOP_REASON_SUSPEND);
@@ -329,7 +332,7 @@ static void ieee80211_recalc_smps_work(struct work_struct *work)
329 container_of(work, struct ieee80211_local, recalc_smps); 332 container_of(work, struct ieee80211_local, recalc_smps);
330 333
331 mutex_lock(&local->iflist_mtx); 334 mutex_lock(&local->iflist_mtx);
332 ieee80211_recalc_smps(local, NULL); 335 ieee80211_recalc_smps(local);
333 mutex_unlock(&local->iflist_mtx); 336 mutex_unlock(&local->iflist_mtx);
334} 337}
335 338
@@ -533,6 +536,7 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
533 /* set up some defaults */ 536 /* set up some defaults */
534 local->hw.queues = 1; 537 local->hw.queues = 1;
535 local->hw.max_rates = 1; 538 local->hw.max_rates = 1;
539 local->hw.max_report_rates = 0;
536 local->hw.conf.long_frame_max_tx_count = wiphy->retry_long; 540 local->hw.conf.long_frame_max_tx_count = wiphy->retry_long;
537 local->hw.conf.short_frame_max_tx_count = wiphy->retry_short; 541 local->hw.conf.short_frame_max_tx_count = wiphy->retry_short;
538 local->user_power_level = -1; 542 local->user_power_level = -1;
@@ -608,6 +612,9 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
608 WLAN_CIPHER_SUITE_AES_CMAC 612 WLAN_CIPHER_SUITE_AES_CMAC
609 }; 613 };
610 614
615 if (hw->max_report_rates == 0)
616 hw->max_report_rates = hw->max_rates;
617
611 /* 618 /*
612 * generic code guarantees at least one band, 619 * generic code guarantees at least one band,
613 * set this very early because much code assumes 620 * set this very early because much code assumes
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 77913a15f53..5695c94c49a 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -913,7 +913,7 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata,
913 913
914 mutex_lock(&local->iflist_mtx); 914 mutex_lock(&local->iflist_mtx);
915 ieee80211_recalc_ps(local, -1); 915 ieee80211_recalc_ps(local, -1);
916 ieee80211_recalc_smps(local, sdata); 916 ieee80211_recalc_smps(local);
917 mutex_unlock(&local->iflist_mtx); 917 mutex_unlock(&local->iflist_mtx);
918 918
919 netif_tx_start_all_queues(sdata->dev); 919 netif_tx_start_all_queues(sdata->dev);
@@ -921,7 +921,7 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata,
921} 921}
922 922
923static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata, 923static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
924 bool remove_sta) 924 bool remove_sta, bool tx)
925{ 925{
926 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 926 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
927 struct ieee80211_local *local = sdata->local; 927 struct ieee80211_local *local = sdata->local;
@@ -960,7 +960,7 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
960 sta = sta_info_get(sdata, bssid); 960 sta = sta_info_get(sdata, bssid);
961 if (sta) { 961 if (sta) {
962 set_sta_flags(sta, WLAN_STA_BLOCK_BA); 962 set_sta_flags(sta, WLAN_STA_BLOCK_BA);
963 ieee80211_sta_tear_down_BA_sessions(sta); 963 ieee80211_sta_tear_down_BA_sessions(sta, tx);
964 } 964 }
965 mutex_unlock(&local->sta_mtx); 965 mutex_unlock(&local->sta_mtx);
966 966
@@ -1124,7 +1124,7 @@ static void __ieee80211_connection_loss(struct ieee80211_sub_if_data *sdata)
1124 1124
1125 printk(KERN_DEBUG "Connection to AP %pM lost.\n", bssid); 1125 printk(KERN_DEBUG "Connection to AP %pM lost.\n", bssid);
1126 1126
1127 ieee80211_set_disassoc(sdata, true); 1127 ieee80211_set_disassoc(sdata, true, true);
1128 mutex_unlock(&ifmgd->mtx); 1128 mutex_unlock(&ifmgd->mtx);
1129 1129
1130 mutex_lock(&local->mtx); 1130 mutex_lock(&local->mtx);
@@ -1197,7 +1197,7 @@ ieee80211_rx_mgmt_deauth(struct ieee80211_sub_if_data *sdata,
1197 printk(KERN_DEBUG "%s: deauthenticated from %pM (Reason: %u)\n", 1197 printk(KERN_DEBUG "%s: deauthenticated from %pM (Reason: %u)\n",
1198 sdata->name, bssid, reason_code); 1198 sdata->name, bssid, reason_code);
1199 1199
1200 ieee80211_set_disassoc(sdata, true); 1200 ieee80211_set_disassoc(sdata, true, false);
1201 mutex_lock(&sdata->local->mtx); 1201 mutex_lock(&sdata->local->mtx);
1202 ieee80211_recalc_idle(sdata->local); 1202 ieee80211_recalc_idle(sdata->local);
1203 mutex_unlock(&sdata->local->mtx); 1203 mutex_unlock(&sdata->local->mtx);
@@ -1229,7 +1229,7 @@ ieee80211_rx_mgmt_disassoc(struct ieee80211_sub_if_data *sdata,
1229 printk(KERN_DEBUG "%s: disassociated from %pM (Reason: %u)\n", 1229 printk(KERN_DEBUG "%s: disassociated from %pM (Reason: %u)\n",
1230 sdata->name, mgmt->sa, reason_code); 1230 sdata->name, mgmt->sa, reason_code);
1231 1231
1232 ieee80211_set_disassoc(sdata, true); 1232 ieee80211_set_disassoc(sdata, true, false);
1233 mutex_lock(&sdata->local->mtx); 1233 mutex_lock(&sdata->local->mtx);
1234 ieee80211_recalc_idle(sdata->local); 1234 ieee80211_recalc_idle(sdata->local);
1235 mutex_unlock(&sdata->local->mtx); 1235 mutex_unlock(&sdata->local->mtx);
@@ -1291,7 +1291,7 @@ static bool ieee80211_assoc_success(struct ieee80211_work *wk,
1291 1291
1292 rates = 0; 1292 rates = 0;
1293 basic_rates = 0; 1293 basic_rates = 0;
1294 sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; 1294 sband = local->hw.wiphy->bands[wk->chan->band];
1295 1295
1296 for (i = 0; i < elems.supp_rates_len; i++) { 1296 for (i = 0; i < elems.supp_rates_len; i++) {
1297 int rate = (elems.supp_rates[i] & 0x7f) * 5; 1297 int rate = (elems.supp_rates[i] & 0x7f) * 5;
@@ -1327,11 +1327,11 @@ static bool ieee80211_assoc_success(struct ieee80211_work *wk,
1327 } 1327 }
1328 } 1328 }
1329 1329
1330 sta->sta.supp_rates[local->hw.conf.channel->band] = rates; 1330 sta->sta.supp_rates[wk->chan->band] = rates;
1331 sdata->vif.bss_conf.basic_rates = basic_rates; 1331 sdata->vif.bss_conf.basic_rates = basic_rates;
1332 1332
1333 /* cf. IEEE 802.11 9.2.12 */ 1333 /* cf. IEEE 802.11 9.2.12 */
1334 if (local->hw.conf.channel->band == IEEE80211_BAND_2GHZ && 1334 if (wk->chan->band == IEEE80211_BAND_2GHZ &&
1335 have_higher_than_11mbit) 1335 have_higher_than_11mbit)
1336 sdata->flags |= IEEE80211_SDATA_OPERATING_GMODE; 1336 sdata->flags |= IEEE80211_SDATA_OPERATING_GMODE;
1337 else 1337 else
@@ -1639,7 +1639,7 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
1639 directed_tim = ieee80211_check_tim(elems.tim, elems.tim_len, 1639 directed_tim = ieee80211_check_tim(elems.tim, elems.tim_len,
1640 ifmgd->aid); 1640 ifmgd->aid);
1641 1641
1642 if (ncrc != ifmgd->beacon_crc) { 1642 if (ncrc != ifmgd->beacon_crc || !ifmgd->beacon_crc_valid) {
1643 ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, &elems, 1643 ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, &elems,
1644 true); 1644 true);
1645 1645
@@ -1670,9 +1670,10 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
1670 } 1670 }
1671 } 1671 }
1672 1672
1673 if (ncrc == ifmgd->beacon_crc) 1673 if (ncrc == ifmgd->beacon_crc && ifmgd->beacon_crc_valid)
1674 return; 1674 return;
1675 ifmgd->beacon_crc = ncrc; 1675 ifmgd->beacon_crc = ncrc;
1676 ifmgd->beacon_crc_valid = true;
1676 1677
1677 if (elems.erp_info && elems.erp_info_len >= 1) { 1678 if (elems.erp_info && elems.erp_info_len >= 1) {
1678 erp_valid = true; 1679 erp_valid = true;
@@ -1879,7 +1880,7 @@ void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata)
1879 printk(KERN_DEBUG "No probe response from AP %pM" 1880 printk(KERN_DEBUG "No probe response from AP %pM"
1880 " after %dms, disconnecting.\n", 1881 " after %dms, disconnecting.\n",
1881 bssid, (1000 * IEEE80211_PROBE_WAIT)/HZ); 1882 bssid, (1000 * IEEE80211_PROBE_WAIT)/HZ);
1882 ieee80211_set_disassoc(sdata, true); 1883 ieee80211_set_disassoc(sdata, true, true);
1883 mutex_unlock(&ifmgd->mtx); 1884 mutex_unlock(&ifmgd->mtx);
1884 mutex_lock(&local->mtx); 1885 mutex_lock(&local->mtx);
1885 ieee80211_recalc_idle(local); 1886 ieee80211_recalc_idle(local);
@@ -2203,7 +2204,7 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
2203 } 2204 }
2204 2205
2205 /* Trying to reassociate - clear previous association state */ 2206 /* Trying to reassociate - clear previous association state */
2206 ieee80211_set_disassoc(sdata, true); 2207 ieee80211_set_disassoc(sdata, true, false);
2207 } 2208 }
2208 mutex_unlock(&ifmgd->mtx); 2209 mutex_unlock(&ifmgd->mtx);
2209 2210
@@ -2214,6 +2215,8 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
2214 ifmgd->flags &= ~IEEE80211_STA_DISABLE_11N; 2215 ifmgd->flags &= ~IEEE80211_STA_DISABLE_11N;
2215 ifmgd->flags &= ~IEEE80211_STA_NULLFUNC_ACKED; 2216 ifmgd->flags &= ~IEEE80211_STA_NULLFUNC_ACKED;
2216 2217
2218 ifmgd->beacon_crc_valid = false;
2219
2217 for (i = 0; i < req->crypto.n_ciphers_pairwise; i++) 2220 for (i = 0; i < req->crypto.n_ciphers_pairwise; i++)
2218 if (req->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_WEP40 || 2221 if (req->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_WEP40 ||
2219 req->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_TKIP || 2222 req->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_TKIP ||
@@ -2315,7 +2318,7 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata,
2315 2318
2316 memcpy(bssid, req->bss->bssid, ETH_ALEN); 2319 memcpy(bssid, req->bss->bssid, ETH_ALEN);
2317 if (ifmgd->associated == req->bss) { 2320 if (ifmgd->associated == req->bss) {
2318 ieee80211_set_disassoc(sdata, false); 2321 ieee80211_set_disassoc(sdata, false, true);
2319 mutex_unlock(&ifmgd->mtx); 2322 mutex_unlock(&ifmgd->mtx);
2320 assoc_bss = true; 2323 assoc_bss = true;
2321 } else { 2324 } else {
@@ -2398,7 +2401,7 @@ int ieee80211_mgd_disassoc(struct ieee80211_sub_if_data *sdata,
2398 sdata->name, req->bss->bssid, req->reason_code); 2401 sdata->name, req->bss->bssid, req->reason_code);
2399 2402
2400 memcpy(bssid, req->bss->bssid, ETH_ALEN); 2403 memcpy(bssid, req->bss->bssid, ETH_ALEN);
2401 ieee80211_set_disassoc(sdata, false); 2404 ieee80211_set_disassoc(sdata, false, true);
2402 2405
2403 mutex_unlock(&ifmgd->mtx); 2406 mutex_unlock(&ifmgd->mtx);
2404 2407
diff --git a/net/mac80211/pm.c b/net/mac80211/pm.c
index ce671dfd238..e37355193ed 100644
--- a/net/mac80211/pm.c
+++ b/net/mac80211/pm.c
@@ -12,8 +12,7 @@ int __ieee80211_suspend(struct ieee80211_hw *hw)
12 struct ieee80211_sub_if_data *sdata; 12 struct ieee80211_sub_if_data *sdata;
13 struct sta_info *sta; 13 struct sta_info *sta;
14 14
15 if (unlikely(test_bit(SCAN_SW_SCANNING, &local->scanning))) 15 ieee80211_scan_cancel(local);
16 ieee80211_scan_cancel(local);
17 16
18 ieee80211_stop_queues_by_reason(hw, 17 ieee80211_stop_queues_by_reason(hw,
19 IEEE80211_QUEUE_STOP_REASON_SUSPEND); 18 IEEE80211_QUEUE_STOP_REASON_SUSPEND);
@@ -46,7 +45,7 @@ int __ieee80211_suspend(struct ieee80211_hw *hw)
46 list_for_each_entry(sta, &local->sta_list, list) { 45 list_for_each_entry(sta, &local->sta_list, list) {
47 if (hw->flags & IEEE80211_HW_AMPDU_AGGREGATION) { 46 if (hw->flags & IEEE80211_HW_AMPDU_AGGREGATION) {
48 set_sta_flags(sta, WLAN_STA_BLOCK_BA); 47 set_sta_flags(sta, WLAN_STA_BLOCK_BA);
49 ieee80211_sta_tear_down_BA_sessions(sta); 48 ieee80211_sta_tear_down_BA_sessions(sta, true);
50 } 49 }
51 50
52 if (sta->uploaded) { 51 if (sta->uploaded) {
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 0b0e83ebe3d..b67221def58 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -819,6 +819,7 @@ ieee80211_rx_h_check(struct ieee80211_rx_data *rx)
819 if (unlikely((ieee80211_is_data(hdr->frame_control) || 819 if (unlikely((ieee80211_is_data(hdr->frame_control) ||
820 ieee80211_is_pspoll(hdr->frame_control)) && 820 ieee80211_is_pspoll(hdr->frame_control)) &&
821 rx->sdata->vif.type != NL80211_IFTYPE_ADHOC && 821 rx->sdata->vif.type != NL80211_IFTYPE_ADHOC &&
822 rx->sdata->vif.type != NL80211_IFTYPE_WDS &&
822 (!rx->sta || !test_sta_flags(rx->sta, WLAN_STA_ASSOC)))) { 823 (!rx->sta || !test_sta_flags(rx->sta, WLAN_STA_ASSOC)))) {
823 if ((!ieee80211_has_fromds(hdr->frame_control) && 824 if ((!ieee80211_has_fromds(hdr->frame_control) &&
824 !ieee80211_has_tods(hdr->frame_control) && 825 !ieee80211_has_tods(hdr->frame_control) &&
@@ -845,7 +846,7 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx)
845 int keyidx; 846 int keyidx;
846 int hdrlen; 847 int hdrlen;
847 ieee80211_rx_result result = RX_DROP_UNUSABLE; 848 ieee80211_rx_result result = RX_DROP_UNUSABLE;
848 struct ieee80211_key *stakey = NULL; 849 struct ieee80211_key *sta_ptk = NULL;
849 int mmie_keyidx = -1; 850 int mmie_keyidx = -1;
850 __le16 fc; 851 __le16 fc;
851 852
@@ -887,15 +888,15 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx)
887 rx->key = NULL; 888 rx->key = NULL;
888 889
889 if (rx->sta) 890 if (rx->sta)
890 stakey = rcu_dereference(rx->sta->key); 891 sta_ptk = rcu_dereference(rx->sta->ptk);
891 892
892 fc = hdr->frame_control; 893 fc = hdr->frame_control;
893 894
894 if (!ieee80211_has_protected(fc)) 895 if (!ieee80211_has_protected(fc))
895 mmie_keyidx = ieee80211_get_mmie_keyidx(rx->skb); 896 mmie_keyidx = ieee80211_get_mmie_keyidx(rx->skb);
896 897
897 if (!is_multicast_ether_addr(hdr->addr1) && stakey) { 898 if (!is_multicast_ether_addr(hdr->addr1) && sta_ptk) {
898 rx->key = stakey; 899 rx->key = sta_ptk;
899 if ((status->flag & RX_FLAG_DECRYPTED) && 900 if ((status->flag & RX_FLAG_DECRYPTED) &&
900 (status->flag & RX_FLAG_IV_STRIPPED)) 901 (status->flag & RX_FLAG_IV_STRIPPED))
901 return RX_CONTINUE; 902 return RX_CONTINUE;
@@ -911,7 +912,10 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx)
911 if (mmie_keyidx < NUM_DEFAULT_KEYS || 912 if (mmie_keyidx < NUM_DEFAULT_KEYS ||
912 mmie_keyidx >= NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS) 913 mmie_keyidx >= NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS)
913 return RX_DROP_MONITOR; /* unexpected BIP keyidx */ 914 return RX_DROP_MONITOR; /* unexpected BIP keyidx */
914 rx->key = rcu_dereference(rx->sdata->keys[mmie_keyidx]); 915 if (rx->sta)
916 rx->key = rcu_dereference(rx->sta->gtk[mmie_keyidx]);
917 if (!rx->key)
918 rx->key = rcu_dereference(rx->sdata->keys[mmie_keyidx]);
915 } else if (!ieee80211_has_protected(fc)) { 919 } else if (!ieee80211_has_protected(fc)) {
916 /* 920 /*
917 * The frame was not protected, so skip decryption. However, we 921 * The frame was not protected, so skip decryption. However, we
@@ -954,17 +958,25 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx)
954 skb_copy_bits(rx->skb, hdrlen + 3, &keyid, 1); 958 skb_copy_bits(rx->skb, hdrlen + 3, &keyid, 1);
955 keyidx = keyid >> 6; 959 keyidx = keyid >> 6;
956 960
957 rx->key = rcu_dereference(rx->sdata->keys[keyidx]); 961 /* check per-station GTK first, if multicast packet */
962 if (is_multicast_ether_addr(hdr->addr1) && rx->sta)
963 rx->key = rcu_dereference(rx->sta->gtk[keyidx]);
958 964
959 /* 965 /* if not found, try default key */
960 * RSNA-protected unicast frames should always be sent with 966 if (!rx->key) {
961 * pairwise or station-to-station keys, but for WEP we allow 967 rx->key = rcu_dereference(rx->sdata->keys[keyidx]);
962 * using a key index as well. 968
963 */ 969 /*
964 if (rx->key && rx->key->conf.cipher != WLAN_CIPHER_SUITE_WEP40 && 970 * RSNA-protected unicast frames should always be
965 rx->key->conf.cipher != WLAN_CIPHER_SUITE_WEP104 && 971 * sent with pairwise or station-to-station keys,
966 !is_multicast_ether_addr(hdr->addr1)) 972 * but for WEP we allow using a key index as well.
967 rx->key = NULL; 973 */
974 if (rx->key &&
975 rx->key->conf.cipher != WLAN_CIPHER_SUITE_WEP40 &&
976 rx->key->conf.cipher != WLAN_CIPHER_SUITE_WEP104 &&
977 !is_multicast_ether_addr(hdr->addr1))
978 rx->key = NULL;
979 }
968 } 980 }
969 981
970 if (rx->key) { 982 if (rx->key) {
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index 5171a958163..fb274db77e3 100644
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -249,12 +249,12 @@ static bool ieee80211_prep_hw_scan(struct ieee80211_local *local)
249 return true; 249 return true;
250} 250}
251 251
252static void __ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted) 252static bool __ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted,
253 bool was_hw_scan)
253{ 254{
254 struct ieee80211_local *local = hw_to_local(hw); 255 struct ieee80211_local *local = hw_to_local(hw);
255 bool was_hw_scan;
256 256
257 mutex_lock(&local->mtx); 257 lockdep_assert_held(&local->mtx);
258 258
259 /* 259 /*
260 * It's ok to abort a not-yet-running scan (that 260 * It's ok to abort a not-yet-running scan (that
@@ -265,17 +265,13 @@ static void __ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted)
265 if (WARN_ON(!local->scanning && !aborted)) 265 if (WARN_ON(!local->scanning && !aborted))
266 aborted = true; 266 aborted = true;
267 267
268 if (WARN_ON(!local->scan_req)) { 268 if (WARN_ON(!local->scan_req))
269 mutex_unlock(&local->mtx); 269 return false;
270 return;
271 }
272 270
273 was_hw_scan = test_bit(SCAN_HW_SCANNING, &local->scanning);
274 if (was_hw_scan && !aborted && ieee80211_prep_hw_scan(local)) { 271 if (was_hw_scan && !aborted && ieee80211_prep_hw_scan(local)) {
275 ieee80211_queue_delayed_work(&local->hw, 272 int rc = drv_hw_scan(local, local->scan_sdata, local->hw_scan_req);
276 &local->scan_work, 0); 273 if (rc == 0)
277 mutex_unlock(&local->mtx); 274 return false;
278 return;
279 } 275 }
280 276
281 kfree(local->hw_scan_req); 277 kfree(local->hw_scan_req);
@@ -289,23 +285,25 @@ static void __ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted)
289 local->scanning = 0; 285 local->scanning = 0;
290 local->scan_channel = NULL; 286 local->scan_channel = NULL;
291 287
292 /* we only have to protect scan_req and hw/sw scan */ 288 return true;
293 mutex_unlock(&local->mtx); 289}
294
295 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);
296 if (was_hw_scan)
297 goto done;
298
299 ieee80211_configure_filter(local);
300 290
301 drv_sw_scan_complete(local); 291static void __ieee80211_scan_completed_finish(struct ieee80211_hw *hw,
292 bool was_hw_scan)
293{
294 struct ieee80211_local *local = hw_to_local(hw);
302 295
303 ieee80211_offchannel_return(local, true); 296 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);
297 if (!was_hw_scan) {
298 ieee80211_configure_filter(local);
299 drv_sw_scan_complete(local);
300 ieee80211_offchannel_return(local, true);
301 }
304 302
305 done:
306 mutex_lock(&local->mtx); 303 mutex_lock(&local->mtx);
307 ieee80211_recalc_idle(local); 304 ieee80211_recalc_idle(local);
308 mutex_unlock(&local->mtx); 305 mutex_unlock(&local->mtx);
306
309 ieee80211_mlme_notify_scan_completed(local); 307 ieee80211_mlme_notify_scan_completed(local);
310 ieee80211_ibss_notify_scan_completed(local); 308 ieee80211_ibss_notify_scan_completed(local);
311 ieee80211_mesh_notify_scan_completed(local); 309 ieee80211_mesh_notify_scan_completed(local);
@@ -366,6 +364,8 @@ static int __ieee80211_start_scan(struct ieee80211_sub_if_data *sdata,
366 struct ieee80211_local *local = sdata->local; 364 struct ieee80211_local *local = sdata->local;
367 int rc; 365 int rc;
368 366
367 lockdep_assert_held(&local->mtx);
368
369 if (local->scan_req) 369 if (local->scan_req)
370 return -EBUSY; 370 return -EBUSY;
371 371
@@ -447,8 +447,8 @@ ieee80211_scan_get_channel_time(struct ieee80211_channel *chan)
447 return IEEE80211_PROBE_DELAY + IEEE80211_CHANNEL_TIME; 447 return IEEE80211_PROBE_DELAY + IEEE80211_CHANNEL_TIME;
448} 448}
449 449
450static int ieee80211_scan_state_decision(struct ieee80211_local *local, 450static void ieee80211_scan_state_decision(struct ieee80211_local *local,
451 unsigned long *next_delay) 451 unsigned long *next_delay)
452{ 452{
453 bool associated = false; 453 bool associated = false;
454 bool tx_empty = true; 454 bool tx_empty = true;
@@ -458,12 +458,6 @@ static int ieee80211_scan_state_decision(struct ieee80211_local *local,
458 struct ieee80211_sub_if_data *sdata; 458 struct ieee80211_sub_if_data *sdata;
459 struct ieee80211_channel *next_chan; 459 struct ieee80211_channel *next_chan;
460 460
461 /* if no more bands/channels left, complete scan and advance to the idle state */
462 if (local->scan_channel_idx >= local->scan_req->n_channels) {
463 __ieee80211_scan_completed(&local->hw, false);
464 return 1;
465 }
466
467 /* 461 /*
468 * check if at least one STA interface is associated, 462 * check if at least one STA interface is associated,
469 * check if at least one STA interface has pending tx frames 463 * check if at least one STA interface has pending tx frames
@@ -535,7 +529,6 @@ static int ieee80211_scan_state_decision(struct ieee80211_local *local,
535 } 529 }
536 530
537 *next_delay = 0; 531 *next_delay = 0;
538 return 0;
539} 532}
540 533
541static void ieee80211_scan_state_leave_oper_channel(struct ieee80211_local *local, 534static void ieee80211_scan_state_leave_oper_channel(struct ieee80211_local *local,
@@ -651,28 +644,17 @@ void ieee80211_scan_work(struct work_struct *work)
651 container_of(work, struct ieee80211_local, scan_work.work); 644 container_of(work, struct ieee80211_local, scan_work.work);
652 struct ieee80211_sub_if_data *sdata = local->scan_sdata; 645 struct ieee80211_sub_if_data *sdata = local->scan_sdata;
653 unsigned long next_delay = 0; 646 unsigned long next_delay = 0;
647 bool aborted, hw_scan, finish;
654 648
655 if (test_and_clear_bit(SCAN_COMPLETED, &local->scanning)) { 649 mutex_lock(&local->mtx);
656 bool aborted;
657 650
651 if (test_and_clear_bit(SCAN_COMPLETED, &local->scanning)) {
658 aborted = test_and_clear_bit(SCAN_ABORTED, &local->scanning); 652 aborted = test_and_clear_bit(SCAN_ABORTED, &local->scanning);
659 __ieee80211_scan_completed(&local->hw, aborted); 653 goto out_complete;
660 return;
661 }
662
663 mutex_lock(&local->mtx);
664 if (!sdata || !local->scan_req) {
665 mutex_unlock(&local->mtx);
666 return;
667 } 654 }
668 655
669 if (local->hw_scan_req) { 656 if (!sdata || !local->scan_req)
670 int rc = drv_hw_scan(local, sdata, local->hw_scan_req); 657 goto out;
671 mutex_unlock(&local->mtx);
672 if (rc)
673 __ieee80211_scan_completed(&local->hw, true);
674 return;
675 }
676 658
677 if (local->scan_req && !local->scanning) { 659 if (local->scan_req && !local->scanning) {
678 struct cfg80211_scan_request *req = local->scan_req; 660 struct cfg80211_scan_request *req = local->scan_req;
@@ -682,21 +664,21 @@ void ieee80211_scan_work(struct work_struct *work)
682 local->scan_sdata = NULL; 664 local->scan_sdata = NULL;
683 665
684 rc = __ieee80211_start_scan(sdata, req); 666 rc = __ieee80211_start_scan(sdata, req);
685 mutex_unlock(&local->mtx); 667 if (rc) {
686 668 /* need to complete scan in cfg80211 */
687 if (rc) 669 local->scan_req = req;
688 __ieee80211_scan_completed(&local->hw, true); 670 aborted = true;
689 return; 671 goto out_complete;
672 } else
673 goto out;
690 } 674 }
691 675
692 mutex_unlock(&local->mtx);
693
694 /* 676 /*
695 * Avoid re-scheduling when the sdata is going away. 677 * Avoid re-scheduling when the sdata is going away.
696 */ 678 */
697 if (!ieee80211_sdata_running(sdata)) { 679 if (!ieee80211_sdata_running(sdata)) {
698 __ieee80211_scan_completed(&local->hw, true); 680 aborted = true;
699 return; 681 goto out_complete;
700 } 682 }
701 683
702 /* 684 /*
@@ -706,8 +688,12 @@ void ieee80211_scan_work(struct work_struct *work)
706 do { 688 do {
707 switch (local->next_scan_state) { 689 switch (local->next_scan_state) {
708 case SCAN_DECISION: 690 case SCAN_DECISION:
709 if (ieee80211_scan_state_decision(local, &next_delay)) 691 /* if no more bands/channels left, complete scan */
710 return; 692 if (local->scan_channel_idx >= local->scan_req->n_channels) {
693 aborted = false;
694 goto out_complete;
695 }
696 ieee80211_scan_state_decision(local, &next_delay);
711 break; 697 break;
712 case SCAN_SET_CHANNEL: 698 case SCAN_SET_CHANNEL:
713 ieee80211_scan_state_set_channel(local, &next_delay); 699 ieee80211_scan_state_set_channel(local, &next_delay);
@@ -725,6 +711,19 @@ void ieee80211_scan_work(struct work_struct *work)
725 } while (next_delay == 0); 711 } while (next_delay == 0);
726 712
727 ieee80211_queue_delayed_work(&local->hw, &local->scan_work, next_delay); 713 ieee80211_queue_delayed_work(&local->hw, &local->scan_work, next_delay);
714 mutex_unlock(&local->mtx);
715 return;
716
717out_complete:
718 hw_scan = test_bit(SCAN_HW_SCANNING, &local->scanning);
719 finish = __ieee80211_scan_completed(&local->hw, aborted, hw_scan);
720 mutex_unlock(&local->mtx);
721 if (finish)
722 __ieee80211_scan_completed_finish(&local->hw, hw_scan);
723 return;
724
725out:
726 mutex_unlock(&local->mtx);
728} 727}
729 728
730int ieee80211_request_scan(struct ieee80211_sub_if_data *sdata, 729int ieee80211_request_scan(struct ieee80211_sub_if_data *sdata,
@@ -786,21 +785,40 @@ int ieee80211_request_internal_scan(struct ieee80211_sub_if_data *sdata,
786 return ret; 785 return ret;
787} 786}
788 787
788/*
789 * Only call this function when a scan can't be queued -- under RTNL.
790 */
789void ieee80211_scan_cancel(struct ieee80211_local *local) 791void ieee80211_scan_cancel(struct ieee80211_local *local)
790{ 792{
791 bool abortscan; 793 bool abortscan;
792 794 bool finish = false;
793 cancel_delayed_work_sync(&local->scan_work);
794 795
795 /* 796 /*
796 * Only call this function when a scan can't be 797 * We are only canceling software scan, or deferred scan that was not
797 * queued -- mostly at suspend under RTNL. 798 * yet really started (see __ieee80211_start_scan ).
799 *
800 * Regarding hardware scan:
801 * - we can not call __ieee80211_scan_completed() as when
802 * SCAN_HW_SCANNING bit is set this function change
803 * local->hw_scan_req to operate on 5G band, what race with
804 * driver which can use local->hw_scan_req
805 *
806 * - we can not cancel scan_work since driver can schedule it
807 * by ieee80211_scan_completed(..., true) to finish scan
808 *
809 * Hence low lever driver is responsible for canceling HW scan.
798 */ 810 */
811
799 mutex_lock(&local->mtx); 812 mutex_lock(&local->mtx);
800 abortscan = test_bit(SCAN_SW_SCANNING, &local->scanning) || 813 abortscan = local->scan_req && !test_bit(SCAN_HW_SCANNING, &local->scanning);
801 (!local->scanning && local->scan_req); 814 if (abortscan)
815 finish = __ieee80211_scan_completed(&local->hw, true, false);
802 mutex_unlock(&local->mtx); 816 mutex_unlock(&local->mtx);
803 817
804 if (abortscan) 818 if (abortscan) {
805 __ieee80211_scan_completed(&local->hw, true); 819 /* The scan is canceled, but stop work from being pending */
820 cancel_delayed_work_sync(&local->scan_work);
821 }
822 if (finish)
823 __ieee80211_scan_completed_finish(&local->hw, false);
806} 824}
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index ca2cba9cea8..6d8f897d876 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -616,7 +616,7 @@ static int __must_check __sta_info_destroy(struct sta_info *sta)
616 struct ieee80211_sub_if_data *sdata; 616 struct ieee80211_sub_if_data *sdata;
617 struct sk_buff *skb; 617 struct sk_buff *skb;
618 unsigned long flags; 618 unsigned long flags;
619 int ret; 619 int ret, i;
620 620
621 might_sleep(); 621 might_sleep();
622 622
@@ -633,7 +633,7 @@ static int __must_check __sta_info_destroy(struct sta_info *sta)
633 * will be sufficient. 633 * will be sufficient.
634 */ 634 */
635 set_sta_flags(sta, WLAN_STA_BLOCK_BA); 635 set_sta_flags(sta, WLAN_STA_BLOCK_BA);
636 ieee80211_sta_tear_down_BA_sessions(sta); 636 ieee80211_sta_tear_down_BA_sessions(sta, true);
637 637
638 spin_lock_irqsave(&local->sta_lock, flags); 638 spin_lock_irqsave(&local->sta_lock, flags);
639 ret = sta_info_hash_del(local, sta); 639 ret = sta_info_hash_del(local, sta);
@@ -644,10 +644,10 @@ static int __must_check __sta_info_destroy(struct sta_info *sta)
644 if (ret) 644 if (ret)
645 return ret; 645 return ret;
646 646
647 if (sta->key) { 647 for (i = 0; i < NUM_DEFAULT_KEYS; i++)
648 ieee80211_key_free(local, sta->key); 648 ieee80211_key_free(local, sta->gtk[i]);
649 WARN_ON(sta->key); 649 if (sta->ptk)
650 } 650 ieee80211_key_free(local, sta->ptk);
651 651
652 sta->dead = true; 652 sta->dead = true;
653 653
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h
index 810c5ce9831..9265acadef3 100644
--- a/net/mac80211/sta_info.h
+++ b/net/mac80211/sta_info.h
@@ -79,6 +79,7 @@ enum ieee80211_sta_info_flags {
79 * @dialog_token: dialog token for aggregation session 79 * @dialog_token: dialog token for aggregation session
80 * @state: session state (see above) 80 * @state: session state (see above)
81 * @stop_initiator: initiator of a session stop 81 * @stop_initiator: initiator of a session stop
82 * @tx_stop: TX DelBA frame when stopping
82 * 83 *
83 * This structure is protected by RCU and the per-station 84 * This structure is protected by RCU and the per-station
84 * spinlock. Assignments to the array holding it must hold 85 * spinlock. Assignments to the array holding it must hold
@@ -95,6 +96,7 @@ struct tid_ampdu_tx {
95 unsigned long state; 96 unsigned long state;
96 u8 dialog_token; 97 u8 dialog_token;
97 u8 stop_initiator; 98 u8 stop_initiator;
99 bool tx_stop;
98}; 100};
99 101
100/** 102/**
@@ -197,7 +199,8 @@ enum plink_state {
197 * @hnext: hash table linked list pointer 199 * @hnext: hash table linked list pointer
198 * @local: pointer to the global information 200 * @local: pointer to the global information
199 * @sdata: virtual interface this station belongs to 201 * @sdata: virtual interface this station belongs to
200 * @key: peer key negotiated with this station, if any 202 * @ptk: peer key negotiated with this station, if any
203 * @gtk: group keys negotiated with this station, if any
201 * @rate_ctrl: rate control algorithm reference 204 * @rate_ctrl: rate control algorithm reference
202 * @rate_ctrl_priv: rate control private per-STA pointer 205 * @rate_ctrl_priv: rate control private per-STA pointer
203 * @last_tx_rate: rate used for last transmit, to report to userspace as 206 * @last_tx_rate: rate used for last transmit, to report to userspace as
@@ -252,7 +255,8 @@ struct sta_info {
252 struct sta_info *hnext; 255 struct sta_info *hnext;
253 struct ieee80211_local *local; 256 struct ieee80211_local *local;
254 struct ieee80211_sub_if_data *sdata; 257 struct ieee80211_sub_if_data *sdata;
255 struct ieee80211_key *key; 258 struct ieee80211_key *gtk[NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS];
259 struct ieee80211_key *ptk;
256 struct rate_control_ref *rate_ctrl; 260 struct rate_control_ref *rate_ctrl;
257 void *rate_ctrl_priv; 261 void *rate_ctrl_priv;
258 spinlock_t lock; 262 spinlock_t lock;
diff --git a/net/mac80211/status.c b/net/mac80211/status.c
index dd85006c4fe..3153c19893b 100644
--- a/net/mac80211/status.c
+++ b/net/mac80211/status.c
@@ -176,7 +176,7 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
176 176
177 for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) { 177 for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) {
178 /* the HW cannot have attempted that rate */ 178 /* the HW cannot have attempted that rate */
179 if (i >= hw->max_rates) { 179 if (i >= hw->max_report_rates) {
180 info->status.rates[i].idx = -1; 180 info->status.rates[i].idx = -1;
181 info->status.rates[i].count = 0; 181 info->status.rates[i].count = 0;
182 } else if (info->status.rates[i].idx >= 0) { 182 } else if (info->status.rates[i].idx >= 0) {
@@ -377,7 +377,7 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
377 skb2 = skb_clone(skb, GFP_ATOMIC); 377 skb2 = skb_clone(skb, GFP_ATOMIC);
378 if (skb2) { 378 if (skb2) {
379 skb2->dev = prev_dev; 379 skb2->dev = prev_dev;
380 netif_receive_skb(skb2); 380 netif_rx(skb2);
381 } 381 }
382 } 382 }
383 383
@@ -386,7 +386,7 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
386 } 386 }
387 if (prev_dev) { 387 if (prev_dev) {
388 skb->dev = prev_dev; 388 skb->dev = prev_dev;
389 netif_receive_skb(skb); 389 netif_rx(skb);
390 skb = NULL; 390 skb = NULL;
391 } 391 }
392 rcu_read_unlock(); 392 rcu_read_unlock();
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index e1733dcb58a..96c59430950 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -273,6 +273,9 @@ ieee80211_tx_h_check_assoc(struct ieee80211_tx_data *tx)
273 */ 273 */
274 return TX_DROP; 274 return TX_DROP;
275 275
276 if (tx->sdata->vif.type == NL80211_IFTYPE_WDS)
277 return TX_CONTINUE;
278
276 if (tx->sdata->vif.type == NL80211_IFTYPE_MESH_POINT) 279 if (tx->sdata->vif.type == NL80211_IFTYPE_MESH_POINT)
277 return TX_CONTINUE; 280 return TX_CONTINUE;
278 281
@@ -529,7 +532,7 @@ ieee80211_tx_h_select_key(struct ieee80211_tx_data *tx)
529 532
530 if (unlikely(info->flags & IEEE80211_TX_INTFL_DONT_ENCRYPT)) 533 if (unlikely(info->flags & IEEE80211_TX_INTFL_DONT_ENCRYPT))
531 tx->key = NULL; 534 tx->key = NULL;
532 else if (tx->sta && (key = rcu_dereference(tx->sta->key))) 535 else if (tx->sta && (key = rcu_dereference(tx->sta->ptk)))
533 tx->key = key; 536 tx->key = key;
534 else if (ieee80211_is_mgmt(hdr->frame_control) && 537 else if (ieee80211_is_mgmt(hdr->frame_control) &&
535 is_multicast_ether_addr(hdr->addr1) && 538 is_multicast_ether_addr(hdr->addr1) &&
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index aba025d748e..0b6fc92bc0d 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -1221,7 +1221,7 @@ int ieee80211_reconfig(struct ieee80211_local *local)
1221 mutex_lock(&local->sta_mtx); 1221 mutex_lock(&local->sta_mtx);
1222 1222
1223 list_for_each_entry(sta, &local->sta_list, list) { 1223 list_for_each_entry(sta, &local->sta_list, list) {
1224 ieee80211_sta_tear_down_BA_sessions(sta); 1224 ieee80211_sta_tear_down_BA_sessions(sta, true);
1225 clear_sta_flags(sta, WLAN_STA_BLOCK_BA); 1225 clear_sta_flags(sta, WLAN_STA_BLOCK_BA);
1226 } 1226 }
1227 1227
@@ -1297,16 +1297,12 @@ static int check_mgd_smps(struct ieee80211_if_managed *ifmgd,
1297} 1297}
1298 1298
1299/* must hold iflist_mtx */ 1299/* must hold iflist_mtx */
1300void ieee80211_recalc_smps(struct ieee80211_local *local, 1300void ieee80211_recalc_smps(struct ieee80211_local *local)
1301 struct ieee80211_sub_if_data *forsdata)
1302{ 1301{
1303 struct ieee80211_sub_if_data *sdata; 1302 struct ieee80211_sub_if_data *sdata;
1304 enum ieee80211_smps_mode smps_mode = IEEE80211_SMPS_OFF; 1303 enum ieee80211_smps_mode smps_mode = IEEE80211_SMPS_OFF;
1305 int count = 0; 1304 int count = 0;
1306 1305
1307 if (forsdata)
1308 lockdep_assert_held(&forsdata->u.mgd.mtx);
1309
1310 lockdep_assert_held(&local->iflist_mtx); 1306 lockdep_assert_held(&local->iflist_mtx);
1311 1307
1312 /* 1308 /*
@@ -1324,18 +1320,8 @@ void ieee80211_recalc_smps(struct ieee80211_local *local,
1324 continue; 1320 continue;
1325 if (sdata->vif.type != NL80211_IFTYPE_STATION) 1321 if (sdata->vif.type != NL80211_IFTYPE_STATION)
1326 goto set; 1322 goto set;
1327 if (sdata != forsdata) { 1323
1328 /* 1324 count += check_mgd_smps(&sdata->u.mgd, &smps_mode);
1329 * This nested is ok -- we are holding the iflist_mtx
1330 * so can't get here twice or so. But it's required
1331 * since normally we acquire it first and then the
1332 * iflist_mtx.
1333 */
1334 mutex_lock_nested(&sdata->u.mgd.mtx, SINGLE_DEPTH_NESTING);
1335 count += check_mgd_smps(&sdata->u.mgd, &smps_mode);
1336 mutex_unlock(&sdata->u.mgd.mtx);
1337 } else
1338 count += check_mgd_smps(&sdata->u.mgd, &smps_mode);
1339 1325
1340 if (count > 1) { 1326 if (count > 1) {
1341 smps_mode = IEEE80211_SMPS_OFF; 1327 smps_mode = IEEE80211_SMPS_OFF;
diff --git a/net/netlink/genetlink.c b/net/netlink/genetlink.c
index 26ed3e8587c..1781d99145e 100644
--- a/net/netlink/genetlink.c
+++ b/net/netlink/genetlink.c
@@ -547,8 +547,20 @@ static int genl_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
547 info.userhdr = nlmsg_data(nlh) + GENL_HDRLEN; 547 info.userhdr = nlmsg_data(nlh) + GENL_HDRLEN;
548 info.attrs = family->attrbuf; 548 info.attrs = family->attrbuf;
549 genl_info_net_set(&info, net); 549 genl_info_net_set(&info, net);
550 memset(&info.user_ptr, 0, sizeof(info.user_ptr));
550 551
551 return ops->doit(skb, &info); 552 if (family->pre_doit) {
553 err = family->pre_doit(ops, skb, &info);
554 if (err)
555 return err;
556 }
557
558 err = ops->doit(skb, &info);
559
560 if (family->post_doit)
561 family->post_doit(ops, skb, &info);
562
563 return err;
552} 564}
553 565
554static void genl_rcv(struct sk_buff *skb) 566static void genl_rcv(struct sk_buff *skb)
diff --git a/net/wireless/core.c b/net/wireless/core.c
index 9c21ebf9780..1684ad91763 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -178,26 +178,10 @@ int cfg80211_dev_rename(struct cfg80211_registered_device *rdev,
178 char *newname) 178 char *newname)
179{ 179{
180 struct cfg80211_registered_device *rdev2; 180 struct cfg80211_registered_device *rdev2;
181 int wiphy_idx, taken = -1, result, digits; 181 int result;
182 182
183 assert_cfg80211_lock(); 183 assert_cfg80211_lock();
184 184
185 /* prohibit calling the thing phy%d when %d is not its number */
186 sscanf(newname, PHY_NAME "%d%n", &wiphy_idx, &taken);
187 if (taken == strlen(newname) && wiphy_idx != rdev->wiphy_idx) {
188 /* count number of places needed to print wiphy_idx */
189 digits = 1;
190 while (wiphy_idx /= 10)
191 digits++;
192 /*
193 * deny the name if it is phy<idx> where <idx> is printed
194 * without leading zeroes. taken == strlen(newname) here
195 */
196 if (taken == strlen(PHY_NAME) + digits)
197 return -EINVAL;
198 }
199
200
201 /* Ignore nop renames */ 185 /* Ignore nop renames */
202 if (strcmp(newname, dev_name(&rdev->wiphy.dev)) == 0) 186 if (strcmp(newname, dev_name(&rdev->wiphy.dev)) == 0)
203 return 0; 187 return 0;
@@ -205,7 +189,7 @@ int cfg80211_dev_rename(struct cfg80211_registered_device *rdev,
205 /* Ensure another device does not already have this name. */ 189 /* Ensure another device does not already have this name. */
206 list_for_each_entry(rdev2, &cfg80211_rdev_list, list) 190 list_for_each_entry(rdev2, &cfg80211_rdev_list, list)
207 if (strcmp(newname, dev_name(&rdev2->wiphy.dev)) == 0) 191 if (strcmp(newname, dev_name(&rdev2->wiphy.dev)) == 0)
208 return -EINVAL; 192 return -EEXIST;
209 193
210 result = device_rename(&rdev->wiphy.dev, newname); 194 result = device_rename(&rdev->wiphy.dev, newname);
211 if (result) 195 if (result)
@@ -320,9 +304,11 @@ static void cfg80211_event_work(struct work_struct *work)
320struct wiphy *wiphy_new(const struct cfg80211_ops *ops, int sizeof_priv) 304struct wiphy *wiphy_new(const struct cfg80211_ops *ops, int sizeof_priv)
321{ 305{
322 static int wiphy_counter; 306 static int wiphy_counter;
323 307 int i;
324 struct cfg80211_registered_device *rdev; 308 struct cfg80211_registered_device *rdev, *rdev2;
325 int alloc_size; 309 int alloc_size;
310 char nname[IFNAMSIZ + 1];
311 bool found = false;
326 312
327 WARN_ON(ops->add_key && (!ops->del_key || !ops->set_default_key)); 313 WARN_ON(ops->add_key && (!ops->del_key || !ops->set_default_key));
328 WARN_ON(ops->auth && (!ops->assoc || !ops->deauth || !ops->disassoc)); 314 WARN_ON(ops->auth && (!ops->assoc || !ops->deauth || !ops->disassoc));
@@ -346,16 +332,36 @@ struct wiphy *wiphy_new(const struct cfg80211_ops *ops, int sizeof_priv)
346 332
347 if (unlikely(!wiphy_idx_valid(rdev->wiphy_idx))) { 333 if (unlikely(!wiphy_idx_valid(rdev->wiphy_idx))) {
348 wiphy_counter--; 334 wiphy_counter--;
335 goto too_many_devs;
336 }
337
338 /* 64k wiphy devices is enough for anyone! */
339 for (i = 0; i < 0xFFFF; i++) {
340 found = false;
341 snprintf(nname, sizeof(nname)-1, PHY_NAME "%d", i);
342 nname[sizeof(nname)-1] = 0;
343 list_for_each_entry(rdev2, &cfg80211_rdev_list, list)
344 if (strcmp(nname, dev_name(&rdev2->wiphy.dev)) == 0) {
345 found = true;
346 break;
347 }
348
349 if (!found)
350 break;
351 }
352
353 if (unlikely(found)) {
354too_many_devs:
349 mutex_unlock(&cfg80211_mutex); 355 mutex_unlock(&cfg80211_mutex);
350 /* ugh, wrapped! */ 356 /* ugh, too many devices already! */
351 kfree(rdev); 357 kfree(rdev);
352 return NULL; 358 return NULL;
353 } 359 }
354 360
355 mutex_unlock(&cfg80211_mutex);
356
357 /* give it a proper name */ 361 /* give it a proper name */
358 dev_set_name(&rdev->wiphy.dev, PHY_NAME "%d", rdev->wiphy_idx); 362 dev_set_name(&rdev->wiphy.dev, "%s", nname);
363
364 mutex_unlock(&cfg80211_mutex);
359 365
360 mutex_init(&rdev->mtx); 366 mutex_init(&rdev->mtx);
361 mutex_init(&rdev->devlist_mtx); 367 mutex_init(&rdev->devlist_mtx);
diff --git a/net/wireless/core.h b/net/wireless/core.h
index 5d89310b358..6583cca0e2e 100644
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
@@ -375,7 +375,7 @@ bool cfg80211_sme_failed_reassoc(struct wireless_dev *wdev);
375/* internal helpers */ 375/* internal helpers */
376int cfg80211_validate_key_settings(struct cfg80211_registered_device *rdev, 376int cfg80211_validate_key_settings(struct cfg80211_registered_device *rdev,
377 struct key_params *params, int key_idx, 377 struct key_params *params, int key_idx,
378 const u8 *mac_addr); 378 bool pairwise, const u8 *mac_addr);
379void __cfg80211_disconnected(struct net_device *dev, const u8 *ie, 379void __cfg80211_disconnected(struct net_device *dev, const u8 *ie,
380 size_t ie_len, u16 reason, bool from_ap); 380 size_t ie_len, u16 reason, bool from_ap);
381void cfg80211_sme_scan_done(struct net_device *dev); 381void cfg80211_sme_scan_done(struct net_device *dev);
diff --git a/net/wireless/ibss.c b/net/wireless/ibss.c
index 8cb6e08373b..f33fbb79437 100644
--- a/net/wireless/ibss.c
+++ b/net/wireless/ibss.c
@@ -160,7 +160,7 @@ static void __cfg80211_clear_ibss(struct net_device *dev, bool nowext)
160 */ 160 */
161 if (rdev->ops->del_key) 161 if (rdev->ops->del_key)
162 for (i = 0; i < 6; i++) 162 for (i = 0; i < 6; i++)
163 rdev->ops->del_key(wdev->wiphy, dev, i, NULL); 163 rdev->ops->del_key(wdev->wiphy, dev, i, false, NULL);
164 164
165 if (wdev->current_bss) { 165 if (wdev->current_bss) {
166 cfg80211_unhold_bss(wdev->current_bss); 166 cfg80211_unhold_bss(wdev->current_bss);
diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c
index 46f37116089..caf11a42750 100644
--- a/net/wireless/mlme.c
+++ b/net/wireless/mlme.c
@@ -876,21 +876,53 @@ int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev,
876 876
877 if (ieee80211_is_action(mgmt->frame_control) && 877 if (ieee80211_is_action(mgmt->frame_control) &&
878 mgmt->u.action.category != WLAN_CATEGORY_PUBLIC) { 878 mgmt->u.action.category != WLAN_CATEGORY_PUBLIC) {
879 /* Verify that we are associated with the destination AP */ 879 int err = 0;
880
880 wdev_lock(wdev); 881 wdev_lock(wdev);
881 882
882 if (!wdev->current_bss || 883 switch (wdev->iftype) {
883 memcmp(wdev->current_bss->pub.bssid, mgmt->bssid, 884 case NL80211_IFTYPE_ADHOC:
884 ETH_ALEN) != 0 || 885 case NL80211_IFTYPE_STATION:
885 ((wdev->iftype == NL80211_IFTYPE_STATION || 886 case NL80211_IFTYPE_P2P_CLIENT:
886 wdev->iftype == NL80211_IFTYPE_P2P_CLIENT) && 887 if (!wdev->current_bss) {
887 memcmp(wdev->current_bss->pub.bssid, mgmt->da, 888 err = -ENOTCONN;
888 ETH_ALEN) != 0)) { 889 break;
889 wdev_unlock(wdev); 890 }
890 return -ENOTCONN; 891
891 } 892 if (memcmp(wdev->current_bss->pub.bssid,
893 mgmt->bssid, ETH_ALEN)) {
894 err = -ENOTCONN;
895 break;
896 }
897
898 /*
899 * check for IBSS DA must be done by driver as
900 * cfg80211 doesn't track the stations
901 */
902 if (wdev->iftype == NL80211_IFTYPE_ADHOC)
903 break;
892 904
905 /* for station, check that DA is the AP */
906 if (memcmp(wdev->current_bss->pub.bssid,
907 mgmt->da, ETH_ALEN)) {
908 err = -ENOTCONN;
909 break;
910 }
911 break;
912 case NL80211_IFTYPE_AP:
913 case NL80211_IFTYPE_P2P_GO:
914 case NL80211_IFTYPE_AP_VLAN:
915 if (memcmp(mgmt->bssid, dev->dev_addr, ETH_ALEN))
916 err = -EINVAL;
917 break;
918 default:
919 err = -EOPNOTSUPP;
920 break;
921 }
893 wdev_unlock(wdev); 922 wdev_unlock(wdev);
923
924 if (err)
925 return err;
894 } 926 }
895 927
896 if (memcmp(mgmt->sa, dev->dev_addr, ETH_ALEN) != 0) 928 if (memcmp(mgmt->sa, dev->dev_addr, ETH_ALEN) != 0)
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 9c84825803c..882dc921103 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -23,6 +23,11 @@
23#include "nl80211.h" 23#include "nl80211.h"
24#include "reg.h" 24#include "reg.h"
25 25
26static int nl80211_pre_doit(struct genl_ops *ops, struct sk_buff *skb,
27 struct genl_info *info);
28static void nl80211_post_doit(struct genl_ops *ops, struct sk_buff *skb,
29 struct genl_info *info);
30
26/* the netlink family */ 31/* the netlink family */
27static struct genl_family nl80211_fam = { 32static struct genl_family nl80211_fam = {
28 .id = GENL_ID_GENERATE, /* don't bother with a hardcoded ID */ 33 .id = GENL_ID_GENERATE, /* don't bother with a hardcoded ID */
@@ -31,6 +36,8 @@ static struct genl_family nl80211_fam = {
31 .version = 1, /* no particular meaning now */ 36 .version = 1, /* no particular meaning now */
32 .maxattr = NL80211_ATTR_MAX, 37 .maxattr = NL80211_ATTR_MAX,
33 .netnsok = true, 38 .netnsok = true,
39 .pre_doit = nl80211_pre_doit,
40 .post_doit = nl80211_post_doit,
34}; 41};
35 42
36/* internal helper: get rdev and dev */ 43/* internal helper: get rdev and dev */
@@ -86,6 +93,7 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = {
86 [NL80211_ATTR_KEY_CIPHER] = { .type = NLA_U32 }, 93 [NL80211_ATTR_KEY_CIPHER] = { .type = NLA_U32 },
87 [NL80211_ATTR_KEY_DEFAULT] = { .type = NLA_FLAG }, 94 [NL80211_ATTR_KEY_DEFAULT] = { .type = NLA_FLAG },
88 [NL80211_ATTR_KEY_SEQ] = { .type = NLA_BINARY, .len = 8 }, 95 [NL80211_ATTR_KEY_SEQ] = { .type = NLA_BINARY, .len = 8 },
96 [NL80211_ATTR_KEY_TYPE] = { .type = NLA_U32 },
89 97
90 [NL80211_ATTR_BEACON_INTERVAL] = { .type = NLA_U32 }, 98 [NL80211_ATTR_BEACON_INTERVAL] = { .type = NLA_U32 },
91 [NL80211_ATTR_DTIM_PERIOD] = { .type = NLA_U32 }, 99 [NL80211_ATTR_DTIM_PERIOD] = { .type = NLA_U32 },
@@ -161,7 +169,7 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = {
161 [NL80211_ATTR_FRAME_TYPE] = { .type = NLA_U16 }, 169 [NL80211_ATTR_FRAME_TYPE] = { .type = NLA_U16 },
162}; 170};
163 171
164/* policy for the attributes */ 172/* policy for the key attributes */
165static const struct nla_policy nl80211_key_policy[NL80211_KEY_MAX + 1] = { 173static const struct nla_policy nl80211_key_policy[NL80211_KEY_MAX + 1] = {
166 [NL80211_KEY_DATA] = { .type = NLA_BINARY, .len = WLAN_MAX_KEY_LEN }, 174 [NL80211_KEY_DATA] = { .type = NLA_BINARY, .len = WLAN_MAX_KEY_LEN },
167 [NL80211_KEY_IDX] = { .type = NLA_U8 }, 175 [NL80211_KEY_IDX] = { .type = NLA_U8 },
@@ -169,6 +177,7 @@ static const struct nla_policy nl80211_key_policy[NL80211_KEY_MAX + 1] = {
169 [NL80211_KEY_SEQ] = { .type = NLA_BINARY, .len = 8 }, 177 [NL80211_KEY_SEQ] = { .type = NLA_BINARY, .len = 8 },
170 [NL80211_KEY_DEFAULT] = { .type = NLA_FLAG }, 178 [NL80211_KEY_DEFAULT] = { .type = NLA_FLAG },
171 [NL80211_KEY_DEFAULT_MGMT] = { .type = NLA_FLAG }, 179 [NL80211_KEY_DEFAULT_MGMT] = { .type = NLA_FLAG },
180 [NL80211_KEY_TYPE] = { .type = NLA_U32 },
172}; 181};
173 182
174/* ifidx get helper */ 183/* ifidx get helper */
@@ -191,6 +200,47 @@ static int nl80211_get_ifidx(struct netlink_callback *cb)
191 return res; 200 return res;
192} 201}
193 202
203static int nl80211_prepare_netdev_dump(struct sk_buff *skb,
204 struct netlink_callback *cb,
205 struct cfg80211_registered_device **rdev,
206 struct net_device **dev)
207{
208 int ifidx = cb->args[0];
209 int err;
210
211 if (!ifidx)
212 ifidx = nl80211_get_ifidx(cb);
213 if (ifidx < 0)
214 return ifidx;
215
216 cb->args[0] = ifidx;
217
218 rtnl_lock();
219
220 *dev = __dev_get_by_index(sock_net(skb->sk), ifidx);
221 if (!*dev) {
222 err = -ENODEV;
223 goto out_rtnl;
224 }
225
226 *rdev = cfg80211_get_dev_from_ifindex(sock_net(skb->sk), ifidx);
227 if (IS_ERR(dev)) {
228 err = PTR_ERR(dev);
229 goto out_rtnl;
230 }
231
232 return 0;
233 out_rtnl:
234 rtnl_unlock();
235 return err;
236}
237
238static void nl80211_finish_netdev_dump(struct cfg80211_registered_device *rdev)
239{
240 cfg80211_unlock_rdev(rdev);
241 rtnl_unlock();
242}
243
194/* IE validation */ 244/* IE validation */
195static bool is_valid_ie_attr(const struct nlattr *attr) 245static bool is_valid_ie_attr(const struct nlattr *attr)
196{ 246{
@@ -258,6 +308,7 @@ static int nl80211_msg_put_channel(struct sk_buff *msg,
258struct key_parse { 308struct key_parse {
259 struct key_params p; 309 struct key_params p;
260 int idx; 310 int idx;
311 int type;
261 bool def, defmgmt; 312 bool def, defmgmt;
262}; 313};
263 314
@@ -288,6 +339,12 @@ static int nl80211_parse_key_new(struct nlattr *key, struct key_parse *k)
288 if (tb[NL80211_KEY_CIPHER]) 339 if (tb[NL80211_KEY_CIPHER])
289 k->p.cipher = nla_get_u32(tb[NL80211_KEY_CIPHER]); 340 k->p.cipher = nla_get_u32(tb[NL80211_KEY_CIPHER]);
290 341
342 if (tb[NL80211_KEY_TYPE]) {
343 k->type = nla_get_u32(tb[NL80211_KEY_TYPE]);
344 if (k->type < 0 || k->type >= NUM_NL80211_KEYTYPES)
345 return -EINVAL;
346 }
347
291 return 0; 348 return 0;
292} 349}
293 350
@@ -312,6 +369,12 @@ static int nl80211_parse_key_old(struct genl_info *info, struct key_parse *k)
312 k->def = !!info->attrs[NL80211_ATTR_KEY_DEFAULT]; 369 k->def = !!info->attrs[NL80211_ATTR_KEY_DEFAULT];
313 k->defmgmt = !!info->attrs[NL80211_ATTR_KEY_DEFAULT_MGMT]; 370 k->defmgmt = !!info->attrs[NL80211_ATTR_KEY_DEFAULT_MGMT];
314 371
372 if (info->attrs[NL80211_ATTR_KEY_TYPE]) {
373 k->type = nla_get_u32(info->attrs[NL80211_ATTR_KEY_TYPE]);
374 if (k->type < 0 || k->type >= NUM_NL80211_KEYTYPES)
375 return -EINVAL;
376 }
377
315 return 0; 378 return 0;
316} 379}
317 380
@@ -321,6 +384,7 @@ static int nl80211_parse_key(struct genl_info *info, struct key_parse *k)
321 384
322 memset(k, 0, sizeof(*k)); 385 memset(k, 0, sizeof(*k));
323 k->idx = -1; 386 k->idx = -1;
387 k->type = -1;
324 388
325 if (info->attrs[NL80211_ATTR_KEY]) 389 if (info->attrs[NL80211_ATTR_KEY])
326 err = nl80211_parse_key_new(info->attrs[NL80211_ATTR_KEY], k); 390 err = nl80211_parse_key_new(info->attrs[NL80211_ATTR_KEY], k);
@@ -385,7 +449,7 @@ nl80211_parse_connkeys(struct cfg80211_registered_device *rdev,
385 } else if (parse.defmgmt) 449 } else if (parse.defmgmt)
386 goto error; 450 goto error;
387 err = cfg80211_validate_key_settings(rdev, &parse.p, 451 err = cfg80211_validate_key_settings(rdev, &parse.p,
388 parse.idx, NULL); 452 parse.idx, false, NULL);
389 if (err) 453 if (err)
390 goto error; 454 goto error;
391 result->params[parse.idx].cipher = parse.p.cipher; 455 result->params[parse.idx].cipher = parse.p.cipher;
@@ -404,9 +468,6 @@ static int nl80211_key_allowed(struct wireless_dev *wdev)
404{ 468{
405 ASSERT_WDEV_LOCK(wdev); 469 ASSERT_WDEV_LOCK(wdev);
406 470
407 if (!netif_running(wdev->netdev))
408 return -ENETDOWN;
409
410 switch (wdev->iftype) { 471 switch (wdev->iftype) {
411 case NL80211_IFTYPE_AP: 472 case NL80211_IFTYPE_AP:
412 case NL80211_IFTYPE_AP_VLAN: 473 case NL80211_IFTYPE_AP_VLAN:
@@ -471,6 +532,9 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
471 NLA_PUT_U16(msg, NL80211_ATTR_MAX_SCAN_IE_LEN, 532 NLA_PUT_U16(msg, NL80211_ATTR_MAX_SCAN_IE_LEN,
472 dev->wiphy.max_scan_ie_len); 533 dev->wiphy.max_scan_ie_len);
473 534
535 if (dev->wiphy.flags & WIPHY_FLAG_IBSS_RSN)
536 NLA_PUT_FLAG(msg, NL80211_ATTR_SUPPORT_IBSS_RSN);
537
474 NLA_PUT(msg, NL80211_ATTR_CIPHER_SUITES, 538 NLA_PUT(msg, NL80211_ATTR_CIPHER_SUITES,
475 sizeof(u32) * dev->wiphy.n_cipher_suites, 539 sizeof(u32) * dev->wiphy.n_cipher_suites,
476 dev->wiphy.cipher_suites); 540 dev->wiphy.cipher_suites);
@@ -603,6 +667,7 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
603 NLA_PUT_U32(msg, i, NL80211_CMD_SET_WIPHY_NETNS); 667 NLA_PUT_U32(msg, i, NL80211_CMD_SET_WIPHY_NETNS);
604 } 668 }
605 CMD(set_channel, SET_CHANNEL); 669 CMD(set_channel, SET_CHANNEL);
670 CMD(set_wds_peer, SET_WDS_PEER);
606 671
607#undef CMD 672#undef CMD
608 673
@@ -703,28 +768,18 @@ static int nl80211_dump_wiphy(struct sk_buff *skb, struct netlink_callback *cb)
703static int nl80211_get_wiphy(struct sk_buff *skb, struct genl_info *info) 768static int nl80211_get_wiphy(struct sk_buff *skb, struct genl_info *info)
704{ 769{
705 struct sk_buff *msg; 770 struct sk_buff *msg;
706 struct cfg80211_registered_device *dev; 771 struct cfg80211_registered_device *dev = info->user_ptr[0];
707
708 dev = cfg80211_get_dev_from_info(info);
709 if (IS_ERR(dev))
710 return PTR_ERR(dev);
711 772
712 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 773 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
713 if (!msg) 774 if (!msg)
714 goto out_err; 775 return -ENOMEM;
715
716 if (nl80211_send_wiphy(msg, info->snd_pid, info->snd_seq, 0, dev) < 0)
717 goto out_free;
718 776
719 cfg80211_unlock_rdev(dev); 777 if (nl80211_send_wiphy(msg, info->snd_pid, info->snd_seq, 0, dev) < 0) {
778 nlmsg_free(msg);
779 return -ENOBUFS;
780 }
720 781
721 return genlmsg_reply(msg, info); 782 return genlmsg_reply(msg, info);
722
723 out_free:
724 nlmsg_free(msg);
725 out_err:
726 cfg80211_unlock_rdev(dev);
727 return -ENOBUFS;
728} 783}
729 784
730static const struct nla_policy txq_params_policy[NL80211_TXQ_ATTR_MAX + 1] = { 785static const struct nla_policy txq_params_policy[NL80211_TXQ_ATTR_MAX + 1] = {
@@ -813,24 +868,36 @@ static int __nl80211_set_channel(struct cfg80211_registered_device *rdev,
813 868
814static int nl80211_set_channel(struct sk_buff *skb, struct genl_info *info) 869static int nl80211_set_channel(struct sk_buff *skb, struct genl_info *info)
815{ 870{
816 struct cfg80211_registered_device *rdev; 871 struct cfg80211_registered_device *rdev = info->user_ptr[0];
817 struct net_device *netdev; 872 struct net_device *netdev = info->user_ptr[1];
818 int result;
819 873
820 rtnl_lock(); 874 return __nl80211_set_channel(rdev, netdev->ieee80211_ptr, info);
875}
821 876
822 result = get_rdev_dev_by_info_ifindex(info, &rdev, &netdev); 877static int nl80211_set_wds_peer(struct sk_buff *skb, struct genl_info *info)
823 if (result) 878{
824 goto unlock; 879 struct cfg80211_registered_device *rdev = info->user_ptr[0];
880 struct net_device *dev = info->user_ptr[1];
881 struct wireless_dev *wdev = dev->ieee80211_ptr;
882 const u8 *bssid;
825 883
826 result = __nl80211_set_channel(rdev, netdev->ieee80211_ptr, info); 884 if (!info->attrs[NL80211_ATTR_MAC])
885 return -EINVAL;
827 886
828 unlock: 887 if (netif_running(dev))
829 rtnl_unlock(); 888 return -EBUSY;
830 889
831 return result; 890 if (!rdev->ops->set_wds_peer)
891 return -EOPNOTSUPP;
892
893 if (wdev->iftype != NL80211_IFTYPE_WDS)
894 return -EOPNOTSUPP;
895
896 bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
897 return rdev->ops->set_wds_peer(wdev->wiphy, dev, bssid);
832} 898}
833 899
900
834static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info) 901static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
835{ 902{
836 struct cfg80211_registered_device *rdev; 903 struct cfg80211_registered_device *rdev;
@@ -843,8 +910,6 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
843 u32 frag_threshold = 0, rts_threshold = 0; 910 u32 frag_threshold = 0, rts_threshold = 0;
844 u8 coverage_class = 0; 911 u8 coverage_class = 0;
845 912
846 rtnl_lock();
847
848 /* 913 /*
849 * Try to find the wiphy and netdev. Normally this 914 * Try to find the wiphy and netdev. Normally this
850 * function shouldn't need the netdev, but this is 915 * function shouldn't need the netdev, but this is
@@ -871,8 +936,7 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
871 rdev = __cfg80211_rdev_from_info(info); 936 rdev = __cfg80211_rdev_from_info(info);
872 if (IS_ERR(rdev)) { 937 if (IS_ERR(rdev)) {
873 mutex_unlock(&cfg80211_mutex); 938 mutex_unlock(&cfg80211_mutex);
874 result = PTR_ERR(rdev); 939 return PTR_ERR(rdev);
875 goto unlock;
876 } 940 }
877 wdev = NULL; 941 wdev = NULL;
878 netdev = NULL; 942 netdev = NULL;
@@ -1054,8 +1118,6 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
1054 mutex_unlock(&rdev->mtx); 1118 mutex_unlock(&rdev->mtx);
1055 if (netdev) 1119 if (netdev)
1056 dev_put(netdev); 1120 dev_put(netdev);
1057 unlock:
1058 rtnl_unlock();
1059 return result; 1121 return result;
1060} 1122}
1061 1123
@@ -1135,33 +1197,20 @@ static int nl80211_dump_interface(struct sk_buff *skb, struct netlink_callback *
1135static int nl80211_get_interface(struct sk_buff *skb, struct genl_info *info) 1197static int nl80211_get_interface(struct sk_buff *skb, struct genl_info *info)
1136{ 1198{
1137 struct sk_buff *msg; 1199 struct sk_buff *msg;
1138 struct cfg80211_registered_device *dev; 1200 struct cfg80211_registered_device *dev = info->user_ptr[0];
1139 struct net_device *netdev; 1201 struct net_device *netdev = info->user_ptr[1];
1140 int err;
1141
1142 err = get_rdev_dev_by_info_ifindex(info, &dev, &netdev);
1143 if (err)
1144 return err;
1145 1202
1146 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 1203 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
1147 if (!msg) 1204 if (!msg)
1148 goto out_err; 1205 return -ENOMEM;
1149 1206
1150 if (nl80211_send_iface(msg, info->snd_pid, info->snd_seq, 0, 1207 if (nl80211_send_iface(msg, info->snd_pid, info->snd_seq, 0,
1151 dev, netdev) < 0) 1208 dev, netdev) < 0) {
1152 goto out_free; 1209 nlmsg_free(msg);
1153 1210 return -ENOBUFS;
1154 dev_put(netdev); 1211 }
1155 cfg80211_unlock_rdev(dev);
1156 1212
1157 return genlmsg_reply(msg, info); 1213 return genlmsg_reply(msg, info);
1158
1159 out_free:
1160 nlmsg_free(msg);
1161 out_err:
1162 dev_put(netdev);
1163 cfg80211_unlock_rdev(dev);
1164 return -ENOBUFS;
1165} 1214}
1166 1215
1167static const struct nla_policy mntr_flags_policy[NL80211_MNTR_FLAG_MAX + 1] = { 1216static const struct nla_policy mntr_flags_policy[NL80211_MNTR_FLAG_MAX + 1] = {
@@ -1221,39 +1270,29 @@ static int nl80211_valid_4addr(struct cfg80211_registered_device *rdev,
1221 1270
1222static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info) 1271static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info)
1223{ 1272{
1224 struct cfg80211_registered_device *rdev; 1273 struct cfg80211_registered_device *rdev = info->user_ptr[0];
1225 struct vif_params params; 1274 struct vif_params params;
1226 int err; 1275 int err;
1227 enum nl80211_iftype otype, ntype; 1276 enum nl80211_iftype otype, ntype;
1228 struct net_device *dev; 1277 struct net_device *dev = info->user_ptr[1];
1229 u32 _flags, *flags = NULL; 1278 u32 _flags, *flags = NULL;
1230 bool change = false; 1279 bool change = false;
1231 1280
1232 memset(&params, 0, sizeof(params)); 1281 memset(&params, 0, sizeof(params));
1233 1282
1234 rtnl_lock();
1235
1236 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
1237 if (err)
1238 goto unlock_rtnl;
1239
1240 otype = ntype = dev->ieee80211_ptr->iftype; 1283 otype = ntype = dev->ieee80211_ptr->iftype;
1241 1284
1242 if (info->attrs[NL80211_ATTR_IFTYPE]) { 1285 if (info->attrs[NL80211_ATTR_IFTYPE]) {
1243 ntype = nla_get_u32(info->attrs[NL80211_ATTR_IFTYPE]); 1286 ntype = nla_get_u32(info->attrs[NL80211_ATTR_IFTYPE]);
1244 if (otype != ntype) 1287 if (otype != ntype)
1245 change = true; 1288 change = true;
1246 if (ntype > NL80211_IFTYPE_MAX) { 1289 if (ntype > NL80211_IFTYPE_MAX)
1247 err = -EINVAL; 1290 return -EINVAL;
1248 goto unlock;
1249 }
1250 } 1291 }
1251 1292
1252 if (info->attrs[NL80211_ATTR_MESH_ID]) { 1293 if (info->attrs[NL80211_ATTR_MESH_ID]) {
1253 if (ntype != NL80211_IFTYPE_MESH_POINT) { 1294 if (ntype != NL80211_IFTYPE_MESH_POINT)
1254 err = -EINVAL; 1295 return -EINVAL;
1255 goto unlock;
1256 }
1257 params.mesh_id = nla_data(info->attrs[NL80211_ATTR_MESH_ID]); 1296 params.mesh_id = nla_data(info->attrs[NL80211_ATTR_MESH_ID]);
1258 params.mesh_id_len = nla_len(info->attrs[NL80211_ATTR_MESH_ID]); 1297 params.mesh_id_len = nla_len(info->attrs[NL80211_ATTR_MESH_ID]);
1259 change = true; 1298 change = true;
@@ -1264,20 +1303,18 @@ static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info)
1264 change = true; 1303 change = true;
1265 err = nl80211_valid_4addr(rdev, dev, params.use_4addr, ntype); 1304 err = nl80211_valid_4addr(rdev, dev, params.use_4addr, ntype);
1266 if (err) 1305 if (err)
1267 goto unlock; 1306 return err;
1268 } else { 1307 } else {
1269 params.use_4addr = -1; 1308 params.use_4addr = -1;
1270 } 1309 }
1271 1310
1272 if (info->attrs[NL80211_ATTR_MNTR_FLAGS]) { 1311 if (info->attrs[NL80211_ATTR_MNTR_FLAGS]) {
1273 if (ntype != NL80211_IFTYPE_MONITOR) { 1312 if (ntype != NL80211_IFTYPE_MONITOR)
1274 err = -EINVAL; 1313 return -EINVAL;
1275 goto unlock;
1276 }
1277 err = parse_monitor_flags(info->attrs[NL80211_ATTR_MNTR_FLAGS], 1314 err = parse_monitor_flags(info->attrs[NL80211_ATTR_MNTR_FLAGS],
1278 &_flags); 1315 &_flags);
1279 if (err) 1316 if (err)
1280 goto unlock; 1317 return err;
1281 1318
1282 flags = &_flags; 1319 flags = &_flags;
1283 change = true; 1320 change = true;
@@ -1291,17 +1328,12 @@ static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info)
1291 if (!err && params.use_4addr != -1) 1328 if (!err && params.use_4addr != -1)
1292 dev->ieee80211_ptr->use_4addr = params.use_4addr; 1329 dev->ieee80211_ptr->use_4addr = params.use_4addr;
1293 1330
1294 unlock:
1295 dev_put(dev);
1296 cfg80211_unlock_rdev(rdev);
1297 unlock_rtnl:
1298 rtnl_unlock();
1299 return err; 1331 return err;
1300} 1332}
1301 1333
1302static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info) 1334static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info)
1303{ 1335{
1304 struct cfg80211_registered_device *rdev; 1336 struct cfg80211_registered_device *rdev = info->user_ptr[0];
1305 struct vif_params params; 1337 struct vif_params params;
1306 int err; 1338 int err;
1307 enum nl80211_iftype type = NL80211_IFTYPE_UNSPECIFIED; 1339 enum nl80211_iftype type = NL80211_IFTYPE_UNSPECIFIED;
@@ -1318,19 +1350,9 @@ static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info)
1318 return -EINVAL; 1350 return -EINVAL;
1319 } 1351 }
1320 1352
1321 rtnl_lock();
1322
1323 rdev = cfg80211_get_dev_from_info(info);
1324 if (IS_ERR(rdev)) {
1325 err = PTR_ERR(rdev);
1326 goto unlock_rtnl;
1327 }
1328
1329 if (!rdev->ops->add_virtual_intf || 1353 if (!rdev->ops->add_virtual_intf ||
1330 !(rdev->wiphy.interface_modes & (1 << type))) { 1354 !(rdev->wiphy.interface_modes & (1 << type)))
1331 err = -EOPNOTSUPP; 1355 return -EOPNOTSUPP;
1332 goto unlock;
1333 }
1334 1356
1335 if (type == NL80211_IFTYPE_MESH_POINT && 1357 if (type == NL80211_IFTYPE_MESH_POINT &&
1336 info->attrs[NL80211_ATTR_MESH_ID]) { 1358 info->attrs[NL80211_ATTR_MESH_ID]) {
@@ -1342,7 +1364,7 @@ static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info)
1342 params.use_4addr = !!nla_get_u8(info->attrs[NL80211_ATTR_4ADDR]); 1364 params.use_4addr = !!nla_get_u8(info->attrs[NL80211_ATTR_4ADDR]);
1343 err = nl80211_valid_4addr(rdev, NULL, params.use_4addr, type); 1365 err = nl80211_valid_4addr(rdev, NULL, params.use_4addr, type);
1344 if (err) 1366 if (err)
1345 goto unlock; 1367 return err;
1346 } 1368 }
1347 1369
1348 err = parse_monitor_flags(type == NL80211_IFTYPE_MONITOR ? 1370 err = parse_monitor_flags(type == NL80211_IFTYPE_MONITOR ?
@@ -1352,38 +1374,18 @@ static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info)
1352 nla_data(info->attrs[NL80211_ATTR_IFNAME]), 1374 nla_data(info->attrs[NL80211_ATTR_IFNAME]),
1353 type, err ? NULL : &flags, &params); 1375 type, err ? NULL : &flags, &params);
1354 1376
1355 unlock:
1356 cfg80211_unlock_rdev(rdev);
1357 unlock_rtnl:
1358 rtnl_unlock();
1359 return err; 1377 return err;
1360} 1378}
1361 1379
1362static int nl80211_del_interface(struct sk_buff *skb, struct genl_info *info) 1380static int nl80211_del_interface(struct sk_buff *skb, struct genl_info *info)
1363{ 1381{
1364 struct cfg80211_registered_device *rdev; 1382 struct cfg80211_registered_device *rdev = info->user_ptr[0];
1365 int err; 1383 struct net_device *dev = info->user_ptr[1];
1366 struct net_device *dev;
1367
1368 rtnl_lock();
1369
1370 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
1371 if (err)
1372 goto unlock_rtnl;
1373 1384
1374 if (!rdev->ops->del_virtual_intf) { 1385 if (!rdev->ops->del_virtual_intf)
1375 err = -EOPNOTSUPP; 1386 return -EOPNOTSUPP;
1376 goto out;
1377 }
1378
1379 err = rdev->ops->del_virtual_intf(&rdev->wiphy, dev);
1380 1387
1381 out: 1388 return rdev->ops->del_virtual_intf(&rdev->wiphy, dev);
1382 cfg80211_unlock_rdev(rdev);
1383 dev_put(dev);
1384 unlock_rtnl:
1385 rtnl_unlock();
1386 return err;
1387} 1389}
1388 1390
1389struct get_key_cookie { 1391struct get_key_cookie {
@@ -1436,11 +1438,12 @@ static void get_key_callback(void *c, struct key_params *params)
1436 1438
1437static int nl80211_get_key(struct sk_buff *skb, struct genl_info *info) 1439static int nl80211_get_key(struct sk_buff *skb, struct genl_info *info)
1438{ 1440{
1439 struct cfg80211_registered_device *rdev; 1441 struct cfg80211_registered_device *rdev = info->user_ptr[0];
1440 int err; 1442 int err;
1441 struct net_device *dev; 1443 struct net_device *dev = info->user_ptr[1];
1442 u8 key_idx = 0; 1444 u8 key_idx = 0;
1443 u8 *mac_addr = NULL; 1445 const u8 *mac_addr = NULL;
1446 bool pairwise;
1444 struct get_key_cookie cookie = { 1447 struct get_key_cookie cookie = {
1445 .error = 0, 1448 .error = 0,
1446 }; 1449 };
@@ -1456,30 +1459,28 @@ static int nl80211_get_key(struct sk_buff *skb, struct genl_info *info)
1456 if (info->attrs[NL80211_ATTR_MAC]) 1459 if (info->attrs[NL80211_ATTR_MAC])
1457 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]); 1460 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
1458 1461
1459 rtnl_lock(); 1462 pairwise = !!mac_addr;
1460 1463 if (info->attrs[NL80211_ATTR_KEY_TYPE]) {
1461 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev); 1464 u32 kt = nla_get_u32(info->attrs[NL80211_ATTR_KEY_TYPE]);
1462 if (err) 1465 if (kt >= NUM_NL80211_KEYTYPES)
1463 goto unlock_rtnl; 1466 return -EINVAL;
1464 1467 if (kt != NL80211_KEYTYPE_GROUP &&
1465 if (!rdev->ops->get_key) { 1468 kt != NL80211_KEYTYPE_PAIRWISE)
1466 err = -EOPNOTSUPP; 1469 return -EINVAL;
1467 goto out; 1470 pairwise = kt == NL80211_KEYTYPE_PAIRWISE;
1468 } 1471 }
1469 1472
1473 if (!rdev->ops->get_key)
1474 return -EOPNOTSUPP;
1475
1470 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 1476 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
1471 if (!msg) { 1477 if (!msg)
1472 err = -ENOMEM; 1478 return -ENOMEM;
1473 goto out;
1474 }
1475 1479
1476 hdr = nl80211hdr_put(msg, info->snd_pid, info->snd_seq, 0, 1480 hdr = nl80211hdr_put(msg, info->snd_pid, info->snd_seq, 0,
1477 NL80211_CMD_NEW_KEY); 1481 NL80211_CMD_NEW_KEY);
1478 1482 if (IS_ERR(hdr))
1479 if (IS_ERR(hdr)) { 1483 return PTR_ERR(hdr);
1480 err = PTR_ERR(hdr);
1481 goto free_msg;
1482 }
1483 1484
1484 cookie.msg = msg; 1485 cookie.msg = msg;
1485 cookie.idx = key_idx; 1486 cookie.idx = key_idx;
@@ -1489,8 +1490,12 @@ static int nl80211_get_key(struct sk_buff *skb, struct genl_info *info)
1489 if (mac_addr) 1490 if (mac_addr)
1490 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr); 1491 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr);
1491 1492
1492 err = rdev->ops->get_key(&rdev->wiphy, dev, key_idx, mac_addr, 1493 if (pairwise && mac_addr &&
1493 &cookie, get_key_callback); 1494 !(rdev->wiphy.flags & WIPHY_FLAG_IBSS_RSN))
1495 return -ENOENT;
1496
1497 err = rdev->ops->get_key(&rdev->wiphy, dev, key_idx, pairwise,
1498 mac_addr, &cookie, get_key_callback);
1494 1499
1495 if (err) 1500 if (err)
1496 goto free_msg; 1501 goto free_msg;
@@ -1499,28 +1504,21 @@ static int nl80211_get_key(struct sk_buff *skb, struct genl_info *info)
1499 goto nla_put_failure; 1504 goto nla_put_failure;
1500 1505
1501 genlmsg_end(msg, hdr); 1506 genlmsg_end(msg, hdr);
1502 err = genlmsg_reply(msg, info); 1507 return genlmsg_reply(msg, info);
1503 goto out;
1504 1508
1505 nla_put_failure: 1509 nla_put_failure:
1506 err = -ENOBUFS; 1510 err = -ENOBUFS;
1507 free_msg: 1511 free_msg:
1508 nlmsg_free(msg); 1512 nlmsg_free(msg);
1509 out:
1510 cfg80211_unlock_rdev(rdev);
1511 dev_put(dev);
1512 unlock_rtnl:
1513 rtnl_unlock();
1514
1515 return err; 1513 return err;
1516} 1514}
1517 1515
1518static int nl80211_set_key(struct sk_buff *skb, struct genl_info *info) 1516static int nl80211_set_key(struct sk_buff *skb, struct genl_info *info)
1519{ 1517{
1520 struct cfg80211_registered_device *rdev; 1518 struct cfg80211_registered_device *rdev = info->user_ptr[0];
1521 struct key_parse key; 1519 struct key_parse key;
1522 int err; 1520 int err;
1523 struct net_device *dev; 1521 struct net_device *dev = info->user_ptr[1];
1524 int (*func)(struct wiphy *wiphy, struct net_device *netdev, 1522 int (*func)(struct wiphy *wiphy, struct net_device *netdev,
1525 u8 key_index); 1523 u8 key_index);
1526 1524
@@ -1535,21 +1533,13 @@ static int nl80211_set_key(struct sk_buff *skb, struct genl_info *info)
1535 if (!key.def && !key.defmgmt) 1533 if (!key.def && !key.defmgmt)
1536 return -EINVAL; 1534 return -EINVAL;
1537 1535
1538 rtnl_lock();
1539
1540 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
1541 if (err)
1542 goto unlock_rtnl;
1543
1544 if (key.def) 1536 if (key.def)
1545 func = rdev->ops->set_default_key; 1537 func = rdev->ops->set_default_key;
1546 else 1538 else
1547 func = rdev->ops->set_default_mgmt_key; 1539 func = rdev->ops->set_default_mgmt_key;
1548 1540
1549 if (!func) { 1541 if (!func)
1550 err = -EOPNOTSUPP; 1542 return -EOPNOTSUPP;
1551 goto out;
1552 }
1553 1543
1554 wdev_lock(dev->ieee80211_ptr); 1544 wdev_lock(dev->ieee80211_ptr);
1555 err = nl80211_key_allowed(dev->ieee80211_ptr); 1545 err = nl80211_key_allowed(dev->ieee80211_ptr);
@@ -1566,23 +1556,16 @@ static int nl80211_set_key(struct sk_buff *skb, struct genl_info *info)
1566#endif 1556#endif
1567 wdev_unlock(dev->ieee80211_ptr); 1557 wdev_unlock(dev->ieee80211_ptr);
1568 1558
1569 out:
1570 cfg80211_unlock_rdev(rdev);
1571 dev_put(dev);
1572
1573 unlock_rtnl:
1574 rtnl_unlock();
1575
1576 return err; 1559 return err;
1577} 1560}
1578 1561
1579static int nl80211_new_key(struct sk_buff *skb, struct genl_info *info) 1562static int nl80211_new_key(struct sk_buff *skb, struct genl_info *info)
1580{ 1563{
1581 struct cfg80211_registered_device *rdev; 1564 struct cfg80211_registered_device *rdev = info->user_ptr[0];
1582 int err; 1565 int err;
1583 struct net_device *dev; 1566 struct net_device *dev = info->user_ptr[1];
1584 struct key_parse key; 1567 struct key_parse key;
1585 u8 *mac_addr = NULL; 1568 const u8 *mac_addr = NULL;
1586 1569
1587 err = nl80211_parse_key(info, &key); 1570 err = nl80211_parse_key(info, &key);
1588 if (err) 1571 if (err)
@@ -1594,43 +1577,42 @@ static int nl80211_new_key(struct sk_buff *skb, struct genl_info *info)
1594 if (info->attrs[NL80211_ATTR_MAC]) 1577 if (info->attrs[NL80211_ATTR_MAC])
1595 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]); 1578 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
1596 1579
1597 rtnl_lock(); 1580 if (key.type == -1) {
1581 if (mac_addr)
1582 key.type = NL80211_KEYTYPE_PAIRWISE;
1583 else
1584 key.type = NL80211_KEYTYPE_GROUP;
1585 }
1598 1586
1599 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev); 1587 /* for now */
1600 if (err) 1588 if (key.type != NL80211_KEYTYPE_PAIRWISE &&
1601 goto unlock_rtnl; 1589 key.type != NL80211_KEYTYPE_GROUP)
1590 return -EINVAL;
1602 1591
1603 if (!rdev->ops->add_key) { 1592 if (!rdev->ops->add_key)
1604 err = -EOPNOTSUPP; 1593 return -EOPNOTSUPP;
1605 goto out;
1606 }
1607 1594
1608 if (cfg80211_validate_key_settings(rdev, &key.p, key.idx, mac_addr)) { 1595 if (cfg80211_validate_key_settings(rdev, &key.p, key.idx,
1609 err = -EINVAL; 1596 key.type == NL80211_KEYTYPE_PAIRWISE,
1610 goto out; 1597 mac_addr))
1611 } 1598 return -EINVAL;
1612 1599
1613 wdev_lock(dev->ieee80211_ptr); 1600 wdev_lock(dev->ieee80211_ptr);
1614 err = nl80211_key_allowed(dev->ieee80211_ptr); 1601 err = nl80211_key_allowed(dev->ieee80211_ptr);
1615 if (!err) 1602 if (!err)
1616 err = rdev->ops->add_key(&rdev->wiphy, dev, key.idx, 1603 err = rdev->ops->add_key(&rdev->wiphy, dev, key.idx,
1604 key.type == NL80211_KEYTYPE_PAIRWISE,
1617 mac_addr, &key.p); 1605 mac_addr, &key.p);
1618 wdev_unlock(dev->ieee80211_ptr); 1606 wdev_unlock(dev->ieee80211_ptr);
1619 1607
1620 out:
1621 cfg80211_unlock_rdev(rdev);
1622 dev_put(dev);
1623 unlock_rtnl:
1624 rtnl_unlock();
1625
1626 return err; 1608 return err;
1627} 1609}
1628 1610
1629static int nl80211_del_key(struct sk_buff *skb, struct genl_info *info) 1611static int nl80211_del_key(struct sk_buff *skb, struct genl_info *info)
1630{ 1612{
1631 struct cfg80211_registered_device *rdev; 1613 struct cfg80211_registered_device *rdev = info->user_ptr[0];
1632 int err; 1614 int err;
1633 struct net_device *dev; 1615 struct net_device *dev = info->user_ptr[1];
1634 u8 *mac_addr = NULL; 1616 u8 *mac_addr = NULL;
1635 struct key_parse key; 1617 struct key_parse key;
1636 1618
@@ -1641,21 +1623,32 @@ static int nl80211_del_key(struct sk_buff *skb, struct genl_info *info)
1641 if (info->attrs[NL80211_ATTR_MAC]) 1623 if (info->attrs[NL80211_ATTR_MAC])
1642 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]); 1624 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
1643 1625
1644 rtnl_lock(); 1626 if (key.type == -1) {
1627 if (mac_addr)
1628 key.type = NL80211_KEYTYPE_PAIRWISE;
1629 else
1630 key.type = NL80211_KEYTYPE_GROUP;
1631 }
1645 1632
1646 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev); 1633 /* for now */
1647 if (err) 1634 if (key.type != NL80211_KEYTYPE_PAIRWISE &&
1648 goto unlock_rtnl; 1635 key.type != NL80211_KEYTYPE_GROUP)
1636 return -EINVAL;
1649 1637
1650 if (!rdev->ops->del_key) { 1638 if (!rdev->ops->del_key)
1651 err = -EOPNOTSUPP; 1639 return -EOPNOTSUPP;
1652 goto out;
1653 }
1654 1640
1655 wdev_lock(dev->ieee80211_ptr); 1641 wdev_lock(dev->ieee80211_ptr);
1656 err = nl80211_key_allowed(dev->ieee80211_ptr); 1642 err = nl80211_key_allowed(dev->ieee80211_ptr);
1643
1644 if (key.type == NL80211_KEYTYPE_PAIRWISE && mac_addr &&
1645 !(rdev->wiphy.flags & WIPHY_FLAG_IBSS_RSN))
1646 err = -ENOENT;
1647
1657 if (!err) 1648 if (!err)
1658 err = rdev->ops->del_key(&rdev->wiphy, dev, key.idx, mac_addr); 1649 err = rdev->ops->del_key(&rdev->wiphy, dev, key.idx,
1650 key.type == NL80211_KEYTYPE_PAIRWISE,
1651 mac_addr);
1659 1652
1660#ifdef CONFIG_CFG80211_WEXT 1653#ifdef CONFIG_CFG80211_WEXT
1661 if (!err) { 1654 if (!err) {
@@ -1667,13 +1660,6 @@ static int nl80211_del_key(struct sk_buff *skb, struct genl_info *info)
1667#endif 1660#endif
1668 wdev_unlock(dev->ieee80211_ptr); 1661 wdev_unlock(dev->ieee80211_ptr);
1669 1662
1670 out:
1671 cfg80211_unlock_rdev(rdev);
1672 dev_put(dev);
1673
1674 unlock_rtnl:
1675 rtnl_unlock();
1676
1677 return err; 1663 return err;
1678} 1664}
1679 1665
@@ -1681,36 +1667,25 @@ static int nl80211_addset_beacon(struct sk_buff *skb, struct genl_info *info)
1681{ 1667{
1682 int (*call)(struct wiphy *wiphy, struct net_device *dev, 1668 int (*call)(struct wiphy *wiphy, struct net_device *dev,
1683 struct beacon_parameters *info); 1669 struct beacon_parameters *info);
1684 struct cfg80211_registered_device *rdev; 1670 struct cfg80211_registered_device *rdev = info->user_ptr[0];
1685 int err; 1671 struct net_device *dev = info->user_ptr[1];
1686 struct net_device *dev;
1687 struct beacon_parameters params; 1672 struct beacon_parameters params;
1688 int haveinfo = 0; 1673 int haveinfo = 0;
1689 1674
1690 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_BEACON_TAIL])) 1675 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_BEACON_TAIL]))
1691 return -EINVAL; 1676 return -EINVAL;
1692 1677
1693 rtnl_lock();
1694
1695 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
1696 if (err)
1697 goto unlock_rtnl;
1698
1699 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP && 1678 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
1700 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) { 1679 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
1701 err = -EOPNOTSUPP; 1680 return -EOPNOTSUPP;
1702 goto out;
1703 }
1704 1681
1705 switch (info->genlhdr->cmd) { 1682 switch (info->genlhdr->cmd) {
1706 case NL80211_CMD_NEW_BEACON: 1683 case NL80211_CMD_NEW_BEACON:
1707 /* these are required for NEW_BEACON */ 1684 /* these are required for NEW_BEACON */
1708 if (!info->attrs[NL80211_ATTR_BEACON_INTERVAL] || 1685 if (!info->attrs[NL80211_ATTR_BEACON_INTERVAL] ||
1709 !info->attrs[NL80211_ATTR_DTIM_PERIOD] || 1686 !info->attrs[NL80211_ATTR_DTIM_PERIOD] ||
1710 !info->attrs[NL80211_ATTR_BEACON_HEAD]) { 1687 !info->attrs[NL80211_ATTR_BEACON_HEAD])
1711 err = -EINVAL; 1688 return -EINVAL;
1712 goto out;
1713 }
1714 1689
1715 call = rdev->ops->add_beacon; 1690 call = rdev->ops->add_beacon;
1716 break; 1691 break;
@@ -1719,14 +1694,11 @@ static int nl80211_addset_beacon(struct sk_buff *skb, struct genl_info *info)
1719 break; 1694 break;
1720 default: 1695 default:
1721 WARN_ON(1); 1696 WARN_ON(1);
1722 err = -EOPNOTSUPP; 1697 return -EOPNOTSUPP;
1723 goto out;
1724 } 1698 }
1725 1699
1726 if (!call) { 1700 if (!call)
1727 err = -EOPNOTSUPP; 1701 return -EOPNOTSUPP;
1728 goto out;
1729 }
1730 1702
1731 memset(&params, 0, sizeof(params)); 1703 memset(&params, 0, sizeof(params));
1732 1704
@@ -1756,53 +1728,25 @@ static int nl80211_addset_beacon(struct sk_buff *skb, struct genl_info *info)
1756 haveinfo = 1; 1728 haveinfo = 1;
1757 } 1729 }
1758 1730
1759 if (!haveinfo) { 1731 if (!haveinfo)
1760 err = -EINVAL; 1732 return -EINVAL;
1761 goto out;
1762 }
1763
1764 err = call(&rdev->wiphy, dev, &params);
1765
1766 out:
1767 cfg80211_unlock_rdev(rdev);
1768 dev_put(dev);
1769 unlock_rtnl:
1770 rtnl_unlock();
1771 1733
1772 return err; 1734 return call(&rdev->wiphy, dev, &params);
1773} 1735}
1774 1736
1775static int nl80211_del_beacon(struct sk_buff *skb, struct genl_info *info) 1737static int nl80211_del_beacon(struct sk_buff *skb, struct genl_info *info)
1776{ 1738{
1777 struct cfg80211_registered_device *rdev; 1739 struct cfg80211_registered_device *rdev = info->user_ptr[0];
1778 int err; 1740 struct net_device *dev = info->user_ptr[1];
1779 struct net_device *dev;
1780 1741
1781 rtnl_lock(); 1742 if (!rdev->ops->del_beacon)
1782 1743 return -EOPNOTSUPP;
1783 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
1784 if (err)
1785 goto unlock_rtnl;
1786
1787 if (!rdev->ops->del_beacon) {
1788 err = -EOPNOTSUPP;
1789 goto out;
1790 }
1791 1744
1792 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP && 1745 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
1793 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) { 1746 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
1794 err = -EOPNOTSUPP; 1747 return -EOPNOTSUPP;
1795 goto out;
1796 }
1797 err = rdev->ops->del_beacon(&rdev->wiphy, dev);
1798
1799 out:
1800 cfg80211_unlock_rdev(rdev);
1801 dev_put(dev);
1802 unlock_rtnl:
1803 rtnl_unlock();
1804 1748
1805 return err; 1749 return rdev->ops->del_beacon(&rdev->wiphy, dev);
1806} 1750}
1807 1751
1808static const struct nla_policy sta_flags_policy[NL80211_STA_FLAG_MAX + 1] = { 1752static const struct nla_policy sta_flags_policy[NL80211_STA_FLAG_MAX + 1] = {
@@ -1923,6 +1867,12 @@ static int nl80211_send_station(struct sk_buff *msg, u32 pid, u32 seq,
1923 if (sinfo->filled & STATION_INFO_TX_PACKETS) 1867 if (sinfo->filled & STATION_INFO_TX_PACKETS)
1924 NLA_PUT_U32(msg, NL80211_STA_INFO_TX_PACKETS, 1868 NLA_PUT_U32(msg, NL80211_STA_INFO_TX_PACKETS,
1925 sinfo->tx_packets); 1869 sinfo->tx_packets);
1870 if (sinfo->filled & STATION_INFO_TX_RETRIES)
1871 NLA_PUT_U32(msg, NL80211_STA_INFO_TX_RETRIES,
1872 sinfo->tx_retries);
1873 if (sinfo->filled & STATION_INFO_TX_FAILED)
1874 NLA_PUT_U32(msg, NL80211_STA_INFO_TX_FAILED,
1875 sinfo->tx_failed);
1926 nla_nest_end(msg, sinfoattr); 1876 nla_nest_end(msg, sinfoattr);
1927 1877
1928 return genlmsg_end(msg, hdr); 1878 return genlmsg_end(msg, hdr);
@@ -1939,28 +1889,12 @@ static int nl80211_dump_station(struct sk_buff *skb,
1939 struct cfg80211_registered_device *dev; 1889 struct cfg80211_registered_device *dev;
1940 struct net_device *netdev; 1890 struct net_device *netdev;
1941 u8 mac_addr[ETH_ALEN]; 1891 u8 mac_addr[ETH_ALEN];
1942 int ifidx = cb->args[0];
1943 int sta_idx = cb->args[1]; 1892 int sta_idx = cb->args[1];
1944 int err; 1893 int err;
1945 1894
1946 if (!ifidx) 1895 err = nl80211_prepare_netdev_dump(skb, cb, &dev, &netdev);
1947 ifidx = nl80211_get_ifidx(cb); 1896 if (err)
1948 if (ifidx < 0) 1897 return err;
1949 return ifidx;
1950
1951 rtnl_lock();
1952
1953 netdev = __dev_get_by_index(sock_net(skb->sk), ifidx);
1954 if (!netdev) {
1955 err = -ENODEV;
1956 goto out_rtnl;
1957 }
1958
1959 dev = cfg80211_get_dev_from_ifindex(sock_net(skb->sk), ifidx);
1960 if (IS_ERR(dev)) {
1961 err = PTR_ERR(dev);
1962 goto out_rtnl;
1963 }
1964 1898
1965 if (!dev->ops->dump_station) { 1899 if (!dev->ops->dump_station) {
1966 err = -EOPNOTSUPP; 1900 err = -EOPNOTSUPP;
@@ -1990,21 +1924,19 @@ static int nl80211_dump_station(struct sk_buff *skb,
1990 cb->args[1] = sta_idx; 1924 cb->args[1] = sta_idx;
1991 err = skb->len; 1925 err = skb->len;
1992 out_err: 1926 out_err:
1993 cfg80211_unlock_rdev(dev); 1927 nl80211_finish_netdev_dump(dev);
1994 out_rtnl:
1995 rtnl_unlock();
1996 1928
1997 return err; 1929 return err;
1998} 1930}
1999 1931
2000static int nl80211_get_station(struct sk_buff *skb, struct genl_info *info) 1932static int nl80211_get_station(struct sk_buff *skb, struct genl_info *info)
2001{ 1933{
2002 struct cfg80211_registered_device *rdev; 1934 struct cfg80211_registered_device *rdev = info->user_ptr[0];
2003 int err; 1935 struct net_device *dev = info->user_ptr[1];
2004 struct net_device *dev;
2005 struct station_info sinfo; 1936 struct station_info sinfo;
2006 struct sk_buff *msg; 1937 struct sk_buff *msg;
2007 u8 *mac_addr = NULL; 1938 u8 *mac_addr = NULL;
1939 int err;
2008 1940
2009 memset(&sinfo, 0, sizeof(sinfo)); 1941 memset(&sinfo, 0, sizeof(sinfo));
2010 1942
@@ -2013,41 +1945,24 @@ static int nl80211_get_station(struct sk_buff *skb, struct genl_info *info)
2013 1945
2014 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]); 1946 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
2015 1947
2016 rtnl_lock(); 1948 if (!rdev->ops->get_station)
2017 1949 return -EOPNOTSUPP;
2018 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
2019 if (err)
2020 goto out_rtnl;
2021
2022 if (!rdev->ops->get_station) {
2023 err = -EOPNOTSUPP;
2024 goto out;
2025 }
2026 1950
2027 err = rdev->ops->get_station(&rdev->wiphy, dev, mac_addr, &sinfo); 1951 err = rdev->ops->get_station(&rdev->wiphy, dev, mac_addr, &sinfo);
2028 if (err) 1952 if (err)
2029 goto out; 1953 return err;
2030 1954
2031 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 1955 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
2032 if (!msg) 1956 if (!msg)
2033 goto out; 1957 return -ENOMEM;
2034 1958
2035 if (nl80211_send_station(msg, info->snd_pid, info->snd_seq, 0, 1959 if (nl80211_send_station(msg, info->snd_pid, info->snd_seq, 0,
2036 dev, mac_addr, &sinfo) < 0) 1960 dev, mac_addr, &sinfo) < 0) {
2037 goto out_free; 1961 nlmsg_free(msg);
2038 1962 return -ENOBUFS;
2039 err = genlmsg_reply(msg, info); 1963 }
2040 goto out;
2041
2042 out_free:
2043 nlmsg_free(msg);
2044 out:
2045 cfg80211_unlock_rdev(rdev);
2046 dev_put(dev);
2047 out_rtnl:
2048 rtnl_unlock();
2049 1964
2050 return err; 1965 return genlmsg_reply(msg, info);
2051} 1966}
2052 1967
2053/* 1968/*
@@ -2077,9 +1992,9 @@ static int get_vlan(struct genl_info *info,
2077 1992
2078static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info) 1993static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info)
2079{ 1994{
2080 struct cfg80211_registered_device *rdev; 1995 struct cfg80211_registered_device *rdev = info->user_ptr[0];
2081 int err; 1996 int err;
2082 struct net_device *dev; 1997 struct net_device *dev = info->user_ptr[1];
2083 struct station_parameters params; 1998 struct station_parameters params;
2084 u8 *mac_addr = NULL; 1999 u8 *mac_addr = NULL;
2085 2000
@@ -2117,12 +2032,6 @@ static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info)
2117 params.plink_action = 2032 params.plink_action =
2118 nla_get_u8(info->attrs[NL80211_ATTR_STA_PLINK_ACTION]); 2033 nla_get_u8(info->attrs[NL80211_ATTR_STA_PLINK_ACTION]);
2119 2034
2120 rtnl_lock();
2121
2122 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
2123 if (err)
2124 goto out_rtnl;
2125
2126 err = get_vlan(info, rdev, &params.vlan); 2035 err = get_vlan(info, rdev, &params.vlan);
2127 if (err) 2036 if (err)
2128 goto out; 2037 goto out;
@@ -2184,19 +2093,15 @@ static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info)
2184 out: 2093 out:
2185 if (params.vlan) 2094 if (params.vlan)
2186 dev_put(params.vlan); 2095 dev_put(params.vlan);
2187 cfg80211_unlock_rdev(rdev);
2188 dev_put(dev);
2189 out_rtnl:
2190 rtnl_unlock();
2191 2096
2192 return err; 2097 return err;
2193} 2098}
2194 2099
2195static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info) 2100static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)
2196{ 2101{
2197 struct cfg80211_registered_device *rdev; 2102 struct cfg80211_registered_device *rdev = info->user_ptr[0];
2198 int err; 2103 int err;
2199 struct net_device *dev; 2104 struct net_device *dev = info->user_ptr[1];
2200 struct station_parameters params; 2105 struct station_parameters params;
2201 u8 *mac_addr = NULL; 2106 u8 *mac_addr = NULL;
2202 2107
@@ -2233,18 +2138,10 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)
2233 if (parse_station_flags(info, &params)) 2138 if (parse_station_flags(info, &params))
2234 return -EINVAL; 2139 return -EINVAL;
2235 2140
2236 rtnl_lock();
2237
2238 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
2239 if (err)
2240 goto out_rtnl;
2241
2242 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP && 2141 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
2243 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN && 2142 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN &&
2244 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) { 2143 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
2245 err = -EINVAL; 2144 return -EINVAL;
2246 goto out;
2247 }
2248 2145
2249 err = get_vlan(info, rdev, &params.vlan); 2146 err = get_vlan(info, rdev, &params.vlan);
2250 if (err) 2147 if (err)
@@ -2258,62 +2155,33 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)
2258 goto out; 2155 goto out;
2259 } 2156 }
2260 2157
2261 if (!netif_running(dev)) {
2262 err = -ENETDOWN;
2263 goto out;
2264 }
2265
2266 err = rdev->ops->add_station(&rdev->wiphy, dev, mac_addr, &params); 2158 err = rdev->ops->add_station(&rdev->wiphy, dev, mac_addr, &params);
2267 2159
2268 out: 2160 out:
2269 if (params.vlan) 2161 if (params.vlan)
2270 dev_put(params.vlan); 2162 dev_put(params.vlan);
2271 cfg80211_unlock_rdev(rdev);
2272 dev_put(dev);
2273 out_rtnl:
2274 rtnl_unlock();
2275
2276 return err; 2163 return err;
2277} 2164}
2278 2165
2279static int nl80211_del_station(struct sk_buff *skb, struct genl_info *info) 2166static int nl80211_del_station(struct sk_buff *skb, struct genl_info *info)
2280{ 2167{
2281 struct cfg80211_registered_device *rdev; 2168 struct cfg80211_registered_device *rdev = info->user_ptr[0];
2282 int err; 2169 struct net_device *dev = info->user_ptr[1];
2283 struct net_device *dev;
2284 u8 *mac_addr = NULL; 2170 u8 *mac_addr = NULL;
2285 2171
2286 if (info->attrs[NL80211_ATTR_MAC]) 2172 if (info->attrs[NL80211_ATTR_MAC])
2287 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]); 2173 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
2288 2174
2289 rtnl_lock();
2290
2291 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
2292 if (err)
2293 goto out_rtnl;
2294
2295 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP && 2175 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
2296 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN && 2176 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN &&
2297 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT && 2177 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT &&
2298 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) { 2178 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
2299 err = -EINVAL; 2179 return -EINVAL;
2300 goto out;
2301 }
2302
2303 if (!rdev->ops->del_station) {
2304 err = -EOPNOTSUPP;
2305 goto out;
2306 }
2307
2308 err = rdev->ops->del_station(&rdev->wiphy, dev, mac_addr);
2309 2180
2310 out: 2181 if (!rdev->ops->del_station)
2311 cfg80211_unlock_rdev(rdev); 2182 return -EOPNOTSUPP;
2312 dev_put(dev);
2313 out_rtnl:
2314 rtnl_unlock();
2315 2183
2316 return err; 2184 return rdev->ops->del_station(&rdev->wiphy, dev, mac_addr);
2317} 2185}
2318 2186
2319static int nl80211_send_mpath(struct sk_buff *msg, u32 pid, u32 seq, 2187static int nl80211_send_mpath(struct sk_buff *msg, u32 pid, u32 seq,
@@ -2376,28 +2244,12 @@ static int nl80211_dump_mpath(struct sk_buff *skb,
2376 struct net_device *netdev; 2244 struct net_device *netdev;
2377 u8 dst[ETH_ALEN]; 2245 u8 dst[ETH_ALEN];
2378 u8 next_hop[ETH_ALEN]; 2246 u8 next_hop[ETH_ALEN];
2379 int ifidx = cb->args[0];
2380 int path_idx = cb->args[1]; 2247 int path_idx = cb->args[1];
2381 int err; 2248 int err;
2382 2249
2383 if (!ifidx) 2250 err = nl80211_prepare_netdev_dump(skb, cb, &dev, &netdev);
2384 ifidx = nl80211_get_ifidx(cb); 2251 if (err)
2385 if (ifidx < 0) 2252 return err;
2386 return ifidx;
2387
2388 rtnl_lock();
2389
2390 netdev = __dev_get_by_index(sock_net(skb->sk), ifidx);
2391 if (!netdev) {
2392 err = -ENODEV;
2393 goto out_rtnl;
2394 }
2395
2396 dev = cfg80211_get_dev_from_ifindex(sock_net(skb->sk), ifidx);
2397 if (IS_ERR(dev)) {
2398 err = PTR_ERR(dev);
2399 goto out_rtnl;
2400 }
2401 2253
2402 if (!dev->ops->dump_mpath) { 2254 if (!dev->ops->dump_mpath) {
2403 err = -EOPNOTSUPP; 2255 err = -EOPNOTSUPP;
@@ -2431,18 +2283,15 @@ static int nl80211_dump_mpath(struct sk_buff *skb,
2431 cb->args[1] = path_idx; 2283 cb->args[1] = path_idx;
2432 err = skb->len; 2284 err = skb->len;
2433 out_err: 2285 out_err:
2434 cfg80211_unlock_rdev(dev); 2286 nl80211_finish_netdev_dump(dev);
2435 out_rtnl:
2436 rtnl_unlock();
2437
2438 return err; 2287 return err;
2439} 2288}
2440 2289
2441static int nl80211_get_mpath(struct sk_buff *skb, struct genl_info *info) 2290static int nl80211_get_mpath(struct sk_buff *skb, struct genl_info *info)
2442{ 2291{
2443 struct cfg80211_registered_device *rdev; 2292 struct cfg80211_registered_device *rdev = info->user_ptr[0];
2444 int err; 2293 int err;
2445 struct net_device *dev; 2294 struct net_device *dev = info->user_ptr[1];
2446 struct mpath_info pinfo; 2295 struct mpath_info pinfo;
2447 struct sk_buff *msg; 2296 struct sk_buff *msg;
2448 u8 *dst = NULL; 2297 u8 *dst = NULL;
@@ -2455,53 +2304,33 @@ static int nl80211_get_mpath(struct sk_buff *skb, struct genl_info *info)
2455 2304
2456 dst = nla_data(info->attrs[NL80211_ATTR_MAC]); 2305 dst = nla_data(info->attrs[NL80211_ATTR_MAC]);
2457 2306
2458 rtnl_lock(); 2307 if (!rdev->ops->get_mpath)
2459 2308 return -EOPNOTSUPP;
2460 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
2461 if (err)
2462 goto out_rtnl;
2463
2464 if (!rdev->ops->get_mpath) {
2465 err = -EOPNOTSUPP;
2466 goto out;
2467 }
2468 2309
2469 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT) { 2310 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT)
2470 err = -EOPNOTSUPP; 2311 return -EOPNOTSUPP;
2471 goto out;
2472 }
2473 2312
2474 err = rdev->ops->get_mpath(&rdev->wiphy, dev, dst, next_hop, &pinfo); 2313 err = rdev->ops->get_mpath(&rdev->wiphy, dev, dst, next_hop, &pinfo);
2475 if (err) 2314 if (err)
2476 goto out; 2315 return err;
2477 2316
2478 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 2317 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
2479 if (!msg) 2318 if (!msg)
2480 goto out; 2319 return -ENOMEM;
2481 2320
2482 if (nl80211_send_mpath(msg, info->snd_pid, info->snd_seq, 0, 2321 if (nl80211_send_mpath(msg, info->snd_pid, info->snd_seq, 0,
2483 dev, dst, next_hop, &pinfo) < 0) 2322 dev, dst, next_hop, &pinfo) < 0) {
2484 goto out_free; 2323 nlmsg_free(msg);
2485 2324 return -ENOBUFS;
2486 err = genlmsg_reply(msg, info); 2325 }
2487 goto out;
2488
2489 out_free:
2490 nlmsg_free(msg);
2491 out:
2492 cfg80211_unlock_rdev(rdev);
2493 dev_put(dev);
2494 out_rtnl:
2495 rtnl_unlock();
2496 2326
2497 return err; 2327 return genlmsg_reply(msg, info);
2498} 2328}
2499 2329
2500static int nl80211_set_mpath(struct sk_buff *skb, struct genl_info *info) 2330static int nl80211_set_mpath(struct sk_buff *skb, struct genl_info *info)
2501{ 2331{
2502 struct cfg80211_registered_device *rdev; 2332 struct cfg80211_registered_device *rdev = info->user_ptr[0];
2503 int err; 2333 struct net_device *dev = info->user_ptr[1];
2504 struct net_device *dev;
2505 u8 *dst = NULL; 2334 u8 *dst = NULL;
2506 u8 *next_hop = NULL; 2335 u8 *next_hop = NULL;
2507 2336
@@ -2514,42 +2343,19 @@ static int nl80211_set_mpath(struct sk_buff *skb, struct genl_info *info)
2514 dst = nla_data(info->attrs[NL80211_ATTR_MAC]); 2343 dst = nla_data(info->attrs[NL80211_ATTR_MAC]);
2515 next_hop = nla_data(info->attrs[NL80211_ATTR_MPATH_NEXT_HOP]); 2344 next_hop = nla_data(info->attrs[NL80211_ATTR_MPATH_NEXT_HOP]);
2516 2345
2517 rtnl_lock(); 2346 if (!rdev->ops->change_mpath)
2518 2347 return -EOPNOTSUPP;
2519 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
2520 if (err)
2521 goto out_rtnl;
2522
2523 if (!rdev->ops->change_mpath) {
2524 err = -EOPNOTSUPP;
2525 goto out;
2526 }
2527
2528 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT) {
2529 err = -EOPNOTSUPP;
2530 goto out;
2531 }
2532
2533 if (!netif_running(dev)) {
2534 err = -ENETDOWN;
2535 goto out;
2536 }
2537
2538 err = rdev->ops->change_mpath(&rdev->wiphy, dev, dst, next_hop);
2539 2348
2540 out: 2349 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT)
2541 cfg80211_unlock_rdev(rdev); 2350 return -EOPNOTSUPP;
2542 dev_put(dev);
2543 out_rtnl:
2544 rtnl_unlock();
2545 2351
2546 return err; 2352 return rdev->ops->change_mpath(&rdev->wiphy, dev, dst, next_hop);
2547} 2353}
2354
2548static int nl80211_new_mpath(struct sk_buff *skb, struct genl_info *info) 2355static int nl80211_new_mpath(struct sk_buff *skb, struct genl_info *info)
2549{ 2356{
2550 struct cfg80211_registered_device *rdev; 2357 struct cfg80211_registered_device *rdev = info->user_ptr[0];
2551 int err; 2358 struct net_device *dev = info->user_ptr[1];
2552 struct net_device *dev;
2553 u8 *dst = NULL; 2359 u8 *dst = NULL;
2554 u8 *next_hop = NULL; 2360 u8 *next_hop = NULL;
2555 2361
@@ -2562,75 +2368,34 @@ static int nl80211_new_mpath(struct sk_buff *skb, struct genl_info *info)
2562 dst = nla_data(info->attrs[NL80211_ATTR_MAC]); 2368 dst = nla_data(info->attrs[NL80211_ATTR_MAC]);
2563 next_hop = nla_data(info->attrs[NL80211_ATTR_MPATH_NEXT_HOP]); 2369 next_hop = nla_data(info->attrs[NL80211_ATTR_MPATH_NEXT_HOP]);
2564 2370
2565 rtnl_lock(); 2371 if (!rdev->ops->add_mpath)
2566 2372 return -EOPNOTSUPP;
2567 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
2568 if (err)
2569 goto out_rtnl;
2570
2571 if (!rdev->ops->add_mpath) {
2572 err = -EOPNOTSUPP;
2573 goto out;
2574 }
2575
2576 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT) {
2577 err = -EOPNOTSUPP;
2578 goto out;
2579 }
2580
2581 if (!netif_running(dev)) {
2582 err = -ENETDOWN;
2583 goto out;
2584 }
2585
2586 err = rdev->ops->add_mpath(&rdev->wiphy, dev, dst, next_hop);
2587 2373
2588 out: 2374 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT)
2589 cfg80211_unlock_rdev(rdev); 2375 return -EOPNOTSUPP;
2590 dev_put(dev);
2591 out_rtnl:
2592 rtnl_unlock();
2593 2376
2594 return err; 2377 return rdev->ops->add_mpath(&rdev->wiphy, dev, dst, next_hop);
2595} 2378}
2596 2379
2597static int nl80211_del_mpath(struct sk_buff *skb, struct genl_info *info) 2380static int nl80211_del_mpath(struct sk_buff *skb, struct genl_info *info)
2598{ 2381{
2599 struct cfg80211_registered_device *rdev; 2382 struct cfg80211_registered_device *rdev = info->user_ptr[0];
2600 int err; 2383 struct net_device *dev = info->user_ptr[1];
2601 struct net_device *dev;
2602 u8 *dst = NULL; 2384 u8 *dst = NULL;
2603 2385
2604 if (info->attrs[NL80211_ATTR_MAC]) 2386 if (info->attrs[NL80211_ATTR_MAC])
2605 dst = nla_data(info->attrs[NL80211_ATTR_MAC]); 2387 dst = nla_data(info->attrs[NL80211_ATTR_MAC]);
2606 2388
2607 rtnl_lock(); 2389 if (!rdev->ops->del_mpath)
2608 2390 return -EOPNOTSUPP;
2609 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
2610 if (err)
2611 goto out_rtnl;
2612
2613 if (!rdev->ops->del_mpath) {
2614 err = -EOPNOTSUPP;
2615 goto out;
2616 }
2617
2618 err = rdev->ops->del_mpath(&rdev->wiphy, dev, dst);
2619
2620 out:
2621 cfg80211_unlock_rdev(rdev);
2622 dev_put(dev);
2623 out_rtnl:
2624 rtnl_unlock();
2625 2391
2626 return err; 2392 return rdev->ops->del_mpath(&rdev->wiphy, dev, dst);
2627} 2393}
2628 2394
2629static int nl80211_set_bss(struct sk_buff *skb, struct genl_info *info) 2395static int nl80211_set_bss(struct sk_buff *skb, struct genl_info *info)
2630{ 2396{
2631 struct cfg80211_registered_device *rdev; 2397 struct cfg80211_registered_device *rdev = info->user_ptr[0];
2632 int err; 2398 struct net_device *dev = info->user_ptr[1];
2633 struct net_device *dev;
2634 struct bss_parameters params; 2399 struct bss_parameters params;
2635 2400
2636 memset(&params, 0, sizeof(params)); 2401 memset(&params, 0, sizeof(params));
@@ -2658,32 +2423,14 @@ static int nl80211_set_bss(struct sk_buff *skb, struct genl_info *info)
2658 if (info->attrs[NL80211_ATTR_AP_ISOLATE]) 2423 if (info->attrs[NL80211_ATTR_AP_ISOLATE])
2659 params.ap_isolate = !!nla_get_u8(info->attrs[NL80211_ATTR_AP_ISOLATE]); 2424 params.ap_isolate = !!nla_get_u8(info->attrs[NL80211_ATTR_AP_ISOLATE]);
2660 2425
2661 rtnl_lock(); 2426 if (!rdev->ops->change_bss)
2662 2427 return -EOPNOTSUPP;
2663 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
2664 if (err)
2665 goto out_rtnl;
2666
2667 if (!rdev->ops->change_bss) {
2668 err = -EOPNOTSUPP;
2669 goto out;
2670 }
2671 2428
2672 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP && 2429 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
2673 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) { 2430 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
2674 err = -EOPNOTSUPP; 2431 return -EOPNOTSUPP;
2675 goto out;
2676 }
2677
2678 err = rdev->ops->change_bss(&rdev->wiphy, dev, &params);
2679
2680 out:
2681 cfg80211_unlock_rdev(rdev);
2682 dev_put(dev);
2683 out_rtnl:
2684 rtnl_unlock();
2685 2432
2686 return err; 2433 return rdev->ops->change_bss(&rdev->wiphy, dev, &params);
2687} 2434}
2688 2435
2689static const struct nla_policy reg_rule_policy[NL80211_REG_RULE_ATTR_MAX + 1] = { 2436static const struct nla_policy reg_rule_policy[NL80211_REG_RULE_ATTR_MAX + 1] = {
@@ -2762,37 +2509,26 @@ static int nl80211_req_set_reg(struct sk_buff *skb, struct genl_info *info)
2762static int nl80211_get_mesh_params(struct sk_buff *skb, 2509static int nl80211_get_mesh_params(struct sk_buff *skb,
2763 struct genl_info *info) 2510 struct genl_info *info)
2764{ 2511{
2765 struct cfg80211_registered_device *rdev; 2512 struct cfg80211_registered_device *rdev = info->user_ptr[0];
2766 struct mesh_config cur_params; 2513 struct mesh_config cur_params;
2767 int err; 2514 int err;
2768 struct net_device *dev; 2515 struct net_device *dev = info->user_ptr[1];
2769 void *hdr; 2516 void *hdr;
2770 struct nlattr *pinfoattr; 2517 struct nlattr *pinfoattr;
2771 struct sk_buff *msg; 2518 struct sk_buff *msg;
2772 2519
2773 rtnl_lock(); 2520 if (!rdev->ops->get_mesh_params)
2774 2521 return -EOPNOTSUPP;
2775 /* Look up our device */
2776 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
2777 if (err)
2778 goto out_rtnl;
2779
2780 if (!rdev->ops->get_mesh_params) {
2781 err = -EOPNOTSUPP;
2782 goto out;
2783 }
2784 2522
2785 /* Get the mesh params */ 2523 /* Get the mesh params */
2786 err = rdev->ops->get_mesh_params(&rdev->wiphy, dev, &cur_params); 2524 err = rdev->ops->get_mesh_params(&rdev->wiphy, dev, &cur_params);
2787 if (err) 2525 if (err)
2788 goto out; 2526 return err;
2789 2527
2790 /* Draw up a netlink message to send back */ 2528 /* Draw up a netlink message to send back */
2791 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 2529 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
2792 if (!msg) { 2530 if (!msg)
2793 err = -ENOBUFS; 2531 return -ENOMEM;
2794 goto out;
2795 }
2796 hdr = nl80211hdr_put(msg, info->snd_pid, info->snd_seq, 0, 2532 hdr = nl80211hdr_put(msg, info->snd_pid, info->snd_seq, 0,
2797 NL80211_CMD_GET_MESH_PARAMS); 2533 NL80211_CMD_GET_MESH_PARAMS);
2798 if (!hdr) 2534 if (!hdr)
@@ -2831,21 +2567,12 @@ static int nl80211_get_mesh_params(struct sk_buff *skb,
2831 cur_params.dot11MeshHWMPRootMode); 2567 cur_params.dot11MeshHWMPRootMode);
2832 nla_nest_end(msg, pinfoattr); 2568 nla_nest_end(msg, pinfoattr);
2833 genlmsg_end(msg, hdr); 2569 genlmsg_end(msg, hdr);
2834 err = genlmsg_reply(msg, info); 2570 return genlmsg_reply(msg, info);
2835 goto out;
2836 2571
2837 nla_put_failure: 2572 nla_put_failure:
2838 genlmsg_cancel(msg, hdr); 2573 genlmsg_cancel(msg, hdr);
2839 nlmsg_free(msg); 2574 nlmsg_free(msg);
2840 err = -EMSGSIZE; 2575 return -ENOBUFS;
2841 out:
2842 /* Cleanup */
2843 cfg80211_unlock_rdev(rdev);
2844 dev_put(dev);
2845 out_rtnl:
2846 rtnl_unlock();
2847
2848 return err;
2849} 2576}
2850 2577
2851#define FILL_IN_MESH_PARAM_IF_SET(table, cfg, param, mask, attr_num, nla_fn) \ 2578#define FILL_IN_MESH_PARAM_IF_SET(table, cfg, param, mask, attr_num, nla_fn) \
@@ -2875,10 +2602,9 @@ static const struct nla_policy nl80211_meshconf_params_policy[NL80211_MESHCONF_A
2875 2602
2876static int nl80211_set_mesh_params(struct sk_buff *skb, struct genl_info *info) 2603static int nl80211_set_mesh_params(struct sk_buff *skb, struct genl_info *info)
2877{ 2604{
2878 int err;
2879 u32 mask; 2605 u32 mask;
2880 struct cfg80211_registered_device *rdev; 2606 struct cfg80211_registered_device *rdev = info->user_ptr[0];
2881 struct net_device *dev; 2607 struct net_device *dev = info->user_ptr[1];
2882 struct mesh_config cfg; 2608 struct mesh_config cfg;
2883 struct nlattr *tb[NL80211_MESHCONF_ATTR_MAX + 1]; 2609 struct nlattr *tb[NL80211_MESHCONF_ATTR_MAX + 1];
2884 struct nlattr *parent_attr; 2610 struct nlattr *parent_attr;
@@ -2890,16 +2616,8 @@ static int nl80211_set_mesh_params(struct sk_buff *skb, struct genl_info *info)
2890 parent_attr, nl80211_meshconf_params_policy)) 2616 parent_attr, nl80211_meshconf_params_policy))
2891 return -EINVAL; 2617 return -EINVAL;
2892 2618
2893 rtnl_lock(); 2619 if (!rdev->ops->set_mesh_params)
2894 2620 return -EOPNOTSUPP;
2895 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
2896 if (err)
2897 goto out_rtnl;
2898
2899 if (!rdev->ops->set_mesh_params) {
2900 err = -EOPNOTSUPP;
2901 goto out;
2902 }
2903 2621
2904 /* This makes sure that there aren't more than 32 mesh config 2622 /* This makes sure that there aren't more than 32 mesh config
2905 * parameters (otherwise our bitfield scheme would not work.) */ 2623 * parameters (otherwise our bitfield scheme would not work.) */
@@ -2945,16 +2663,7 @@ static int nl80211_set_mesh_params(struct sk_buff *skb, struct genl_info *info)
2945 nla_get_u8); 2663 nla_get_u8);
2946 2664
2947 /* Apply changes */ 2665 /* Apply changes */
2948 err = rdev->ops->set_mesh_params(&rdev->wiphy, dev, &cfg, mask); 2666 return rdev->ops->set_mesh_params(&rdev->wiphy, dev, &cfg, mask);
2949
2950 out:
2951 /* cleanup */
2952 cfg80211_unlock_rdev(rdev);
2953 dev_put(dev);
2954 out_rtnl:
2955 rtnl_unlock();
2956
2957 return err;
2958} 2667}
2959 2668
2960#undef FILL_IN_MESH_PARAM_IF_SET 2669#undef FILL_IN_MESH_PARAM_IF_SET
@@ -3137,8 +2846,8 @@ static int validate_scan_freqs(struct nlattr *freqs)
3137 2846
3138static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info) 2847static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
3139{ 2848{
3140 struct cfg80211_registered_device *rdev; 2849 struct cfg80211_registered_device *rdev = info->user_ptr[0];
3141 struct net_device *dev; 2850 struct net_device *dev = info->user_ptr[1];
3142 struct cfg80211_scan_request *request; 2851 struct cfg80211_scan_request *request;
3143 struct cfg80211_ssid *ssid; 2852 struct cfg80211_ssid *ssid;
3144 struct ieee80211_channel *channel; 2853 struct ieee80211_channel *channel;
@@ -3151,36 +2860,19 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
3151 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE])) 2860 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
3152 return -EINVAL; 2861 return -EINVAL;
3153 2862
3154 rtnl_lock();
3155
3156 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
3157 if (err)
3158 goto out_rtnl;
3159
3160 wiphy = &rdev->wiphy; 2863 wiphy = &rdev->wiphy;
3161 2864
3162 if (!rdev->ops->scan) { 2865 if (!rdev->ops->scan)
3163 err = -EOPNOTSUPP; 2866 return -EOPNOTSUPP;
3164 goto out;
3165 }
3166
3167 if (!netif_running(dev)) {
3168 err = -ENETDOWN;
3169 goto out;
3170 }
3171 2867
3172 if (rdev->scan_req) { 2868 if (rdev->scan_req)
3173 err = -EBUSY; 2869 return -EBUSY;
3174 goto out;
3175 }
3176 2870
3177 if (info->attrs[NL80211_ATTR_SCAN_FREQUENCIES]) { 2871 if (info->attrs[NL80211_ATTR_SCAN_FREQUENCIES]) {
3178 n_channels = validate_scan_freqs( 2872 n_channels = validate_scan_freqs(
3179 info->attrs[NL80211_ATTR_SCAN_FREQUENCIES]); 2873 info->attrs[NL80211_ATTR_SCAN_FREQUENCIES]);
3180 if (!n_channels) { 2874 if (!n_channels)
3181 err = -EINVAL; 2875 return -EINVAL;
3182 goto out;
3183 }
3184 } else { 2876 } else {
3185 n_channels = 0; 2877 n_channels = 0;
3186 2878
@@ -3193,29 +2885,23 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
3193 nla_for_each_nested(attr, info->attrs[NL80211_ATTR_SCAN_SSIDS], tmp) 2885 nla_for_each_nested(attr, info->attrs[NL80211_ATTR_SCAN_SSIDS], tmp)
3194 n_ssids++; 2886 n_ssids++;
3195 2887
3196 if (n_ssids > wiphy->max_scan_ssids) { 2888 if (n_ssids > wiphy->max_scan_ssids)
3197 err = -EINVAL; 2889 return -EINVAL;
3198 goto out;
3199 }
3200 2890
3201 if (info->attrs[NL80211_ATTR_IE]) 2891 if (info->attrs[NL80211_ATTR_IE])
3202 ie_len = nla_len(info->attrs[NL80211_ATTR_IE]); 2892 ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
3203 else 2893 else
3204 ie_len = 0; 2894 ie_len = 0;
3205 2895
3206 if (ie_len > wiphy->max_scan_ie_len) { 2896 if (ie_len > wiphy->max_scan_ie_len)
3207 err = -EINVAL; 2897 return -EINVAL;
3208 goto out;
3209 }
3210 2898
3211 request = kzalloc(sizeof(*request) 2899 request = kzalloc(sizeof(*request)
3212 + sizeof(*ssid) * n_ssids 2900 + sizeof(*ssid) * n_ssids
3213 + sizeof(channel) * n_channels 2901 + sizeof(channel) * n_channels
3214 + ie_len, GFP_KERNEL); 2902 + ie_len, GFP_KERNEL);
3215 if (!request) { 2903 if (!request)
3216 err = -ENOMEM; 2904 return -ENOMEM;
3217 goto out;
3218 }
3219 2905
3220 if (n_ssids) 2906 if (n_ssids)
3221 request->ssids = (void *)&request->channels[n_channels]; 2907 request->ssids = (void *)&request->channels[n_channels];
@@ -3303,18 +2989,11 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
3303 if (!err) { 2989 if (!err) {
3304 nl80211_send_scan_start(rdev, dev); 2990 nl80211_send_scan_start(rdev, dev);
3305 dev_hold(dev); 2991 dev_hold(dev);
3306 } 2992 } else {
3307
3308 out_free: 2993 out_free:
3309 if (err) {
3310 rdev->scan_req = NULL; 2994 rdev->scan_req = NULL;
3311 kfree(request); 2995 kfree(request);
3312 } 2996 }
3313 out:
3314 cfg80211_unlock_rdev(rdev);
3315 dev_put(dev);
3316 out_rtnl:
3317 rtnl_unlock();
3318 2997
3319 return err; 2998 return err;
3320} 2999}
@@ -3411,25 +3090,12 @@ static int nl80211_dump_scan(struct sk_buff *skb,
3411 struct net_device *dev; 3090 struct net_device *dev;
3412 struct cfg80211_internal_bss *scan; 3091 struct cfg80211_internal_bss *scan;
3413 struct wireless_dev *wdev; 3092 struct wireless_dev *wdev;
3414 int ifidx = cb->args[0];
3415 int start = cb->args[1], idx = 0; 3093 int start = cb->args[1], idx = 0;
3416 int err; 3094 int err;
3417 3095
3418 if (!ifidx) 3096 err = nl80211_prepare_netdev_dump(skb, cb, &rdev, &dev);
3419 ifidx = nl80211_get_ifidx(cb); 3097 if (err)
3420 if (ifidx < 0) 3098 return err;
3421 return ifidx;
3422 cb->args[0] = ifidx;
3423
3424 dev = dev_get_by_index(sock_net(skb->sk), ifidx);
3425 if (!dev)
3426 return -ENODEV;
3427
3428 rdev = cfg80211_get_dev_from_ifindex(sock_net(skb->sk), ifidx);
3429 if (IS_ERR(rdev)) {
3430 err = PTR_ERR(rdev);
3431 goto out_put_netdev;
3432 }
3433 3099
3434 wdev = dev->ieee80211_ptr; 3100 wdev = dev->ieee80211_ptr;
3435 3101
@@ -3445,21 +3111,17 @@ static int nl80211_dump_scan(struct sk_buff *skb,
3445 cb->nlh->nlmsg_seq, NLM_F_MULTI, 3111 cb->nlh->nlmsg_seq, NLM_F_MULTI,
3446 rdev, wdev, scan) < 0) { 3112 rdev, wdev, scan) < 0) {
3447 idx--; 3113 idx--;
3448 goto out; 3114 break;
3449 } 3115 }
3450 } 3116 }
3451 3117
3452 out:
3453 spin_unlock_bh(&rdev->bss_lock); 3118 spin_unlock_bh(&rdev->bss_lock);
3454 wdev_unlock(wdev); 3119 wdev_unlock(wdev);
3455 3120
3456 cb->args[1] = idx; 3121 cb->args[1] = idx;
3457 err = skb->len; 3122 nl80211_finish_netdev_dump(rdev);
3458 cfg80211_unlock_rdev(rdev);
3459 out_put_netdev:
3460 dev_put(dev);
3461 3123
3462 return err; 3124 return skb->len;
3463} 3125}
3464 3126
3465static int nl80211_send_survey(struct sk_buff *msg, u32 pid, u32 seq, 3127static int nl80211_send_survey(struct sk_buff *msg, u32 pid, u32 seq,
@@ -3489,6 +3151,8 @@ static int nl80211_send_survey(struct sk_buff *msg, u32 pid, u32 seq,
3489 if (survey->filled & SURVEY_INFO_NOISE_DBM) 3151 if (survey->filled & SURVEY_INFO_NOISE_DBM)
3490 NLA_PUT_U8(msg, NL80211_SURVEY_INFO_NOISE, 3152 NLA_PUT_U8(msg, NL80211_SURVEY_INFO_NOISE,
3491 survey->noise); 3153 survey->noise);
3154 if (survey->filled & SURVEY_INFO_IN_USE)
3155 NLA_PUT_FLAG(msg, NL80211_SURVEY_INFO_IN_USE);
3492 3156
3493 nla_nest_end(msg, infoattr); 3157 nla_nest_end(msg, infoattr);
3494 3158
@@ -3505,29 +3169,12 @@ static int nl80211_dump_survey(struct sk_buff *skb,
3505 struct survey_info survey; 3169 struct survey_info survey;
3506 struct cfg80211_registered_device *dev; 3170 struct cfg80211_registered_device *dev;
3507 struct net_device *netdev; 3171 struct net_device *netdev;
3508 int ifidx = cb->args[0];
3509 int survey_idx = cb->args[1]; 3172 int survey_idx = cb->args[1];
3510 int res; 3173 int res;
3511 3174
3512 if (!ifidx) 3175 res = nl80211_prepare_netdev_dump(skb, cb, &dev, &netdev);
3513 ifidx = nl80211_get_ifidx(cb); 3176 if (res)
3514 if (ifidx < 0) 3177 return res;
3515 return ifidx;
3516 cb->args[0] = ifidx;
3517
3518 rtnl_lock();
3519
3520 netdev = __dev_get_by_index(sock_net(skb->sk), ifidx);
3521 if (!netdev) {
3522 res = -ENODEV;
3523 goto out_rtnl;
3524 }
3525
3526 dev = cfg80211_get_dev_from_ifindex(sock_net(skb->sk), ifidx);
3527 if (IS_ERR(dev)) {
3528 res = PTR_ERR(dev);
3529 goto out_rtnl;
3530 }
3531 3178
3532 if (!dev->ops->dump_survey) { 3179 if (!dev->ops->dump_survey) {
3533 res = -EOPNOTSUPP; 3180 res = -EOPNOTSUPP;
@@ -3555,10 +3202,7 @@ static int nl80211_dump_survey(struct sk_buff *skb,
3555 cb->args[1] = survey_idx; 3202 cb->args[1] = survey_idx;
3556 res = skb->len; 3203 res = skb->len;
3557 out_err: 3204 out_err:
3558 cfg80211_unlock_rdev(dev); 3205 nl80211_finish_netdev_dump(dev);
3559 out_rtnl:
3560 rtnl_unlock();
3561
3562 return res; 3206 return res;
3563} 3207}
3564 3208
@@ -3591,8 +3235,8 @@ static bool nl80211_valid_cipher_suite(u32 cipher)
3591 3235
3592static int nl80211_authenticate(struct sk_buff *skb, struct genl_info *info) 3236static int nl80211_authenticate(struct sk_buff *skb, struct genl_info *info)
3593{ 3237{
3594 struct cfg80211_registered_device *rdev; 3238 struct cfg80211_registered_device *rdev = info->user_ptr[0];
3595 struct net_device *dev; 3239 struct net_device *dev = info->user_ptr[1];
3596 struct ieee80211_channel *chan; 3240 struct ieee80211_channel *chan;
3597 const u8 *bssid, *ssid, *ie = NULL; 3241 const u8 *bssid, *ssid, *ie = NULL;
3598 int err, ssid_len, ie_len = 0; 3242 int err, ssid_len, ie_len = 0;
@@ -3620,6 +3264,8 @@ static int nl80211_authenticate(struct sk_buff *skb, struct genl_info *info)
3620 return err; 3264 return err;
3621 3265
3622 if (key.idx >= 0) { 3266 if (key.idx >= 0) {
3267 if (key.type != -1 && key.type != NL80211_KEYTYPE_GROUP)
3268 return -EINVAL;
3623 if (!key.p.key || !key.p.key_len) 3269 if (!key.p.key || !key.p.key_len)
3624 return -EINVAL; 3270 return -EINVAL;
3625 if ((key.p.cipher != WLAN_CIPHER_SUITE_WEP40 || 3271 if ((key.p.cipher != WLAN_CIPHER_SUITE_WEP40 ||
@@ -3634,12 +3280,6 @@ static int nl80211_authenticate(struct sk_buff *skb, struct genl_info *info)
3634 key.p.key = NULL; 3280 key.p.key = NULL;
3635 } 3281 }
3636 3282
3637 rtnl_lock();
3638
3639 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
3640 if (err)
3641 goto unlock_rtnl;
3642
3643 if (key.idx >= 0) { 3283 if (key.idx >= 0) {
3644 int i; 3284 int i;
3645 bool ok = false; 3285 bool ok = false;
@@ -3649,35 +3289,22 @@ static int nl80211_authenticate(struct sk_buff *skb, struct genl_info *info)
3649 break; 3289 break;
3650 } 3290 }
3651 } 3291 }
3652 if (!ok) { 3292 if (!ok)
3653 err = -EINVAL; 3293 return -EINVAL;
3654 goto out;
3655 }
3656 } 3294 }
3657 3295
3658 if (!rdev->ops->auth) { 3296 if (!rdev->ops->auth)
3659 err = -EOPNOTSUPP; 3297 return -EOPNOTSUPP;
3660 goto out;
3661 }
3662 3298
3663 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION && 3299 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
3664 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT) { 3300 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT)
3665 err = -EOPNOTSUPP; 3301 return -EOPNOTSUPP;
3666 goto out;
3667 }
3668
3669 if (!netif_running(dev)) {
3670 err = -ENETDOWN;
3671 goto out;
3672 }
3673 3302
3674 bssid = nla_data(info->attrs[NL80211_ATTR_MAC]); 3303 bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
3675 chan = ieee80211_get_channel(&rdev->wiphy, 3304 chan = ieee80211_get_channel(&rdev->wiphy,
3676 nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ])); 3305 nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]));
3677 if (!chan || (chan->flags & IEEE80211_CHAN_DISABLED)) { 3306 if (!chan || (chan->flags & IEEE80211_CHAN_DISABLED))
3678 err = -EINVAL; 3307 return -EINVAL;
3679 goto out;
3680 }
3681 3308
3682 ssid = nla_data(info->attrs[NL80211_ATTR_SSID]); 3309 ssid = nla_data(info->attrs[NL80211_ATTR_SSID]);
3683 ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]); 3310 ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]);
@@ -3688,24 +3315,15 @@ static int nl80211_authenticate(struct sk_buff *skb, struct genl_info *info)
3688 } 3315 }
3689 3316
3690 auth_type = nla_get_u32(info->attrs[NL80211_ATTR_AUTH_TYPE]); 3317 auth_type = nla_get_u32(info->attrs[NL80211_ATTR_AUTH_TYPE]);
3691 if (!nl80211_valid_auth_type(auth_type)) { 3318 if (!nl80211_valid_auth_type(auth_type))
3692 err = -EINVAL; 3319 return -EINVAL;
3693 goto out;
3694 }
3695 3320
3696 local_state_change = !!info->attrs[NL80211_ATTR_LOCAL_STATE_CHANGE]; 3321 local_state_change = !!info->attrs[NL80211_ATTR_LOCAL_STATE_CHANGE];
3697 3322
3698 err = cfg80211_mlme_auth(rdev, dev, chan, auth_type, bssid, 3323 return cfg80211_mlme_auth(rdev, dev, chan, auth_type, bssid,
3699 ssid, ssid_len, ie, ie_len, 3324 ssid, ssid_len, ie, ie_len,
3700 key.p.key, key.p.key_len, key.idx, 3325 key.p.key, key.p.key_len, key.idx,
3701 local_state_change); 3326 local_state_change);
3702
3703out:
3704 cfg80211_unlock_rdev(rdev);
3705 dev_put(dev);
3706unlock_rtnl:
3707 rtnl_unlock();
3708 return err;
3709} 3327}
3710 3328
3711static int nl80211_crypto_settings(struct cfg80211_registered_device *rdev, 3329static int nl80211_crypto_settings(struct cfg80211_registered_device *rdev,
@@ -3789,8 +3407,8 @@ static int nl80211_crypto_settings(struct cfg80211_registered_device *rdev,
3789 3407
3790static int nl80211_associate(struct sk_buff *skb, struct genl_info *info) 3408static int nl80211_associate(struct sk_buff *skb, struct genl_info *info)
3791{ 3409{
3792 struct cfg80211_registered_device *rdev; 3410 struct cfg80211_registered_device *rdev = info->user_ptr[0];
3793 struct net_device *dev; 3411 struct net_device *dev = info->user_ptr[1];
3794 struct cfg80211_crypto_settings crypto; 3412 struct cfg80211_crypto_settings crypto;
3795 struct ieee80211_channel *chan; 3413 struct ieee80211_channel *chan;
3796 const u8 *bssid, *ssid, *ie = NULL, *prev_bssid = NULL; 3414 const u8 *bssid, *ssid, *ie = NULL, *prev_bssid = NULL;
@@ -3805,36 +3423,19 @@ static int nl80211_associate(struct sk_buff *skb, struct genl_info *info)
3805 !info->attrs[NL80211_ATTR_WIPHY_FREQ]) 3423 !info->attrs[NL80211_ATTR_WIPHY_FREQ])
3806 return -EINVAL; 3424 return -EINVAL;
3807 3425
3808 rtnl_lock(); 3426 if (!rdev->ops->assoc)
3809 3427 return -EOPNOTSUPP;
3810 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
3811 if (err)
3812 goto unlock_rtnl;
3813
3814 if (!rdev->ops->assoc) {
3815 err = -EOPNOTSUPP;
3816 goto out;
3817 }
3818 3428
3819 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION && 3429 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
3820 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT) { 3430 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT)
3821 err = -EOPNOTSUPP; 3431 return -EOPNOTSUPP;
3822 goto out;
3823 }
3824
3825 if (!netif_running(dev)) {
3826 err = -ENETDOWN;
3827 goto out;
3828 }
3829 3432
3830 bssid = nla_data(info->attrs[NL80211_ATTR_MAC]); 3433 bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
3831 3434
3832 chan = ieee80211_get_channel(&rdev->wiphy, 3435 chan = ieee80211_get_channel(&rdev->wiphy,
3833 nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ])); 3436 nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]));
3834 if (!chan || (chan->flags & IEEE80211_CHAN_DISABLED)) { 3437 if (!chan || (chan->flags & IEEE80211_CHAN_DISABLED))
3835 err = -EINVAL; 3438 return -EINVAL;
3836 goto out;
3837 }
3838 3439
3839 ssid = nla_data(info->attrs[NL80211_ATTR_SSID]); 3440 ssid = nla_data(info->attrs[NL80211_ATTR_SSID]);
3840 ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]); 3441 ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]);
@@ -3849,10 +3450,8 @@ static int nl80211_associate(struct sk_buff *skb, struct genl_info *info)
3849 nla_get_u32(info->attrs[NL80211_ATTR_USE_MFP]); 3450 nla_get_u32(info->attrs[NL80211_ATTR_USE_MFP]);
3850 if (mfp == NL80211_MFP_REQUIRED) 3451 if (mfp == NL80211_MFP_REQUIRED)
3851 use_mfp = true; 3452 use_mfp = true;
3852 else if (mfp != NL80211_MFP_NO) { 3453 else if (mfp != NL80211_MFP_NO)
3853 err = -EINVAL; 3454 return -EINVAL;
3854 goto out;
3855 }
3856 } 3455 }
3857 3456
3858 if (info->attrs[NL80211_ATTR_PREV_BSSID]) 3457 if (info->attrs[NL80211_ATTR_PREV_BSSID])
@@ -3864,20 +3463,15 @@ static int nl80211_associate(struct sk_buff *skb, struct genl_info *info)
3864 ssid, ssid_len, ie, ie_len, use_mfp, 3463 ssid, ssid_len, ie, ie_len, use_mfp,
3865 &crypto); 3464 &crypto);
3866 3465
3867out:
3868 cfg80211_unlock_rdev(rdev);
3869 dev_put(dev);
3870unlock_rtnl:
3871 rtnl_unlock();
3872 return err; 3466 return err;
3873} 3467}
3874 3468
3875static int nl80211_deauthenticate(struct sk_buff *skb, struct genl_info *info) 3469static int nl80211_deauthenticate(struct sk_buff *skb, struct genl_info *info)
3876{ 3470{
3877 struct cfg80211_registered_device *rdev; 3471 struct cfg80211_registered_device *rdev = info->user_ptr[0];
3878 struct net_device *dev; 3472 struct net_device *dev = info->user_ptr[1];
3879 const u8 *ie = NULL, *bssid; 3473 const u8 *ie = NULL, *bssid;
3880 int err, ie_len = 0; 3474 int ie_len = 0;
3881 u16 reason_code; 3475 u16 reason_code;
3882 bool local_state_change; 3476 bool local_state_change;
3883 3477
@@ -3890,35 +3484,19 @@ static int nl80211_deauthenticate(struct sk_buff *skb, struct genl_info *info)
3890 if (!info->attrs[NL80211_ATTR_REASON_CODE]) 3484 if (!info->attrs[NL80211_ATTR_REASON_CODE])
3891 return -EINVAL; 3485 return -EINVAL;
3892 3486
3893 rtnl_lock(); 3487 if (!rdev->ops->deauth)
3894 3488 return -EOPNOTSUPP;
3895 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
3896 if (err)
3897 goto unlock_rtnl;
3898
3899 if (!rdev->ops->deauth) {
3900 err = -EOPNOTSUPP;
3901 goto out;
3902 }
3903 3489
3904 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION && 3490 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
3905 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT) { 3491 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT)
3906 err = -EOPNOTSUPP; 3492 return -EOPNOTSUPP;
3907 goto out;
3908 }
3909
3910 if (!netif_running(dev)) {
3911 err = -ENETDOWN;
3912 goto out;
3913 }
3914 3493
3915 bssid = nla_data(info->attrs[NL80211_ATTR_MAC]); 3494 bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
3916 3495
3917 reason_code = nla_get_u16(info->attrs[NL80211_ATTR_REASON_CODE]); 3496 reason_code = nla_get_u16(info->attrs[NL80211_ATTR_REASON_CODE]);
3918 if (reason_code == 0) { 3497 if (reason_code == 0) {
3919 /* Reason Code 0 is reserved */ 3498 /* Reason Code 0 is reserved */
3920 err = -EINVAL; 3499 return -EINVAL;
3921 goto out;
3922 } 3500 }
3923 3501
3924 if (info->attrs[NL80211_ATTR_IE]) { 3502 if (info->attrs[NL80211_ATTR_IE]) {
@@ -3928,23 +3506,16 @@ static int nl80211_deauthenticate(struct sk_buff *skb, struct genl_info *info)
3928 3506
3929 local_state_change = !!info->attrs[NL80211_ATTR_LOCAL_STATE_CHANGE]; 3507 local_state_change = !!info->attrs[NL80211_ATTR_LOCAL_STATE_CHANGE];
3930 3508
3931 err = cfg80211_mlme_deauth(rdev, dev, bssid, ie, ie_len, reason_code, 3509 return cfg80211_mlme_deauth(rdev, dev, bssid, ie, ie_len, reason_code,
3932 local_state_change); 3510 local_state_change);
3933
3934out:
3935 cfg80211_unlock_rdev(rdev);
3936 dev_put(dev);
3937unlock_rtnl:
3938 rtnl_unlock();
3939 return err;
3940} 3511}
3941 3512
3942static int nl80211_disassociate(struct sk_buff *skb, struct genl_info *info) 3513static int nl80211_disassociate(struct sk_buff *skb, struct genl_info *info)
3943{ 3514{
3944 struct cfg80211_registered_device *rdev; 3515 struct cfg80211_registered_device *rdev = info->user_ptr[0];
3945 struct net_device *dev; 3516 struct net_device *dev = info->user_ptr[1];
3946 const u8 *ie = NULL, *bssid; 3517 const u8 *ie = NULL, *bssid;
3947 int err, ie_len = 0; 3518 int ie_len = 0;
3948 u16 reason_code; 3519 u16 reason_code;
3949 bool local_state_change; 3520 bool local_state_change;
3950 3521
@@ -3957,35 +3528,19 @@ static int nl80211_disassociate(struct sk_buff *skb, struct genl_info *info)
3957 if (!info->attrs[NL80211_ATTR_REASON_CODE]) 3528 if (!info->attrs[NL80211_ATTR_REASON_CODE])
3958 return -EINVAL; 3529 return -EINVAL;
3959 3530
3960 rtnl_lock(); 3531 if (!rdev->ops->disassoc)
3961 3532 return -EOPNOTSUPP;
3962 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
3963 if (err)
3964 goto unlock_rtnl;
3965
3966 if (!rdev->ops->disassoc) {
3967 err = -EOPNOTSUPP;
3968 goto out;
3969 }
3970 3533
3971 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION && 3534 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
3972 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT) { 3535 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT)
3973 err = -EOPNOTSUPP; 3536 return -EOPNOTSUPP;
3974 goto out;
3975 }
3976
3977 if (!netif_running(dev)) {
3978 err = -ENETDOWN;
3979 goto out;
3980 }
3981 3537
3982 bssid = nla_data(info->attrs[NL80211_ATTR_MAC]); 3538 bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
3983 3539
3984 reason_code = nla_get_u16(info->attrs[NL80211_ATTR_REASON_CODE]); 3540 reason_code = nla_get_u16(info->attrs[NL80211_ATTR_REASON_CODE]);
3985 if (reason_code == 0) { 3541 if (reason_code == 0) {
3986 /* Reason Code 0 is reserved */ 3542 /* Reason Code 0 is reserved */
3987 err = -EINVAL; 3543 return -EINVAL;
3988 goto out;
3989 } 3544 }
3990 3545
3991 if (info->attrs[NL80211_ATTR_IE]) { 3546 if (info->attrs[NL80211_ATTR_IE]) {
@@ -3995,21 +3550,14 @@ static int nl80211_disassociate(struct sk_buff *skb, struct genl_info *info)
3995 3550
3996 local_state_change = !!info->attrs[NL80211_ATTR_LOCAL_STATE_CHANGE]; 3551 local_state_change = !!info->attrs[NL80211_ATTR_LOCAL_STATE_CHANGE];
3997 3552
3998 err = cfg80211_mlme_disassoc(rdev, dev, bssid, ie, ie_len, reason_code, 3553 return cfg80211_mlme_disassoc(rdev, dev, bssid, ie, ie_len, reason_code,
3999 local_state_change); 3554 local_state_change);
4000
4001out:
4002 cfg80211_unlock_rdev(rdev);
4003 dev_put(dev);
4004unlock_rtnl:
4005 rtnl_unlock();
4006 return err;
4007} 3555}
4008 3556
4009static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info) 3557static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info)
4010{ 3558{
4011 struct cfg80211_registered_device *rdev; 3559 struct cfg80211_registered_device *rdev = info->user_ptr[0];
4012 struct net_device *dev; 3560 struct net_device *dev = info->user_ptr[1];
4013 struct cfg80211_ibss_params ibss; 3561 struct cfg80211_ibss_params ibss;
4014 struct wiphy *wiphy; 3562 struct wiphy *wiphy;
4015 struct cfg80211_cached_keys *connkeys = NULL; 3563 struct cfg80211_cached_keys *connkeys = NULL;
@@ -4034,26 +3582,11 @@ static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info)
4034 return -EINVAL; 3582 return -EINVAL;
4035 } 3583 }
4036 3584
4037 rtnl_lock(); 3585 if (!rdev->ops->join_ibss)
4038 3586 return -EOPNOTSUPP;
4039 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
4040 if (err)
4041 goto unlock_rtnl;
4042
4043 if (!rdev->ops->join_ibss) {
4044 err = -EOPNOTSUPP;
4045 goto out;
4046 }
4047
4048 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC) {
4049 err = -EOPNOTSUPP;
4050 goto out;
4051 }
4052 3587
4053 if (!netif_running(dev)) { 3588 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC)
4054 err = -ENETDOWN; 3589 return -EOPNOTSUPP;
4055 goto out;
4056 }
4057 3590
4058 wiphy = &rdev->wiphy; 3591 wiphy = &rdev->wiphy;
4059 3592
@@ -4071,24 +3604,12 @@ static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info)
4071 nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ])); 3604 nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]));
4072 if (!ibss.channel || 3605 if (!ibss.channel ||
4073 ibss.channel->flags & IEEE80211_CHAN_NO_IBSS || 3606 ibss.channel->flags & IEEE80211_CHAN_NO_IBSS ||
4074 ibss.channel->flags & IEEE80211_CHAN_DISABLED) { 3607 ibss.channel->flags & IEEE80211_CHAN_DISABLED)
4075 err = -EINVAL; 3608 return -EINVAL;
4076 goto out;
4077 }
4078 3609
4079 ibss.channel_fixed = !!info->attrs[NL80211_ATTR_FREQ_FIXED]; 3610 ibss.channel_fixed = !!info->attrs[NL80211_ATTR_FREQ_FIXED];
4080 ibss.privacy = !!info->attrs[NL80211_ATTR_PRIVACY]; 3611 ibss.privacy = !!info->attrs[NL80211_ATTR_PRIVACY];
4081 3612
4082 if (ibss.privacy && info->attrs[NL80211_ATTR_KEYS]) {
4083 connkeys = nl80211_parse_connkeys(rdev,
4084 info->attrs[NL80211_ATTR_KEYS]);
4085 if (IS_ERR(connkeys)) {
4086 err = PTR_ERR(connkeys);
4087 connkeys = NULL;
4088 goto out;
4089 }
4090 }
4091
4092 if (info->attrs[NL80211_ATTR_BSS_BASIC_RATES]) { 3613 if (info->attrs[NL80211_ATTR_BSS_BASIC_RATES]) {
4093 u8 *rates = 3614 u8 *rates =
4094 nla_data(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]); 3615 nla_data(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]);
@@ -4098,10 +3619,8 @@ static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info)
4098 wiphy->bands[ibss.channel->band]; 3619 wiphy->bands[ibss.channel->band];
4099 int i, j; 3620 int i, j;
4100 3621
4101 if (n_rates == 0) { 3622 if (n_rates == 0)
4102 err = -EINVAL; 3623 return -EINVAL;
4103 goto out;
4104 }
4105 3624
4106 for (i = 0; i < n_rates; i++) { 3625 for (i = 0; i < n_rates; i++) {
4107 int rate = (rates[i] & 0x7f) * 5; 3626 int rate = (rates[i] & 0x7f) * 5;
@@ -4114,60 +3633,36 @@ static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info)
4114 break; 3633 break;
4115 } 3634 }
4116 } 3635 }
4117 if (!found) { 3636 if (!found)
4118 err = -EINVAL; 3637 return -EINVAL;
4119 goto out;
4120 }
4121 } 3638 }
4122 } 3639 }
4123 3640
4124 err = cfg80211_join_ibss(rdev, dev, &ibss, connkeys); 3641 if (ibss.privacy && info->attrs[NL80211_ATTR_KEYS]) {
3642 connkeys = nl80211_parse_connkeys(rdev,
3643 info->attrs[NL80211_ATTR_KEYS]);
3644 if (IS_ERR(connkeys))
3645 return PTR_ERR(connkeys);
3646 }
4125 3647
4126out: 3648 err = cfg80211_join_ibss(rdev, dev, &ibss, connkeys);
4127 cfg80211_unlock_rdev(rdev);
4128 dev_put(dev);
4129unlock_rtnl:
4130 if (err) 3649 if (err)
4131 kfree(connkeys); 3650 kfree(connkeys);
4132 rtnl_unlock();
4133 return err; 3651 return err;
4134} 3652}
4135 3653
4136static int nl80211_leave_ibss(struct sk_buff *skb, struct genl_info *info) 3654static int nl80211_leave_ibss(struct sk_buff *skb, struct genl_info *info)
4137{ 3655{
4138 struct cfg80211_registered_device *rdev; 3656 struct cfg80211_registered_device *rdev = info->user_ptr[0];
4139 struct net_device *dev; 3657 struct net_device *dev = info->user_ptr[1];
4140 int err;
4141 3658
4142 rtnl_lock(); 3659 if (!rdev->ops->leave_ibss)
4143 3660 return -EOPNOTSUPP;
4144 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
4145 if (err)
4146 goto unlock_rtnl;
4147
4148 if (!rdev->ops->leave_ibss) {
4149 err = -EOPNOTSUPP;
4150 goto out;
4151 }
4152
4153 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC) {
4154 err = -EOPNOTSUPP;
4155 goto out;
4156 }
4157
4158 if (!netif_running(dev)) {
4159 err = -ENETDOWN;
4160 goto out;
4161 }
4162 3661
4163 err = cfg80211_leave_ibss(rdev, dev, false); 3662 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC)
3663 return -EOPNOTSUPP;
4164 3664
4165out: 3665 return cfg80211_leave_ibss(rdev, dev, false);
4166 cfg80211_unlock_rdev(rdev);
4167 dev_put(dev);
4168unlock_rtnl:
4169 rtnl_unlock();
4170 return err;
4171} 3666}
4172 3667
4173#ifdef CONFIG_NL80211_TESTMODE 3668#ifdef CONFIG_NL80211_TESTMODE
@@ -4177,20 +3672,12 @@ static struct genl_multicast_group nl80211_testmode_mcgrp = {
4177 3672
4178static int nl80211_testmode_do(struct sk_buff *skb, struct genl_info *info) 3673static int nl80211_testmode_do(struct sk_buff *skb, struct genl_info *info)
4179{ 3674{
4180 struct cfg80211_registered_device *rdev; 3675 struct cfg80211_registered_device *rdev = info->user_ptr[0];
4181 int err; 3676 int err;
4182 3677
4183 if (!info->attrs[NL80211_ATTR_TESTDATA]) 3678 if (!info->attrs[NL80211_ATTR_TESTDATA])
4184 return -EINVAL; 3679 return -EINVAL;
4185 3680
4186 rtnl_lock();
4187
4188 rdev = cfg80211_get_dev_from_info(info);
4189 if (IS_ERR(rdev)) {
4190 err = PTR_ERR(rdev);
4191 goto unlock_rtnl;
4192 }
4193
4194 err = -EOPNOTSUPP; 3681 err = -EOPNOTSUPP;
4195 if (rdev->ops->testmode_cmd) { 3682 if (rdev->ops->testmode_cmd) {
4196 rdev->testmode_info = info; 3683 rdev->testmode_info = info;
@@ -4200,10 +3687,6 @@ static int nl80211_testmode_do(struct sk_buff *skb, struct genl_info *info)
4200 rdev->testmode_info = NULL; 3687 rdev->testmode_info = NULL;
4201 } 3688 }
4202 3689
4203 cfg80211_unlock_rdev(rdev);
4204
4205 unlock_rtnl:
4206 rtnl_unlock();
4207 return err; 3690 return err;
4208} 3691}
4209 3692
@@ -4294,8 +3777,8 @@ EXPORT_SYMBOL(cfg80211_testmode_event);
4294 3777
4295static int nl80211_connect(struct sk_buff *skb, struct genl_info *info) 3778static int nl80211_connect(struct sk_buff *skb, struct genl_info *info)
4296{ 3779{
4297 struct cfg80211_registered_device *rdev; 3780 struct cfg80211_registered_device *rdev = info->user_ptr[0];
4298 struct net_device *dev; 3781 struct net_device *dev = info->user_ptr[1];
4299 struct cfg80211_connect_params connect; 3782 struct cfg80211_connect_params connect;
4300 struct wiphy *wiphy; 3783 struct wiphy *wiphy;
4301 struct cfg80211_cached_keys *connkeys = NULL; 3784 struct cfg80211_cached_keys *connkeys = NULL;
@@ -4324,22 +3807,10 @@ static int nl80211_connect(struct sk_buff *skb, struct genl_info *info)
4324 NL80211_MAX_NR_CIPHER_SUITES); 3807 NL80211_MAX_NR_CIPHER_SUITES);
4325 if (err) 3808 if (err)
4326 return err; 3809 return err;
4327 rtnl_lock();
4328
4329 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
4330 if (err)
4331 goto unlock_rtnl;
4332 3810
4333 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION && 3811 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
4334 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT) { 3812 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT)
4335 err = -EOPNOTSUPP; 3813 return -EOPNOTSUPP;
4336 goto out;
4337 }
4338
4339 if (!netif_running(dev)) {
4340 err = -ENETDOWN;
4341 goto out;
4342 }
4343 3814
4344 wiphy = &rdev->wiphy; 3815 wiphy = &rdev->wiphy;
4345 3816
@@ -4358,39 +3829,27 @@ static int nl80211_connect(struct sk_buff *skb, struct genl_info *info)
4358 ieee80211_get_channel(wiphy, 3829 ieee80211_get_channel(wiphy,
4359 nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ])); 3830 nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]));
4360 if (!connect.channel || 3831 if (!connect.channel ||
4361 connect.channel->flags & IEEE80211_CHAN_DISABLED) { 3832 connect.channel->flags & IEEE80211_CHAN_DISABLED)
4362 err = -EINVAL; 3833 return -EINVAL;
4363 goto out;
4364 }
4365 } 3834 }
4366 3835
4367 if (connect.privacy && info->attrs[NL80211_ATTR_KEYS]) { 3836 if (connect.privacy && info->attrs[NL80211_ATTR_KEYS]) {
4368 connkeys = nl80211_parse_connkeys(rdev, 3837 connkeys = nl80211_parse_connkeys(rdev,
4369 info->attrs[NL80211_ATTR_KEYS]); 3838 info->attrs[NL80211_ATTR_KEYS]);
4370 if (IS_ERR(connkeys)) { 3839 if (IS_ERR(connkeys))
4371 err = PTR_ERR(connkeys); 3840 return PTR_ERR(connkeys);
4372 connkeys = NULL;
4373 goto out;
4374 }
4375 } 3841 }
4376 3842
4377 err = cfg80211_connect(rdev, dev, &connect, connkeys); 3843 err = cfg80211_connect(rdev, dev, &connect, connkeys);
4378
4379out:
4380 cfg80211_unlock_rdev(rdev);
4381 dev_put(dev);
4382unlock_rtnl:
4383 if (err) 3844 if (err)
4384 kfree(connkeys); 3845 kfree(connkeys);
4385 rtnl_unlock();
4386 return err; 3846 return err;
4387} 3847}
4388 3848
4389static int nl80211_disconnect(struct sk_buff *skb, struct genl_info *info) 3849static int nl80211_disconnect(struct sk_buff *skb, struct genl_info *info)
4390{ 3850{
4391 struct cfg80211_registered_device *rdev; 3851 struct cfg80211_registered_device *rdev = info->user_ptr[0];
4392 struct net_device *dev; 3852 struct net_device *dev = info->user_ptr[1];
4393 int err;
4394 u16 reason; 3853 u16 reason;
4395 3854
4396 if (!info->attrs[NL80211_ATTR_REASON_CODE]) 3855 if (!info->attrs[NL80211_ATTR_REASON_CODE])
@@ -4401,36 +3860,16 @@ static int nl80211_disconnect(struct sk_buff *skb, struct genl_info *info)
4401 if (reason == 0) 3860 if (reason == 0)
4402 return -EINVAL; 3861 return -EINVAL;
4403 3862
4404 rtnl_lock();
4405
4406 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
4407 if (err)
4408 goto unlock_rtnl;
4409
4410 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION && 3863 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
4411 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT) { 3864 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT)
4412 err = -EOPNOTSUPP; 3865 return -EOPNOTSUPP;
4413 goto out;
4414 }
4415
4416 if (!netif_running(dev)) {
4417 err = -ENETDOWN;
4418 goto out;
4419 }
4420
4421 err = cfg80211_disconnect(rdev, dev, reason, true);
4422 3866
4423out: 3867 return cfg80211_disconnect(rdev, dev, reason, true);
4424 cfg80211_unlock_rdev(rdev);
4425 dev_put(dev);
4426unlock_rtnl:
4427 rtnl_unlock();
4428 return err;
4429} 3868}
4430 3869
4431static int nl80211_wiphy_netns(struct sk_buff *skb, struct genl_info *info) 3870static int nl80211_wiphy_netns(struct sk_buff *skb, struct genl_info *info)
4432{ 3871{
4433 struct cfg80211_registered_device *rdev; 3872 struct cfg80211_registered_device *rdev = info->user_ptr[0];
4434 struct net *net; 3873 struct net *net;
4435 int err; 3874 int err;
4436 u32 pid; 3875 u32 pid;
@@ -4440,43 +3879,26 @@ static int nl80211_wiphy_netns(struct sk_buff *skb, struct genl_info *info)
4440 3879
4441 pid = nla_get_u32(info->attrs[NL80211_ATTR_PID]); 3880 pid = nla_get_u32(info->attrs[NL80211_ATTR_PID]);
4442 3881
4443 rtnl_lock();
4444
4445 rdev = cfg80211_get_dev_from_info(info);
4446 if (IS_ERR(rdev)) {
4447 err = PTR_ERR(rdev);
4448 goto out_rtnl;
4449 }
4450
4451 net = get_net_ns_by_pid(pid); 3882 net = get_net_ns_by_pid(pid);
4452 if (IS_ERR(net)) { 3883 if (IS_ERR(net))
4453 err = PTR_ERR(net); 3884 return PTR_ERR(net);
4454 goto out;
4455 }
4456 3885
4457 err = 0; 3886 err = 0;
4458 3887
4459 /* check if anything to do */ 3888 /* check if anything to do */
4460 if (net_eq(wiphy_net(&rdev->wiphy), net)) 3889 if (!net_eq(wiphy_net(&rdev->wiphy), net))
4461 goto out_put_net; 3890 err = cfg80211_switch_netns(rdev, net);
4462 3891
4463 err = cfg80211_switch_netns(rdev, net);
4464 out_put_net:
4465 put_net(net); 3892 put_net(net);
4466 out:
4467 cfg80211_unlock_rdev(rdev);
4468 out_rtnl:
4469 rtnl_unlock();
4470 return err; 3893 return err;
4471} 3894}
4472 3895
4473static int nl80211_setdel_pmksa(struct sk_buff *skb, struct genl_info *info) 3896static int nl80211_setdel_pmksa(struct sk_buff *skb, struct genl_info *info)
4474{ 3897{
4475 struct cfg80211_registered_device *rdev; 3898 struct cfg80211_registered_device *rdev = info->user_ptr[0];
4476 int (*rdev_ops)(struct wiphy *wiphy, struct net_device *dev, 3899 int (*rdev_ops)(struct wiphy *wiphy, struct net_device *dev,
4477 struct cfg80211_pmksa *pmksa) = NULL; 3900 struct cfg80211_pmksa *pmksa) = NULL;
4478 int err; 3901 struct net_device *dev = info->user_ptr[1];
4479 struct net_device *dev;
4480 struct cfg80211_pmksa pmksa; 3902 struct cfg80211_pmksa pmksa;
4481 3903
4482 memset(&pmksa, 0, sizeof(struct cfg80211_pmksa)); 3904 memset(&pmksa, 0, sizeof(struct cfg80211_pmksa));
@@ -4487,20 +3909,12 @@ static int nl80211_setdel_pmksa(struct sk_buff *skb, struct genl_info *info)
4487 if (!info->attrs[NL80211_ATTR_PMKID]) 3909 if (!info->attrs[NL80211_ATTR_PMKID])
4488 return -EINVAL; 3910 return -EINVAL;
4489 3911
4490 rtnl_lock();
4491
4492 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
4493 if (err)
4494 goto out_rtnl;
4495
4496 pmksa.pmkid = nla_data(info->attrs[NL80211_ATTR_PMKID]); 3912 pmksa.pmkid = nla_data(info->attrs[NL80211_ATTR_PMKID]);
4497 pmksa.bssid = nla_data(info->attrs[NL80211_ATTR_MAC]); 3913 pmksa.bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
4498 3914
4499 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION && 3915 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
4500 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT) { 3916 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT)
4501 err = -EOPNOTSUPP; 3917 return -EOPNOTSUPP;
4502 goto out;
4503 }
4504 3918
4505 switch (info->genlhdr->cmd) { 3919 switch (info->genlhdr->cmd) {
4506 case NL80211_CMD_SET_PMKSA: 3920 case NL80211_CMD_SET_PMKSA:
@@ -4514,62 +3928,32 @@ static int nl80211_setdel_pmksa(struct sk_buff *skb, struct genl_info *info)
4514 break; 3928 break;
4515 } 3929 }
4516 3930
4517 if (!rdev_ops) { 3931 if (!rdev_ops)
4518 err = -EOPNOTSUPP; 3932 return -EOPNOTSUPP;
4519 goto out;
4520 }
4521
4522 err = rdev_ops(&rdev->wiphy, dev, &pmksa);
4523
4524 out:
4525 cfg80211_unlock_rdev(rdev);
4526 dev_put(dev);
4527 out_rtnl:
4528 rtnl_unlock();
4529 3933
4530 return err; 3934 return rdev_ops(&rdev->wiphy, dev, &pmksa);
4531} 3935}
4532 3936
4533static int nl80211_flush_pmksa(struct sk_buff *skb, struct genl_info *info) 3937static int nl80211_flush_pmksa(struct sk_buff *skb, struct genl_info *info)
4534{ 3938{
4535 struct cfg80211_registered_device *rdev; 3939 struct cfg80211_registered_device *rdev = info->user_ptr[0];
4536 int err; 3940 struct net_device *dev = info->user_ptr[1];
4537 struct net_device *dev;
4538
4539 rtnl_lock();
4540
4541 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
4542 if (err)
4543 goto out_rtnl;
4544 3941
4545 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION && 3942 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
4546 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT) { 3943 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT)
4547 err = -EOPNOTSUPP; 3944 return -EOPNOTSUPP;
4548 goto out;
4549 }
4550
4551 if (!rdev->ops->flush_pmksa) {
4552 err = -EOPNOTSUPP;
4553 goto out;
4554 }
4555
4556 err = rdev->ops->flush_pmksa(&rdev->wiphy, dev);
4557
4558 out:
4559 cfg80211_unlock_rdev(rdev);
4560 dev_put(dev);
4561 out_rtnl:
4562 rtnl_unlock();
4563 3945
4564 return err; 3946 if (!rdev->ops->flush_pmksa)
3947 return -EOPNOTSUPP;
4565 3948
3949 return rdev->ops->flush_pmksa(&rdev->wiphy, dev);
4566} 3950}
4567 3951
4568static int nl80211_remain_on_channel(struct sk_buff *skb, 3952static int nl80211_remain_on_channel(struct sk_buff *skb,
4569 struct genl_info *info) 3953 struct genl_info *info)
4570{ 3954{
4571 struct cfg80211_registered_device *rdev; 3955 struct cfg80211_registered_device *rdev = info->user_ptr[0];
4572 struct net_device *dev; 3956 struct net_device *dev = info->user_ptr[1];
4573 struct ieee80211_channel *chan; 3957 struct ieee80211_channel *chan;
4574 struct sk_buff *msg; 3958 struct sk_buff *msg;
4575 void *hdr; 3959 void *hdr;
@@ -4591,21 +3975,8 @@ static int nl80211_remain_on_channel(struct sk_buff *skb,
4591 if (!duration || !msecs_to_jiffies(duration) || duration > 5000) 3975 if (!duration || !msecs_to_jiffies(duration) || duration > 5000)
4592 return -EINVAL; 3976 return -EINVAL;
4593 3977
4594 rtnl_lock(); 3978 if (!rdev->ops->remain_on_channel)
4595 3979 return -EOPNOTSUPP;
4596 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
4597 if (err)
4598 goto unlock_rtnl;
4599
4600 if (!rdev->ops->remain_on_channel) {
4601 err = -EOPNOTSUPP;
4602 goto out;
4603 }
4604
4605 if (!netif_running(dev)) {
4606 err = -ENETDOWN;
4607 goto out;
4608 }
4609 3980
4610 if (info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE]) { 3981 if (info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE]) {
4611 channel_type = nla_get_u32( 3982 channel_type = nla_get_u32(
@@ -4613,24 +3984,18 @@ static int nl80211_remain_on_channel(struct sk_buff *skb,
4613 if (channel_type != NL80211_CHAN_NO_HT && 3984 if (channel_type != NL80211_CHAN_NO_HT &&
4614 channel_type != NL80211_CHAN_HT20 && 3985 channel_type != NL80211_CHAN_HT20 &&
4615 channel_type != NL80211_CHAN_HT40PLUS && 3986 channel_type != NL80211_CHAN_HT40PLUS &&
4616 channel_type != NL80211_CHAN_HT40MINUS) { 3987 channel_type != NL80211_CHAN_HT40MINUS)
4617 err = -EINVAL; 3988 return -EINVAL;
4618 goto out;
4619 }
4620 } 3989 }
4621 3990
4622 freq = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]); 3991 freq = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]);
4623 chan = rdev_freq_to_chan(rdev, freq, channel_type); 3992 chan = rdev_freq_to_chan(rdev, freq, channel_type);
4624 if (chan == NULL) { 3993 if (chan == NULL)
4625 err = -EINVAL; 3994 return -EINVAL;
4626 goto out;
4627 }
4628 3995
4629 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 3996 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
4630 if (!msg) { 3997 if (!msg)
4631 err = -ENOMEM; 3998 return -ENOMEM;
4632 goto out;
4633 }
4634 3999
4635 hdr = nl80211hdr_put(msg, info->snd_pid, info->snd_seq, 0, 4000 hdr = nl80211hdr_put(msg, info->snd_pid, info->snd_seq, 0,
4636 NL80211_CMD_REMAIN_ON_CHANNEL); 4001 NL80211_CMD_REMAIN_ON_CHANNEL);
@@ -4649,58 +4014,32 @@ static int nl80211_remain_on_channel(struct sk_buff *skb,
4649 NLA_PUT_U64(msg, NL80211_ATTR_COOKIE, cookie); 4014 NLA_PUT_U64(msg, NL80211_ATTR_COOKIE, cookie);
4650 4015
4651 genlmsg_end(msg, hdr); 4016 genlmsg_end(msg, hdr);
4652 err = genlmsg_reply(msg, info); 4017
4653 goto out; 4018 return genlmsg_reply(msg, info);
4654 4019
4655 nla_put_failure: 4020 nla_put_failure:
4656 err = -ENOBUFS; 4021 err = -ENOBUFS;
4657 free_msg: 4022 free_msg:
4658 nlmsg_free(msg); 4023 nlmsg_free(msg);
4659 out:
4660 cfg80211_unlock_rdev(rdev);
4661 dev_put(dev);
4662 unlock_rtnl:
4663 rtnl_unlock();
4664 return err; 4024 return err;
4665} 4025}
4666 4026
4667static int nl80211_cancel_remain_on_channel(struct sk_buff *skb, 4027static int nl80211_cancel_remain_on_channel(struct sk_buff *skb,
4668 struct genl_info *info) 4028 struct genl_info *info)
4669{ 4029{
4670 struct cfg80211_registered_device *rdev; 4030 struct cfg80211_registered_device *rdev = info->user_ptr[0];
4671 struct net_device *dev; 4031 struct net_device *dev = info->user_ptr[1];
4672 u64 cookie; 4032 u64 cookie;
4673 int err;
4674 4033
4675 if (!info->attrs[NL80211_ATTR_COOKIE]) 4034 if (!info->attrs[NL80211_ATTR_COOKIE])
4676 return -EINVAL; 4035 return -EINVAL;
4677 4036
4678 rtnl_lock(); 4037 if (!rdev->ops->cancel_remain_on_channel)
4679 4038 return -EOPNOTSUPP;
4680 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
4681 if (err)
4682 goto unlock_rtnl;
4683
4684 if (!rdev->ops->cancel_remain_on_channel) {
4685 err = -EOPNOTSUPP;
4686 goto out;
4687 }
4688
4689 if (!netif_running(dev)) {
4690 err = -ENETDOWN;
4691 goto out;
4692 }
4693 4039
4694 cookie = nla_get_u64(info->attrs[NL80211_ATTR_COOKIE]); 4040 cookie = nla_get_u64(info->attrs[NL80211_ATTR_COOKIE]);
4695 4041
4696 err = rdev->ops->cancel_remain_on_channel(&rdev->wiphy, dev, cookie); 4042 return rdev->ops->cancel_remain_on_channel(&rdev->wiphy, dev, cookie);
4697
4698 out:
4699 cfg80211_unlock_rdev(rdev);
4700 dev_put(dev);
4701 unlock_rtnl:
4702 rtnl_unlock();
4703 return err;
4704} 4043}
4705 4044
4706static u32 rateset_to_mask(struct ieee80211_supported_band *sband, 4045static u32 rateset_to_mask(struct ieee80211_supported_band *sband,
@@ -4736,26 +4075,18 @@ static int nl80211_set_tx_bitrate_mask(struct sk_buff *skb,
4736 struct genl_info *info) 4075 struct genl_info *info)
4737{ 4076{
4738 struct nlattr *tb[NL80211_TXRATE_MAX + 1]; 4077 struct nlattr *tb[NL80211_TXRATE_MAX + 1];
4739 struct cfg80211_registered_device *rdev; 4078 struct cfg80211_registered_device *rdev = info->user_ptr[0];
4740 struct cfg80211_bitrate_mask mask; 4079 struct cfg80211_bitrate_mask mask;
4741 int err, rem, i; 4080 int rem, i;
4742 struct net_device *dev; 4081 struct net_device *dev = info->user_ptr[1];
4743 struct nlattr *tx_rates; 4082 struct nlattr *tx_rates;
4744 struct ieee80211_supported_band *sband; 4083 struct ieee80211_supported_band *sband;
4745 4084
4746 if (info->attrs[NL80211_ATTR_TX_RATES] == NULL) 4085 if (info->attrs[NL80211_ATTR_TX_RATES] == NULL)
4747 return -EINVAL; 4086 return -EINVAL;
4748 4087
4749 rtnl_lock(); 4088 if (!rdev->ops->set_bitrate_mask)
4750 4089 return -EOPNOTSUPP;
4751 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
4752 if (err)
4753 goto unlock_rtnl;
4754
4755 if (!rdev->ops->set_bitrate_mask) {
4756 err = -EOPNOTSUPP;
4757 goto unlock;
4758 }
4759 4090
4760 memset(&mask, 0, sizeof(mask)); 4091 memset(&mask, 0, sizeof(mask));
4761 /* Default to all rates enabled */ 4092 /* Default to all rates enabled */
@@ -4772,15 +4103,11 @@ static int nl80211_set_tx_bitrate_mask(struct sk_buff *skb,
4772 nla_for_each_nested(tx_rates, info->attrs[NL80211_ATTR_TX_RATES], rem) 4103 nla_for_each_nested(tx_rates, info->attrs[NL80211_ATTR_TX_RATES], rem)
4773 { 4104 {
4774 enum ieee80211_band band = nla_type(tx_rates); 4105 enum ieee80211_band band = nla_type(tx_rates);
4775 if (band < 0 || band >= IEEE80211_NUM_BANDS) { 4106 if (band < 0 || band >= IEEE80211_NUM_BANDS)
4776 err = -EINVAL; 4107 return -EINVAL;
4777 goto unlock;
4778 }
4779 sband = rdev->wiphy.bands[band]; 4108 sband = rdev->wiphy.bands[band];
4780 if (sband == NULL) { 4109 if (sband == NULL)
4781 err = -EINVAL; 4110 return -EINVAL;
4782 goto unlock;
4783 }
4784 nla_parse(tb, NL80211_TXRATE_MAX, nla_data(tx_rates), 4111 nla_parse(tb, NL80211_TXRATE_MAX, nla_data(tx_rates),
4785 nla_len(tx_rates), nl80211_txattr_policy); 4112 nla_len(tx_rates), nl80211_txattr_policy);
4786 if (tb[NL80211_TXRATE_LEGACY]) { 4113 if (tb[NL80211_TXRATE_LEGACY]) {
@@ -4788,29 +4115,19 @@ static int nl80211_set_tx_bitrate_mask(struct sk_buff *skb,
4788 sband, 4115 sband,
4789 nla_data(tb[NL80211_TXRATE_LEGACY]), 4116 nla_data(tb[NL80211_TXRATE_LEGACY]),
4790 nla_len(tb[NL80211_TXRATE_LEGACY])); 4117 nla_len(tb[NL80211_TXRATE_LEGACY]));
4791 if (mask.control[band].legacy == 0) { 4118 if (mask.control[band].legacy == 0)
4792 err = -EINVAL; 4119 return -EINVAL;
4793 goto unlock;
4794 }
4795 } 4120 }
4796 } 4121 }
4797 4122
4798 err = rdev->ops->set_bitrate_mask(&rdev->wiphy, dev, NULL, &mask); 4123 return rdev->ops->set_bitrate_mask(&rdev->wiphy, dev, NULL, &mask);
4799
4800 unlock:
4801 dev_put(dev);
4802 cfg80211_unlock_rdev(rdev);
4803 unlock_rtnl:
4804 rtnl_unlock();
4805 return err;
4806} 4124}
4807 4125
4808static int nl80211_register_mgmt(struct sk_buff *skb, struct genl_info *info) 4126static int nl80211_register_mgmt(struct sk_buff *skb, struct genl_info *info)
4809{ 4127{
4810 struct cfg80211_registered_device *rdev; 4128 struct cfg80211_registered_device *rdev = info->user_ptr[0];
4811 struct net_device *dev; 4129 struct net_device *dev = info->user_ptr[1];
4812 u16 frame_type = IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_ACTION; 4130 u16 frame_type = IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_ACTION;
4813 int err;
4814 4131
4815 if (!info->attrs[NL80211_ATTR_FRAME_MATCH]) 4132 if (!info->attrs[NL80211_ATTR_FRAME_MATCH])
4816 return -EINVAL; 4133 return -EINVAL;
@@ -4818,41 +4135,28 @@ static int nl80211_register_mgmt(struct sk_buff *skb, struct genl_info *info)
4818 if (info->attrs[NL80211_ATTR_FRAME_TYPE]) 4135 if (info->attrs[NL80211_ATTR_FRAME_TYPE])
4819 frame_type = nla_get_u16(info->attrs[NL80211_ATTR_FRAME_TYPE]); 4136 frame_type = nla_get_u16(info->attrs[NL80211_ATTR_FRAME_TYPE]);
4820 4137
4821 rtnl_lock();
4822
4823 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
4824 if (err)
4825 goto unlock_rtnl;
4826
4827 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION && 4138 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
4828 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC && 4139 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC &&
4829 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT) { 4140 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT &&
4830 err = -EOPNOTSUPP; 4141 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
4831 goto out; 4142 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN &&
4832 } 4143 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
4144 return -EOPNOTSUPP;
4833 4145
4834 /* not much point in registering if we can't reply */ 4146 /* not much point in registering if we can't reply */
4835 if (!rdev->ops->mgmt_tx) { 4147 if (!rdev->ops->mgmt_tx)
4836 err = -EOPNOTSUPP; 4148 return -EOPNOTSUPP;
4837 goto out;
4838 }
4839 4149
4840 err = cfg80211_mlme_register_mgmt(dev->ieee80211_ptr, info->snd_pid, 4150 return cfg80211_mlme_register_mgmt(dev->ieee80211_ptr, info->snd_pid,
4841 frame_type, 4151 frame_type,
4842 nla_data(info->attrs[NL80211_ATTR_FRAME_MATCH]), 4152 nla_data(info->attrs[NL80211_ATTR_FRAME_MATCH]),
4843 nla_len(info->attrs[NL80211_ATTR_FRAME_MATCH])); 4153 nla_len(info->attrs[NL80211_ATTR_FRAME_MATCH]));
4844 out:
4845 cfg80211_unlock_rdev(rdev);
4846 dev_put(dev);
4847 unlock_rtnl:
4848 rtnl_unlock();
4849 return err;
4850} 4154}
4851 4155
4852static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info) 4156static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info)
4853{ 4157{
4854 struct cfg80211_registered_device *rdev; 4158 struct cfg80211_registered_device *rdev = info->user_ptr[0];
4855 struct net_device *dev; 4159 struct net_device *dev = info->user_ptr[1];
4856 struct ieee80211_channel *chan; 4160 struct ieee80211_channel *chan;
4857 enum nl80211_channel_type channel_type = NL80211_CHAN_NO_HT; 4161 enum nl80211_channel_type channel_type = NL80211_CHAN_NO_HT;
4858 bool channel_type_valid = false; 4162 bool channel_type_valid = false;
@@ -4866,28 +4170,16 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info)
4866 !info->attrs[NL80211_ATTR_WIPHY_FREQ]) 4170 !info->attrs[NL80211_ATTR_WIPHY_FREQ])
4867 return -EINVAL; 4171 return -EINVAL;
4868 4172
4869 rtnl_lock(); 4173 if (!rdev->ops->mgmt_tx)
4870 4174 return -EOPNOTSUPP;
4871 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
4872 if (err)
4873 goto unlock_rtnl;
4874
4875 if (!rdev->ops->mgmt_tx) {
4876 err = -EOPNOTSUPP;
4877 goto out;
4878 }
4879 4175
4880 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION && 4176 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
4881 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC && 4177 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC &&
4882 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT) { 4178 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT &&
4883 err = -EOPNOTSUPP; 4179 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
4884 goto out; 4180 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN &&
4885 } 4181 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
4886 4182 return -EOPNOTSUPP;
4887 if (!netif_running(dev)) {
4888 err = -ENETDOWN;
4889 goto out;
4890 }
4891 4183
4892 if (info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE]) { 4184 if (info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE]) {
4893 channel_type = nla_get_u32( 4185 channel_type = nla_get_u32(
@@ -4895,25 +4187,19 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info)
4895 if (channel_type != NL80211_CHAN_NO_HT && 4187 if (channel_type != NL80211_CHAN_NO_HT &&
4896 channel_type != NL80211_CHAN_HT20 && 4188 channel_type != NL80211_CHAN_HT20 &&
4897 channel_type != NL80211_CHAN_HT40PLUS && 4189 channel_type != NL80211_CHAN_HT40PLUS &&
4898 channel_type != NL80211_CHAN_HT40MINUS) { 4190 channel_type != NL80211_CHAN_HT40MINUS)
4899 err = -EINVAL; 4191 return -EINVAL;
4900 goto out;
4901 }
4902 channel_type_valid = true; 4192 channel_type_valid = true;
4903 } 4193 }
4904 4194
4905 freq = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]); 4195 freq = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]);
4906 chan = rdev_freq_to_chan(rdev, freq, channel_type); 4196 chan = rdev_freq_to_chan(rdev, freq, channel_type);
4907 if (chan == NULL) { 4197 if (chan == NULL)
4908 err = -EINVAL; 4198 return -EINVAL;
4909 goto out;
4910 }
4911 4199
4912 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 4200 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
4913 if (!msg) { 4201 if (!msg)
4914 err = -ENOMEM; 4202 return -ENOMEM;
4915 goto out;
4916 }
4917 4203
4918 hdr = nl80211hdr_put(msg, info->snd_pid, info->snd_seq, 0, 4204 hdr = nl80211hdr_put(msg, info->snd_pid, info->snd_seq, 0,
4919 NL80211_CMD_FRAME); 4205 NL80211_CMD_FRAME);
@@ -4933,110 +4219,72 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info)
4933 NLA_PUT_U64(msg, NL80211_ATTR_COOKIE, cookie); 4219 NLA_PUT_U64(msg, NL80211_ATTR_COOKIE, cookie);
4934 4220
4935 genlmsg_end(msg, hdr); 4221 genlmsg_end(msg, hdr);
4936 err = genlmsg_reply(msg, info); 4222 return genlmsg_reply(msg, info);
4937 goto out;
4938 4223
4939 nla_put_failure: 4224 nla_put_failure:
4940 err = -ENOBUFS; 4225 err = -ENOBUFS;
4941 free_msg: 4226 free_msg:
4942 nlmsg_free(msg); 4227 nlmsg_free(msg);
4943 out:
4944 cfg80211_unlock_rdev(rdev);
4945 dev_put(dev);
4946unlock_rtnl:
4947 rtnl_unlock();
4948 return err; 4228 return err;
4949} 4229}
4950 4230
4951static int nl80211_set_power_save(struct sk_buff *skb, struct genl_info *info) 4231static int nl80211_set_power_save(struct sk_buff *skb, struct genl_info *info)
4952{ 4232{
4953 struct cfg80211_registered_device *rdev; 4233 struct cfg80211_registered_device *rdev = info->user_ptr[0];
4954 struct wireless_dev *wdev; 4234 struct wireless_dev *wdev;
4955 struct net_device *dev; 4235 struct net_device *dev = info->user_ptr[1];
4956 u8 ps_state; 4236 u8 ps_state;
4957 bool state; 4237 bool state;
4958 int err; 4238 int err;
4959 4239
4960 if (!info->attrs[NL80211_ATTR_PS_STATE]) { 4240 if (!info->attrs[NL80211_ATTR_PS_STATE])
4961 err = -EINVAL; 4241 return -EINVAL;
4962 goto out;
4963 }
4964 4242
4965 ps_state = nla_get_u32(info->attrs[NL80211_ATTR_PS_STATE]); 4243 ps_state = nla_get_u32(info->attrs[NL80211_ATTR_PS_STATE]);
4966 4244
4967 if (ps_state != NL80211_PS_DISABLED && ps_state != NL80211_PS_ENABLED) { 4245 if (ps_state != NL80211_PS_DISABLED && ps_state != NL80211_PS_ENABLED)
4968 err = -EINVAL; 4246 return -EINVAL;
4969 goto out;
4970 }
4971
4972 rtnl_lock();
4973
4974 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
4975 if (err)
4976 goto unlock_rtnl;
4977 4247
4978 wdev = dev->ieee80211_ptr; 4248 wdev = dev->ieee80211_ptr;
4979 4249
4980 if (!rdev->ops->set_power_mgmt) { 4250 if (!rdev->ops->set_power_mgmt)
4981 err = -EOPNOTSUPP; 4251 return -EOPNOTSUPP;
4982 goto unlock_rdev;
4983 }
4984 4252
4985 state = (ps_state == NL80211_PS_ENABLED) ? true : false; 4253 state = (ps_state == NL80211_PS_ENABLED) ? true : false;
4986 4254
4987 if (state == wdev->ps) 4255 if (state == wdev->ps)
4988 goto unlock_rdev; 4256 return 0;
4989
4990 wdev->ps = state;
4991
4992 if (rdev->ops->set_power_mgmt(wdev->wiphy, dev, wdev->ps,
4993 wdev->ps_timeout))
4994 /* assume this means it's off */
4995 wdev->ps = false;
4996
4997unlock_rdev:
4998 cfg80211_unlock_rdev(rdev);
4999 dev_put(dev);
5000unlock_rtnl:
5001 rtnl_unlock();
5002 4257
5003out: 4258 err = rdev->ops->set_power_mgmt(wdev->wiphy, dev, state,
4259 wdev->ps_timeout);
4260 if (!err)
4261 wdev->ps = state;
5004 return err; 4262 return err;
5005} 4263}
5006 4264
5007static int nl80211_get_power_save(struct sk_buff *skb, struct genl_info *info) 4265static int nl80211_get_power_save(struct sk_buff *skb, struct genl_info *info)
5008{ 4266{
5009 struct cfg80211_registered_device *rdev; 4267 struct cfg80211_registered_device *rdev = info->user_ptr[0];
5010 enum nl80211_ps_state ps_state; 4268 enum nl80211_ps_state ps_state;
5011 struct wireless_dev *wdev; 4269 struct wireless_dev *wdev;
5012 struct net_device *dev; 4270 struct net_device *dev = info->user_ptr[1];
5013 struct sk_buff *msg; 4271 struct sk_buff *msg;
5014 void *hdr; 4272 void *hdr;
5015 int err; 4273 int err;
5016 4274
5017 rtnl_lock();
5018
5019 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
5020 if (err)
5021 goto unlock_rtnl;
5022
5023 wdev = dev->ieee80211_ptr; 4275 wdev = dev->ieee80211_ptr;
5024 4276
5025 if (!rdev->ops->set_power_mgmt) { 4277 if (!rdev->ops->set_power_mgmt)
5026 err = -EOPNOTSUPP; 4278 return -EOPNOTSUPP;
5027 goto out;
5028 }
5029 4279
5030 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 4280 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
5031 if (!msg) { 4281 if (!msg)
5032 err = -ENOMEM; 4282 return -ENOMEM;
5033 goto out;
5034 }
5035 4283
5036 hdr = nl80211hdr_put(msg, info->snd_pid, info->snd_seq, 0, 4284 hdr = nl80211hdr_put(msg, info->snd_pid, info->snd_seq, 0,
5037 NL80211_CMD_GET_POWER_SAVE); 4285 NL80211_CMD_GET_POWER_SAVE);
5038 if (!hdr) { 4286 if (!hdr) {
5039 err = -ENOMEM; 4287 err = -ENOBUFS;
5040 goto free_msg; 4288 goto free_msg;
5041 } 4289 }
5042 4290
@@ -5048,22 +4296,12 @@ static int nl80211_get_power_save(struct sk_buff *skb, struct genl_info *info)
5048 NLA_PUT_U32(msg, NL80211_ATTR_PS_STATE, ps_state); 4296 NLA_PUT_U32(msg, NL80211_ATTR_PS_STATE, ps_state);
5049 4297
5050 genlmsg_end(msg, hdr); 4298 genlmsg_end(msg, hdr);
5051 err = genlmsg_reply(msg, info); 4299 return genlmsg_reply(msg, info);
5052 goto out;
5053 4300
5054nla_put_failure: 4301 nla_put_failure:
5055 err = -ENOBUFS; 4302 err = -ENOBUFS;
5056 4303 free_msg:
5057free_msg:
5058 nlmsg_free(msg); 4304 nlmsg_free(msg);
5059
5060out:
5061 cfg80211_unlock_rdev(rdev);
5062 dev_put(dev);
5063
5064unlock_rtnl:
5065 rtnl_unlock();
5066
5067 return err; 4305 return err;
5068} 4306}
5069 4307
@@ -5077,42 +4315,24 @@ nl80211_attr_cqm_policy[NL80211_ATTR_CQM_MAX + 1] __read_mostly = {
5077static int nl80211_set_cqm_rssi(struct genl_info *info, 4315static int nl80211_set_cqm_rssi(struct genl_info *info,
5078 s32 threshold, u32 hysteresis) 4316 s32 threshold, u32 hysteresis)
5079{ 4317{
5080 struct cfg80211_registered_device *rdev; 4318 struct cfg80211_registered_device *rdev = info->user_ptr[0];
5081 struct wireless_dev *wdev; 4319 struct wireless_dev *wdev;
5082 struct net_device *dev; 4320 struct net_device *dev = info->user_ptr[1];
5083 int err;
5084 4321
5085 if (threshold > 0) 4322 if (threshold > 0)
5086 return -EINVAL; 4323 return -EINVAL;
5087 4324
5088 rtnl_lock();
5089
5090 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
5091 if (err)
5092 goto unlock_rdev;
5093
5094 wdev = dev->ieee80211_ptr; 4325 wdev = dev->ieee80211_ptr;
5095 4326
5096 if (!rdev->ops->set_cqm_rssi_config) { 4327 if (!rdev->ops->set_cqm_rssi_config)
5097 err = -EOPNOTSUPP; 4328 return -EOPNOTSUPP;
5098 goto unlock_rdev;
5099 }
5100 4329
5101 if (wdev->iftype != NL80211_IFTYPE_STATION && 4330 if (wdev->iftype != NL80211_IFTYPE_STATION &&
5102 wdev->iftype != NL80211_IFTYPE_P2P_CLIENT) { 4331 wdev->iftype != NL80211_IFTYPE_P2P_CLIENT)
5103 err = -EOPNOTSUPP; 4332 return -EOPNOTSUPP;
5104 goto unlock_rdev;
5105 }
5106
5107 err = rdev->ops->set_cqm_rssi_config(wdev->wiphy, dev,
5108 threshold, hysteresis);
5109
5110unlock_rdev:
5111 cfg80211_unlock_rdev(rdev);
5112 dev_put(dev);
5113 rtnl_unlock();
5114 4333
5115 return err; 4334 return rdev->ops->set_cqm_rssi_config(wdev->wiphy, dev,
4335 threshold, hysteresis);
5116} 4336}
5117 4337
5118static int nl80211_set_cqm(struct sk_buff *skb, struct genl_info *info) 4338static int nl80211_set_cqm(struct sk_buff *skb, struct genl_info *info)
@@ -5146,6 +4366,65 @@ out:
5146 return err; 4366 return err;
5147} 4367}
5148 4368
4369#define NL80211_FLAG_NEED_WIPHY 0x01
4370#define NL80211_FLAG_NEED_NETDEV 0x02
4371#define NL80211_FLAG_NEED_RTNL 0x04
4372#define NL80211_FLAG_CHECK_NETDEV_UP 0x08
4373#define NL80211_FLAG_NEED_NETDEV_UP (NL80211_FLAG_NEED_NETDEV |\
4374 NL80211_FLAG_CHECK_NETDEV_UP)
4375
4376static int nl80211_pre_doit(struct genl_ops *ops, struct sk_buff *skb,
4377 struct genl_info *info)
4378{
4379 struct cfg80211_registered_device *rdev;
4380 struct net_device *dev;
4381 int err;
4382 bool rtnl = ops->internal_flags & NL80211_FLAG_NEED_RTNL;
4383
4384 if (rtnl)
4385 rtnl_lock();
4386
4387 if (ops->internal_flags & NL80211_FLAG_NEED_WIPHY) {
4388 rdev = cfg80211_get_dev_from_info(info);
4389 if (IS_ERR(rdev)) {
4390 if (rtnl)
4391 rtnl_unlock();
4392 return PTR_ERR(rdev);
4393 }
4394 info->user_ptr[0] = rdev;
4395 } else if (ops->internal_flags & NL80211_FLAG_NEED_NETDEV) {
4396 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
4397 if (err) {
4398 if (rtnl)
4399 rtnl_unlock();
4400 return err;
4401 }
4402 if (ops->internal_flags & NL80211_FLAG_CHECK_NETDEV_UP &&
4403 !netif_running(dev)) {
4404 cfg80211_unlock_rdev(rdev);
4405 dev_put(dev);
4406 if (rtnl)
4407 rtnl_unlock();
4408 return -ENETDOWN;
4409 }
4410 info->user_ptr[0] = rdev;
4411 info->user_ptr[1] = dev;
4412 }
4413
4414 return 0;
4415}
4416
4417static void nl80211_post_doit(struct genl_ops *ops, struct sk_buff *skb,
4418 struct genl_info *info)
4419{
4420 if (info->user_ptr[0])
4421 cfg80211_unlock_rdev(info->user_ptr[0]);
4422 if (info->user_ptr[1])
4423 dev_put(info->user_ptr[1]);
4424 if (ops->internal_flags & NL80211_FLAG_NEED_RTNL)
4425 rtnl_unlock();
4426}
4427
5149static struct genl_ops nl80211_ops[] = { 4428static struct genl_ops nl80211_ops[] = {
5150 { 4429 {
5151 .cmd = NL80211_CMD_GET_WIPHY, 4430 .cmd = NL80211_CMD_GET_WIPHY,
@@ -5153,12 +4432,14 @@ static struct genl_ops nl80211_ops[] = {
5153 .dumpit = nl80211_dump_wiphy, 4432 .dumpit = nl80211_dump_wiphy,
5154 .policy = nl80211_policy, 4433 .policy = nl80211_policy,
5155 /* can be retrieved by unprivileged users */ 4434 /* can be retrieved by unprivileged users */
4435 .internal_flags = NL80211_FLAG_NEED_WIPHY,
5156 }, 4436 },
5157 { 4437 {
5158 .cmd = NL80211_CMD_SET_WIPHY, 4438 .cmd = NL80211_CMD_SET_WIPHY,
5159 .doit = nl80211_set_wiphy, 4439 .doit = nl80211_set_wiphy,
5160 .policy = nl80211_policy, 4440 .policy = nl80211_policy,
5161 .flags = GENL_ADMIN_PERM, 4441 .flags = GENL_ADMIN_PERM,
4442 .internal_flags = NL80211_FLAG_NEED_RTNL,
5162 }, 4443 },
5163 { 4444 {
5164 .cmd = NL80211_CMD_GET_INTERFACE, 4445 .cmd = NL80211_CMD_GET_INTERFACE,
@@ -5166,90 +4447,119 @@ static struct genl_ops nl80211_ops[] = {
5166 .dumpit = nl80211_dump_interface, 4447 .dumpit = nl80211_dump_interface,
5167 .policy = nl80211_policy, 4448 .policy = nl80211_policy,
5168 /* can be retrieved by unprivileged users */ 4449 /* can be retrieved by unprivileged users */
4450 .internal_flags = NL80211_FLAG_NEED_NETDEV,
5169 }, 4451 },
5170 { 4452 {
5171 .cmd = NL80211_CMD_SET_INTERFACE, 4453 .cmd = NL80211_CMD_SET_INTERFACE,
5172 .doit = nl80211_set_interface, 4454 .doit = nl80211_set_interface,
5173 .policy = nl80211_policy, 4455 .policy = nl80211_policy,
5174 .flags = GENL_ADMIN_PERM, 4456 .flags = GENL_ADMIN_PERM,
4457 .internal_flags = NL80211_FLAG_NEED_NETDEV |
4458 NL80211_FLAG_NEED_RTNL,
5175 }, 4459 },
5176 { 4460 {
5177 .cmd = NL80211_CMD_NEW_INTERFACE, 4461 .cmd = NL80211_CMD_NEW_INTERFACE,
5178 .doit = nl80211_new_interface, 4462 .doit = nl80211_new_interface,
5179 .policy = nl80211_policy, 4463 .policy = nl80211_policy,
5180 .flags = GENL_ADMIN_PERM, 4464 .flags = GENL_ADMIN_PERM,
4465 .internal_flags = NL80211_FLAG_NEED_WIPHY |
4466 NL80211_FLAG_NEED_RTNL,
5181 }, 4467 },
5182 { 4468 {
5183 .cmd = NL80211_CMD_DEL_INTERFACE, 4469 .cmd = NL80211_CMD_DEL_INTERFACE,
5184 .doit = nl80211_del_interface, 4470 .doit = nl80211_del_interface,
5185 .policy = nl80211_policy, 4471 .policy = nl80211_policy,
5186 .flags = GENL_ADMIN_PERM, 4472 .flags = GENL_ADMIN_PERM,
4473 .internal_flags = NL80211_FLAG_NEED_NETDEV |
4474 NL80211_FLAG_NEED_RTNL,
5187 }, 4475 },
5188 { 4476 {
5189 .cmd = NL80211_CMD_GET_KEY, 4477 .cmd = NL80211_CMD_GET_KEY,
5190 .doit = nl80211_get_key, 4478 .doit = nl80211_get_key,
5191 .policy = nl80211_policy, 4479 .policy = nl80211_policy,
5192 .flags = GENL_ADMIN_PERM, 4480 .flags = GENL_ADMIN_PERM,
4481 .internal_flags = NL80211_FLAG_NEED_NETDEV |
4482 NL80211_FLAG_NEED_RTNL,
5193 }, 4483 },
5194 { 4484 {
5195 .cmd = NL80211_CMD_SET_KEY, 4485 .cmd = NL80211_CMD_SET_KEY,
5196 .doit = nl80211_set_key, 4486 .doit = nl80211_set_key,
5197 .policy = nl80211_policy, 4487 .policy = nl80211_policy,
5198 .flags = GENL_ADMIN_PERM, 4488 .flags = GENL_ADMIN_PERM,
4489 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4490 NL80211_FLAG_NEED_RTNL,
5199 }, 4491 },
5200 { 4492 {
5201 .cmd = NL80211_CMD_NEW_KEY, 4493 .cmd = NL80211_CMD_NEW_KEY,
5202 .doit = nl80211_new_key, 4494 .doit = nl80211_new_key,
5203 .policy = nl80211_policy, 4495 .policy = nl80211_policy,
5204 .flags = GENL_ADMIN_PERM, 4496 .flags = GENL_ADMIN_PERM,
4497 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4498 NL80211_FLAG_NEED_RTNL,
5205 }, 4499 },
5206 { 4500 {
5207 .cmd = NL80211_CMD_DEL_KEY, 4501 .cmd = NL80211_CMD_DEL_KEY,
5208 .doit = nl80211_del_key, 4502 .doit = nl80211_del_key,
5209 .policy = nl80211_policy, 4503 .policy = nl80211_policy,
5210 .flags = GENL_ADMIN_PERM, 4504 .flags = GENL_ADMIN_PERM,
4505 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4506 NL80211_FLAG_NEED_RTNL,
5211 }, 4507 },
5212 { 4508 {
5213 .cmd = NL80211_CMD_SET_BEACON, 4509 .cmd = NL80211_CMD_SET_BEACON,
5214 .policy = nl80211_policy, 4510 .policy = nl80211_policy,
5215 .flags = GENL_ADMIN_PERM, 4511 .flags = GENL_ADMIN_PERM,
5216 .doit = nl80211_addset_beacon, 4512 .doit = nl80211_addset_beacon,
4513 .internal_flags = NL80211_FLAG_NEED_NETDEV |
4514 NL80211_FLAG_NEED_RTNL,
5217 }, 4515 },
5218 { 4516 {
5219 .cmd = NL80211_CMD_NEW_BEACON, 4517 .cmd = NL80211_CMD_NEW_BEACON,
5220 .policy = nl80211_policy, 4518 .policy = nl80211_policy,
5221 .flags = GENL_ADMIN_PERM, 4519 .flags = GENL_ADMIN_PERM,
5222 .doit = nl80211_addset_beacon, 4520 .doit = nl80211_addset_beacon,
4521 .internal_flags = NL80211_FLAG_NEED_NETDEV |
4522 NL80211_FLAG_NEED_RTNL,
5223 }, 4523 },
5224 { 4524 {
5225 .cmd = NL80211_CMD_DEL_BEACON, 4525 .cmd = NL80211_CMD_DEL_BEACON,
5226 .policy = nl80211_policy, 4526 .policy = nl80211_policy,
5227 .flags = GENL_ADMIN_PERM, 4527 .flags = GENL_ADMIN_PERM,
5228 .doit = nl80211_del_beacon, 4528 .doit = nl80211_del_beacon,
4529 .internal_flags = NL80211_FLAG_NEED_NETDEV |
4530 NL80211_FLAG_NEED_RTNL,
5229 }, 4531 },
5230 { 4532 {
5231 .cmd = NL80211_CMD_GET_STATION, 4533 .cmd = NL80211_CMD_GET_STATION,
5232 .doit = nl80211_get_station, 4534 .doit = nl80211_get_station,
5233 .dumpit = nl80211_dump_station, 4535 .dumpit = nl80211_dump_station,
5234 .policy = nl80211_policy, 4536 .policy = nl80211_policy,
4537 .internal_flags = NL80211_FLAG_NEED_NETDEV |
4538 NL80211_FLAG_NEED_RTNL,
5235 }, 4539 },
5236 { 4540 {
5237 .cmd = NL80211_CMD_SET_STATION, 4541 .cmd = NL80211_CMD_SET_STATION,
5238 .doit = nl80211_set_station, 4542 .doit = nl80211_set_station,
5239 .policy = nl80211_policy, 4543 .policy = nl80211_policy,
5240 .flags = GENL_ADMIN_PERM, 4544 .flags = GENL_ADMIN_PERM,
4545 .internal_flags = NL80211_FLAG_NEED_NETDEV |
4546 NL80211_FLAG_NEED_RTNL,
5241 }, 4547 },
5242 { 4548 {
5243 .cmd = NL80211_CMD_NEW_STATION, 4549 .cmd = NL80211_CMD_NEW_STATION,
5244 .doit = nl80211_new_station, 4550 .doit = nl80211_new_station,
5245 .policy = nl80211_policy, 4551 .policy = nl80211_policy,
5246 .flags = GENL_ADMIN_PERM, 4552 .flags = GENL_ADMIN_PERM,
4553 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4554 NL80211_FLAG_NEED_RTNL,
5247 }, 4555 },
5248 { 4556 {
5249 .cmd = NL80211_CMD_DEL_STATION, 4557 .cmd = NL80211_CMD_DEL_STATION,
5250 .doit = nl80211_del_station, 4558 .doit = nl80211_del_station,
5251 .policy = nl80211_policy, 4559 .policy = nl80211_policy,
5252 .flags = GENL_ADMIN_PERM, 4560 .flags = GENL_ADMIN_PERM,
4561 .internal_flags = NL80211_FLAG_NEED_NETDEV |
4562 NL80211_FLAG_NEED_RTNL,
5253 }, 4563 },
5254 { 4564 {
5255 .cmd = NL80211_CMD_GET_MPATH, 4565 .cmd = NL80211_CMD_GET_MPATH,
@@ -5257,30 +4567,40 @@ static struct genl_ops nl80211_ops[] = {
5257 .dumpit = nl80211_dump_mpath, 4567 .dumpit = nl80211_dump_mpath,
5258 .policy = nl80211_policy, 4568 .policy = nl80211_policy,
5259 .flags = GENL_ADMIN_PERM, 4569 .flags = GENL_ADMIN_PERM,
4570 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4571 NL80211_FLAG_NEED_RTNL,
5260 }, 4572 },
5261 { 4573 {
5262 .cmd = NL80211_CMD_SET_MPATH, 4574 .cmd = NL80211_CMD_SET_MPATH,
5263 .doit = nl80211_set_mpath, 4575 .doit = nl80211_set_mpath,
5264 .policy = nl80211_policy, 4576 .policy = nl80211_policy,
5265 .flags = GENL_ADMIN_PERM, 4577 .flags = GENL_ADMIN_PERM,
4578 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4579 NL80211_FLAG_NEED_RTNL,
5266 }, 4580 },
5267 { 4581 {
5268 .cmd = NL80211_CMD_NEW_MPATH, 4582 .cmd = NL80211_CMD_NEW_MPATH,
5269 .doit = nl80211_new_mpath, 4583 .doit = nl80211_new_mpath,
5270 .policy = nl80211_policy, 4584 .policy = nl80211_policy,
5271 .flags = GENL_ADMIN_PERM, 4585 .flags = GENL_ADMIN_PERM,
4586 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4587 NL80211_FLAG_NEED_RTNL,
5272 }, 4588 },
5273 { 4589 {
5274 .cmd = NL80211_CMD_DEL_MPATH, 4590 .cmd = NL80211_CMD_DEL_MPATH,
5275 .doit = nl80211_del_mpath, 4591 .doit = nl80211_del_mpath,
5276 .policy = nl80211_policy, 4592 .policy = nl80211_policy,
5277 .flags = GENL_ADMIN_PERM, 4593 .flags = GENL_ADMIN_PERM,
4594 .internal_flags = NL80211_FLAG_NEED_NETDEV |
4595 NL80211_FLAG_NEED_RTNL,
5278 }, 4596 },
5279 { 4597 {
5280 .cmd = NL80211_CMD_SET_BSS, 4598 .cmd = NL80211_CMD_SET_BSS,
5281 .doit = nl80211_set_bss, 4599 .doit = nl80211_set_bss,
5282 .policy = nl80211_policy, 4600 .policy = nl80211_policy,
5283 .flags = GENL_ADMIN_PERM, 4601 .flags = GENL_ADMIN_PERM,
4602 .internal_flags = NL80211_FLAG_NEED_NETDEV |
4603 NL80211_FLAG_NEED_RTNL,
5284 }, 4604 },
5285 { 4605 {
5286 .cmd = NL80211_CMD_GET_REG, 4606 .cmd = NL80211_CMD_GET_REG,
@@ -5305,18 +4625,24 @@ static struct genl_ops nl80211_ops[] = {
5305 .doit = nl80211_get_mesh_params, 4625 .doit = nl80211_get_mesh_params,
5306 .policy = nl80211_policy, 4626 .policy = nl80211_policy,
5307 /* can be retrieved by unprivileged users */ 4627 /* can be retrieved by unprivileged users */
4628 .internal_flags = NL80211_FLAG_NEED_NETDEV |
4629 NL80211_FLAG_NEED_RTNL,
5308 }, 4630 },
5309 { 4631 {
5310 .cmd = NL80211_CMD_SET_MESH_PARAMS, 4632 .cmd = NL80211_CMD_SET_MESH_PARAMS,
5311 .doit = nl80211_set_mesh_params, 4633 .doit = nl80211_set_mesh_params,
5312 .policy = nl80211_policy, 4634 .policy = nl80211_policy,
5313 .flags = GENL_ADMIN_PERM, 4635 .flags = GENL_ADMIN_PERM,
4636 .internal_flags = NL80211_FLAG_NEED_NETDEV |
4637 NL80211_FLAG_NEED_RTNL,
5314 }, 4638 },
5315 { 4639 {
5316 .cmd = NL80211_CMD_TRIGGER_SCAN, 4640 .cmd = NL80211_CMD_TRIGGER_SCAN,
5317 .doit = nl80211_trigger_scan, 4641 .doit = nl80211_trigger_scan,
5318 .policy = nl80211_policy, 4642 .policy = nl80211_policy,
5319 .flags = GENL_ADMIN_PERM, 4643 .flags = GENL_ADMIN_PERM,
4644 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4645 NL80211_FLAG_NEED_RTNL,
5320 }, 4646 },
5321 { 4647 {
5322 .cmd = NL80211_CMD_GET_SCAN, 4648 .cmd = NL80211_CMD_GET_SCAN,
@@ -5328,36 +4654,48 @@ static struct genl_ops nl80211_ops[] = {
5328 .doit = nl80211_authenticate, 4654 .doit = nl80211_authenticate,
5329 .policy = nl80211_policy, 4655 .policy = nl80211_policy,
5330 .flags = GENL_ADMIN_PERM, 4656 .flags = GENL_ADMIN_PERM,
4657 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4658 NL80211_FLAG_NEED_RTNL,
5331 }, 4659 },
5332 { 4660 {
5333 .cmd = NL80211_CMD_ASSOCIATE, 4661 .cmd = NL80211_CMD_ASSOCIATE,
5334 .doit = nl80211_associate, 4662 .doit = nl80211_associate,
5335 .policy = nl80211_policy, 4663 .policy = nl80211_policy,
5336 .flags = GENL_ADMIN_PERM, 4664 .flags = GENL_ADMIN_PERM,
4665 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4666 NL80211_FLAG_NEED_RTNL,
5337 }, 4667 },
5338 { 4668 {
5339 .cmd = NL80211_CMD_DEAUTHENTICATE, 4669 .cmd = NL80211_CMD_DEAUTHENTICATE,
5340 .doit = nl80211_deauthenticate, 4670 .doit = nl80211_deauthenticate,
5341 .policy = nl80211_policy, 4671 .policy = nl80211_policy,
5342 .flags = GENL_ADMIN_PERM, 4672 .flags = GENL_ADMIN_PERM,
4673 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4674 NL80211_FLAG_NEED_RTNL,
5343 }, 4675 },
5344 { 4676 {
5345 .cmd = NL80211_CMD_DISASSOCIATE, 4677 .cmd = NL80211_CMD_DISASSOCIATE,
5346 .doit = nl80211_disassociate, 4678 .doit = nl80211_disassociate,
5347 .policy = nl80211_policy, 4679 .policy = nl80211_policy,
5348 .flags = GENL_ADMIN_PERM, 4680 .flags = GENL_ADMIN_PERM,
4681 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4682 NL80211_FLAG_NEED_RTNL,
5349 }, 4683 },
5350 { 4684 {
5351 .cmd = NL80211_CMD_JOIN_IBSS, 4685 .cmd = NL80211_CMD_JOIN_IBSS,
5352 .doit = nl80211_join_ibss, 4686 .doit = nl80211_join_ibss,
5353 .policy = nl80211_policy, 4687 .policy = nl80211_policy,
5354 .flags = GENL_ADMIN_PERM, 4688 .flags = GENL_ADMIN_PERM,
4689 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4690 NL80211_FLAG_NEED_RTNL,
5355 }, 4691 },
5356 { 4692 {
5357 .cmd = NL80211_CMD_LEAVE_IBSS, 4693 .cmd = NL80211_CMD_LEAVE_IBSS,
5358 .doit = nl80211_leave_ibss, 4694 .doit = nl80211_leave_ibss,
5359 .policy = nl80211_policy, 4695 .policy = nl80211_policy,
5360 .flags = GENL_ADMIN_PERM, 4696 .flags = GENL_ADMIN_PERM,
4697 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4698 NL80211_FLAG_NEED_RTNL,
5361 }, 4699 },
5362#ifdef CONFIG_NL80211_TESTMODE 4700#ifdef CONFIG_NL80211_TESTMODE
5363 { 4701 {
@@ -5365,6 +4703,8 @@ static struct genl_ops nl80211_ops[] = {
5365 .doit = nl80211_testmode_do, 4703 .doit = nl80211_testmode_do,
5366 .policy = nl80211_policy, 4704 .policy = nl80211_policy,
5367 .flags = GENL_ADMIN_PERM, 4705 .flags = GENL_ADMIN_PERM,
4706 .internal_flags = NL80211_FLAG_NEED_WIPHY |
4707 NL80211_FLAG_NEED_RTNL,
5368 }, 4708 },
5369#endif 4709#endif
5370 { 4710 {
@@ -5372,18 +4712,24 @@ static struct genl_ops nl80211_ops[] = {
5372 .doit = nl80211_connect, 4712 .doit = nl80211_connect,
5373 .policy = nl80211_policy, 4713 .policy = nl80211_policy,
5374 .flags = GENL_ADMIN_PERM, 4714 .flags = GENL_ADMIN_PERM,
4715 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4716 NL80211_FLAG_NEED_RTNL,
5375 }, 4717 },
5376 { 4718 {
5377 .cmd = NL80211_CMD_DISCONNECT, 4719 .cmd = NL80211_CMD_DISCONNECT,
5378 .doit = nl80211_disconnect, 4720 .doit = nl80211_disconnect,
5379 .policy = nl80211_policy, 4721 .policy = nl80211_policy,
5380 .flags = GENL_ADMIN_PERM, 4722 .flags = GENL_ADMIN_PERM,
4723 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4724 NL80211_FLAG_NEED_RTNL,
5381 }, 4725 },
5382 { 4726 {
5383 .cmd = NL80211_CMD_SET_WIPHY_NETNS, 4727 .cmd = NL80211_CMD_SET_WIPHY_NETNS,
5384 .doit = nl80211_wiphy_netns, 4728 .doit = nl80211_wiphy_netns,
5385 .policy = nl80211_policy, 4729 .policy = nl80211_policy,
5386 .flags = GENL_ADMIN_PERM, 4730 .flags = GENL_ADMIN_PERM,
4731 .internal_flags = NL80211_FLAG_NEED_WIPHY |
4732 NL80211_FLAG_NEED_RTNL,
5387 }, 4733 },
5388 { 4734 {
5389 .cmd = NL80211_CMD_GET_SURVEY, 4735 .cmd = NL80211_CMD_GET_SURVEY,
@@ -5395,72 +4741,104 @@ static struct genl_ops nl80211_ops[] = {
5395 .doit = nl80211_setdel_pmksa, 4741 .doit = nl80211_setdel_pmksa,
5396 .policy = nl80211_policy, 4742 .policy = nl80211_policy,
5397 .flags = GENL_ADMIN_PERM, 4743 .flags = GENL_ADMIN_PERM,
4744 .internal_flags = NL80211_FLAG_NEED_NETDEV |
4745 NL80211_FLAG_NEED_RTNL,
5398 }, 4746 },
5399 { 4747 {
5400 .cmd = NL80211_CMD_DEL_PMKSA, 4748 .cmd = NL80211_CMD_DEL_PMKSA,
5401 .doit = nl80211_setdel_pmksa, 4749 .doit = nl80211_setdel_pmksa,
5402 .policy = nl80211_policy, 4750 .policy = nl80211_policy,
5403 .flags = GENL_ADMIN_PERM, 4751 .flags = GENL_ADMIN_PERM,
4752 .internal_flags = NL80211_FLAG_NEED_NETDEV |
4753 NL80211_FLAG_NEED_RTNL,
5404 }, 4754 },
5405 { 4755 {
5406 .cmd = NL80211_CMD_FLUSH_PMKSA, 4756 .cmd = NL80211_CMD_FLUSH_PMKSA,
5407 .doit = nl80211_flush_pmksa, 4757 .doit = nl80211_flush_pmksa,
5408 .policy = nl80211_policy, 4758 .policy = nl80211_policy,
5409 .flags = GENL_ADMIN_PERM, 4759 .flags = GENL_ADMIN_PERM,
4760 .internal_flags = NL80211_FLAG_NEED_NETDEV |
4761 NL80211_FLAG_NEED_RTNL,
5410 }, 4762 },
5411 { 4763 {
5412 .cmd = NL80211_CMD_REMAIN_ON_CHANNEL, 4764 .cmd = NL80211_CMD_REMAIN_ON_CHANNEL,
5413 .doit = nl80211_remain_on_channel, 4765 .doit = nl80211_remain_on_channel,
5414 .policy = nl80211_policy, 4766 .policy = nl80211_policy,
5415 .flags = GENL_ADMIN_PERM, 4767 .flags = GENL_ADMIN_PERM,
4768 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4769 NL80211_FLAG_NEED_RTNL,
5416 }, 4770 },
5417 { 4771 {
5418 .cmd = NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL, 4772 .cmd = NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL,
5419 .doit = nl80211_cancel_remain_on_channel, 4773 .doit = nl80211_cancel_remain_on_channel,
5420 .policy = nl80211_policy, 4774 .policy = nl80211_policy,
5421 .flags = GENL_ADMIN_PERM, 4775 .flags = GENL_ADMIN_PERM,
4776 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4777 NL80211_FLAG_NEED_RTNL,
5422 }, 4778 },
5423 { 4779 {
5424 .cmd = NL80211_CMD_SET_TX_BITRATE_MASK, 4780 .cmd = NL80211_CMD_SET_TX_BITRATE_MASK,
5425 .doit = nl80211_set_tx_bitrate_mask, 4781 .doit = nl80211_set_tx_bitrate_mask,
5426 .policy = nl80211_policy, 4782 .policy = nl80211_policy,
5427 .flags = GENL_ADMIN_PERM, 4783 .flags = GENL_ADMIN_PERM,
4784 .internal_flags = NL80211_FLAG_NEED_NETDEV |
4785 NL80211_FLAG_NEED_RTNL,
5428 }, 4786 },
5429 { 4787 {
5430 .cmd = NL80211_CMD_REGISTER_FRAME, 4788 .cmd = NL80211_CMD_REGISTER_FRAME,
5431 .doit = nl80211_register_mgmt, 4789 .doit = nl80211_register_mgmt,
5432 .policy = nl80211_policy, 4790 .policy = nl80211_policy,
5433 .flags = GENL_ADMIN_PERM, 4791 .flags = GENL_ADMIN_PERM,
4792 .internal_flags = NL80211_FLAG_NEED_NETDEV |
4793 NL80211_FLAG_NEED_RTNL,
5434 }, 4794 },
5435 { 4795 {
5436 .cmd = NL80211_CMD_FRAME, 4796 .cmd = NL80211_CMD_FRAME,
5437 .doit = nl80211_tx_mgmt, 4797 .doit = nl80211_tx_mgmt,
5438 .policy = nl80211_policy, 4798 .policy = nl80211_policy,
5439 .flags = GENL_ADMIN_PERM, 4799 .flags = GENL_ADMIN_PERM,
4800 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4801 NL80211_FLAG_NEED_RTNL,
5440 }, 4802 },
5441 { 4803 {
5442 .cmd = NL80211_CMD_SET_POWER_SAVE, 4804 .cmd = NL80211_CMD_SET_POWER_SAVE,
5443 .doit = nl80211_set_power_save, 4805 .doit = nl80211_set_power_save,
5444 .policy = nl80211_policy, 4806 .policy = nl80211_policy,
5445 .flags = GENL_ADMIN_PERM, 4807 .flags = GENL_ADMIN_PERM,
4808 .internal_flags = NL80211_FLAG_NEED_NETDEV |
4809 NL80211_FLAG_NEED_RTNL,
5446 }, 4810 },
5447 { 4811 {
5448 .cmd = NL80211_CMD_GET_POWER_SAVE, 4812 .cmd = NL80211_CMD_GET_POWER_SAVE,
5449 .doit = nl80211_get_power_save, 4813 .doit = nl80211_get_power_save,
5450 .policy = nl80211_policy, 4814 .policy = nl80211_policy,
5451 /* can be retrieved by unprivileged users */ 4815 /* can be retrieved by unprivileged users */
4816 .internal_flags = NL80211_FLAG_NEED_NETDEV |
4817 NL80211_FLAG_NEED_RTNL,
5452 }, 4818 },
5453 { 4819 {
5454 .cmd = NL80211_CMD_SET_CQM, 4820 .cmd = NL80211_CMD_SET_CQM,
5455 .doit = nl80211_set_cqm, 4821 .doit = nl80211_set_cqm,
5456 .policy = nl80211_policy, 4822 .policy = nl80211_policy,
5457 .flags = GENL_ADMIN_PERM, 4823 .flags = GENL_ADMIN_PERM,
4824 .internal_flags = NL80211_FLAG_NEED_NETDEV |
4825 NL80211_FLAG_NEED_RTNL,
5458 }, 4826 },
5459 { 4827 {
5460 .cmd = NL80211_CMD_SET_CHANNEL, 4828 .cmd = NL80211_CMD_SET_CHANNEL,
5461 .doit = nl80211_set_channel, 4829 .doit = nl80211_set_channel,
5462 .policy = nl80211_policy, 4830 .policy = nl80211_policy,
5463 .flags = GENL_ADMIN_PERM, 4831 .flags = GENL_ADMIN_PERM,
4832 .internal_flags = NL80211_FLAG_NEED_NETDEV |
4833 NL80211_FLAG_NEED_RTNL,
4834 },
4835 {
4836 .cmd = NL80211_CMD_SET_WDS_PEER,
4837 .doit = nl80211_set_wds_peer,
4838 .policy = nl80211_policy,
4839 .flags = GENL_ADMIN_PERM,
4840 .internal_flags = NL80211_FLAG_NEED_NETDEV |
4841 NL80211_FLAG_NEED_RTNL,
5464 }, 4842 },
5465}; 4843};
5466 4844
diff --git a/net/wireless/scan.c b/net/wireless/scan.c
index 5ca8c718014..503ebb86ba1 100644
--- a/net/wireless/scan.c
+++ b/net/wireless/scan.c
@@ -650,14 +650,14 @@ void cfg80211_unlink_bss(struct wiphy *wiphy, struct cfg80211_bss *pub)
650 bss = container_of(pub, struct cfg80211_internal_bss, pub); 650 bss = container_of(pub, struct cfg80211_internal_bss, pub);
651 651
652 spin_lock_bh(&dev->bss_lock); 652 spin_lock_bh(&dev->bss_lock);
653 if (!list_empty(&bss->list)) {
654 list_del_init(&bss->list);
655 dev->bss_generation++;
656 rb_erase(&bss->rbn, &dev->bss_tree);
653 657
654 list_del(&bss->list); 658 kref_put(&bss->ref, bss_release);
655 dev->bss_generation++; 659 }
656 rb_erase(&bss->rbn, &dev->bss_tree);
657
658 spin_unlock_bh(&dev->bss_lock); 660 spin_unlock_bh(&dev->bss_lock);
659
660 kref_put(&bss->ref, bss_release);
661} 661}
662EXPORT_SYMBOL(cfg80211_unlink_bss); 662EXPORT_SYMBOL(cfg80211_unlink_bss);
663 663
diff --git a/net/wireless/sme.c b/net/wireless/sme.c
index f161b984454..e17b0bee6bd 100644
--- a/net/wireless/sme.c
+++ b/net/wireless/sme.c
@@ -698,7 +698,7 @@ void __cfg80211_disconnected(struct net_device *dev, const u8 *ie,
698 */ 698 */
699 if (rdev->ops->del_key) 699 if (rdev->ops->del_key)
700 for (i = 0; i < 6; i++) 700 for (i = 0; i < 6; i++)
701 rdev->ops->del_key(wdev->wiphy, dev, i, NULL); 701 rdev->ops->del_key(wdev->wiphy, dev, i, false, NULL);
702 702
703#ifdef CONFIG_CFG80211_WEXT 703#ifdef CONFIG_CFG80211_WEXT
704 memset(&wrqu, 0, sizeof(wrqu)); 704 memset(&wrqu, 0, sizeof(wrqu));
diff --git a/net/wireless/util.c b/net/wireless/util.c
index fb5448f7d55..76120aeda57 100644
--- a/net/wireless/util.c
+++ b/net/wireless/util.c
@@ -144,19 +144,25 @@ void ieee80211_set_bitrate_flags(struct wiphy *wiphy)
144 144
145int cfg80211_validate_key_settings(struct cfg80211_registered_device *rdev, 145int cfg80211_validate_key_settings(struct cfg80211_registered_device *rdev,
146 struct key_params *params, int key_idx, 146 struct key_params *params, int key_idx,
147 const u8 *mac_addr) 147 bool pairwise, const u8 *mac_addr)
148{ 148{
149 int i; 149 int i;
150 150
151 if (key_idx > 5) 151 if (key_idx > 5)
152 return -EINVAL; 152 return -EINVAL;
153 153
154 if (!pairwise && mac_addr && !(rdev->wiphy.flags & WIPHY_FLAG_IBSS_RSN))
155 return -EINVAL;
156
157 if (pairwise && !mac_addr)
158 return -EINVAL;
159
154 /* 160 /*
155 * Disallow pairwise keys with non-zero index unless it's WEP 161 * Disallow pairwise keys with non-zero index unless it's WEP
156 * (because current deployments use pairwise WEP keys with 162 * (because current deployments use pairwise WEP keys with
157 * non-zero indizes but 802.11i clearly specifies to use zero) 163 * non-zero indizes but 802.11i clearly specifies to use zero)
158 */ 164 */
159 if (mac_addr && key_idx && 165 if (pairwise && key_idx &&
160 params->cipher != WLAN_CIPHER_SUITE_WEP40 && 166 params->cipher != WLAN_CIPHER_SUITE_WEP40 &&
161 params->cipher != WLAN_CIPHER_SUITE_WEP104) 167 params->cipher != WLAN_CIPHER_SUITE_WEP104)
162 return -EINVAL; 168 return -EINVAL;
@@ -677,7 +683,7 @@ void cfg80211_upload_connect_keys(struct wireless_dev *wdev)
677 for (i = 0; i < 6; i++) { 683 for (i = 0; i < 6; i++) {
678 if (!wdev->connect_keys->params[i].cipher) 684 if (!wdev->connect_keys->params[i].cipher)
679 continue; 685 continue;
680 if (rdev->ops->add_key(wdev->wiphy, dev, i, NULL, 686 if (rdev->ops->add_key(wdev->wiphy, dev, i, false, NULL,
681 &wdev->connect_keys->params[i])) { 687 &wdev->connect_keys->params[i])) {
682 printk(KERN_ERR "%s: failed to set key %d\n", 688 printk(KERN_ERR "%s: failed to set key %d\n",
683 dev->name, i); 689 dev->name, i);
diff --git a/net/wireless/wext-compat.c b/net/wireless/wext-compat.c
index 7e5c3a45f81..6002265289c 100644
--- a/net/wireless/wext-compat.c
+++ b/net/wireless/wext-compat.c
@@ -432,14 +432,17 @@ int cfg80211_wext_giwretry(struct net_device *dev,
432EXPORT_SYMBOL_GPL(cfg80211_wext_giwretry); 432EXPORT_SYMBOL_GPL(cfg80211_wext_giwretry);
433 433
434static int __cfg80211_set_encryption(struct cfg80211_registered_device *rdev, 434static int __cfg80211_set_encryption(struct cfg80211_registered_device *rdev,
435 struct net_device *dev, const u8 *addr, 435 struct net_device *dev, bool pairwise,
436 bool remove, bool tx_key, int idx, 436 const u8 *addr, bool remove, bool tx_key,
437 struct key_params *params) 437 int idx, struct key_params *params)
438{ 438{
439 struct wireless_dev *wdev = dev->ieee80211_ptr; 439 struct wireless_dev *wdev = dev->ieee80211_ptr;
440 int err, i; 440 int err, i;
441 bool rejoin = false; 441 bool rejoin = false;
442 442
443 if (pairwise && !addr)
444 return -EINVAL;
445
443 if (!wdev->wext.keys) { 446 if (!wdev->wext.keys) {
444 wdev->wext.keys = kzalloc(sizeof(*wdev->wext.keys), 447 wdev->wext.keys = kzalloc(sizeof(*wdev->wext.keys),
445 GFP_KERNEL); 448 GFP_KERNEL);
@@ -478,7 +481,13 @@ static int __cfg80211_set_encryption(struct cfg80211_registered_device *rdev,
478 __cfg80211_leave_ibss(rdev, wdev->netdev, true); 481 __cfg80211_leave_ibss(rdev, wdev->netdev, true);
479 rejoin = true; 482 rejoin = true;
480 } 483 }
481 err = rdev->ops->del_key(&rdev->wiphy, dev, idx, addr); 484
485 if (!pairwise && addr &&
486 !(rdev->wiphy.flags & WIPHY_FLAG_IBSS_RSN))
487 err = -ENOENT;
488 else
489 err = rdev->ops->del_key(&rdev->wiphy, dev, idx,
490 pairwise, addr);
482 } 491 }
483 wdev->wext.connect.privacy = false; 492 wdev->wext.connect.privacy = false;
484 /* 493 /*
@@ -507,12 +516,13 @@ static int __cfg80211_set_encryption(struct cfg80211_registered_device *rdev,
507 if (addr) 516 if (addr)
508 tx_key = false; 517 tx_key = false;
509 518
510 if (cfg80211_validate_key_settings(rdev, params, idx, addr)) 519 if (cfg80211_validate_key_settings(rdev, params, idx, pairwise, addr))
511 return -EINVAL; 520 return -EINVAL;
512 521
513 err = 0; 522 err = 0;
514 if (wdev->current_bss) 523 if (wdev->current_bss)
515 err = rdev->ops->add_key(&rdev->wiphy, dev, idx, addr, params); 524 err = rdev->ops->add_key(&rdev->wiphy, dev, idx,
525 pairwise, addr, params);
516 if (err) 526 if (err)
517 return err; 527 return err;
518 528
@@ -563,17 +573,17 @@ static int __cfg80211_set_encryption(struct cfg80211_registered_device *rdev,
563} 573}
564 574
565static int cfg80211_set_encryption(struct cfg80211_registered_device *rdev, 575static int cfg80211_set_encryption(struct cfg80211_registered_device *rdev,
566 struct net_device *dev, const u8 *addr, 576 struct net_device *dev, bool pairwise,
567 bool remove, bool tx_key, int idx, 577 const u8 *addr, bool remove, bool tx_key,
568 struct key_params *params) 578 int idx, struct key_params *params)
569{ 579{
570 int err; 580 int err;
571 581
572 /* devlist mutex needed for possible IBSS re-join */ 582 /* devlist mutex needed for possible IBSS re-join */
573 mutex_lock(&rdev->devlist_mtx); 583 mutex_lock(&rdev->devlist_mtx);
574 wdev_lock(dev->ieee80211_ptr); 584 wdev_lock(dev->ieee80211_ptr);
575 err = __cfg80211_set_encryption(rdev, dev, addr, remove, 585 err = __cfg80211_set_encryption(rdev, dev, pairwise, addr,
576 tx_key, idx, params); 586 remove, tx_key, idx, params);
577 wdev_unlock(dev->ieee80211_ptr); 587 wdev_unlock(dev->ieee80211_ptr);
578 mutex_unlock(&rdev->devlist_mtx); 588 mutex_unlock(&rdev->devlist_mtx);
579 589
@@ -635,7 +645,7 @@ int cfg80211_wext_siwencode(struct net_device *dev,
635 else if (!remove) 645 else if (!remove)
636 return -EINVAL; 646 return -EINVAL;
637 647
638 return cfg80211_set_encryption(rdev, dev, NULL, remove, 648 return cfg80211_set_encryption(rdev, dev, false, NULL, remove,
639 wdev->wext.default_key == -1, 649 wdev->wext.default_key == -1,
640 idx, &params); 650 idx, &params);
641} 651}
@@ -725,7 +735,9 @@ int cfg80211_wext_siwencodeext(struct net_device *dev,
725 } 735 }
726 736
727 return cfg80211_set_encryption( 737 return cfg80211_set_encryption(
728 rdev, dev, addr, remove, 738 rdev, dev,
739 !(ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY),
740 addr, remove,
729 ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY, 741 ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY,
730 idx, &params); 742 idx, &params);
731} 743}