Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wirel...
authorJohn W. Linville <linville@tuxdriver.com>
Wed, 8 Jun 2011 17:44:21 +0000 (13:44 -0400)
committerJohn W. Linville <linville@tuxdriver.com>
Wed, 8 Jun 2011 17:44:21 +0000 (13:44 -0400)
133 files changed:
drivers/bcma/Kconfig
drivers/bcma/Makefile
drivers/bcma/bcma_private.h
drivers/bcma/driver_pci.c
drivers/bcma/host_pci.c
drivers/bcma/main.c
drivers/bcma/sprom.c [new file with mode: 0644]
drivers/net/wireless/ath/ath.h
drivers/net/wireless/ath/ath5k/base.c
drivers/net/wireless/ath/ath5k/reset.c
drivers/net/wireless/ath/ath9k/ar9002_mac.c
drivers/net/wireless/ath/ath9k/ar9003_mac.c
drivers/net/wireless/ath/ath9k/ar9003_paprd.c
drivers/net/wireless/ath/ath9k/ath9k.h
drivers/net/wireless/ath/ath9k/beacon.c
drivers/net/wireless/ath/ath9k/debug.c
drivers/net/wireless/ath/ath9k/debug.h
drivers/net/wireless/ath/ath9k/htc_drv_beacon.c
drivers/net/wireless/ath/ath9k/hw-ops.h
drivers/net/wireless/ath/ath9k/hw.c
drivers/net/wireless/ath/ath9k/hw.h
drivers/net/wireless/ath/ath9k/init.c
drivers/net/wireless/ath/ath9k/main.c
drivers/net/wireless/ath/ath9k/xmit.c
drivers/net/wireless/b43/Kconfig
drivers/net/wireless/b43/Makefile
drivers/net/wireless/b43/b43.h
drivers/net/wireless/b43/bus.c [new file with mode: 0644]
drivers/net/wireless/b43/bus.h [new file with mode: 0644]
drivers/net/wireless/b43/dma.c
drivers/net/wireless/b43/leds.c
drivers/net/wireless/b43/lo.c
drivers/net/wireless/b43/main.c
drivers/net/wireless/b43/main.h
drivers/net/wireless/b43/phy_a.c
drivers/net/wireless/b43/phy_common.c
drivers/net/wireless/b43/phy_g.c
drivers/net/wireless/b43/phy_lp.c
drivers/net/wireless/b43/phy_n.c
drivers/net/wireless/b43/pio.c
drivers/net/wireless/b43/rfkill.c
drivers/net/wireless/b43/sdio.c
drivers/net/wireless/b43/sysfs.c
drivers/net/wireless/b43/tables_lpphy.c
drivers/net/wireless/b43/wa.c
drivers/net/wireless/b43/xmit.c
drivers/net/wireless/b43legacy/dma.c
drivers/net/wireless/b43legacy/main.c
drivers/net/wireless/b43legacy/xmit.c
drivers/net/wireless/iwlegacy/iwl-4965-rs.c
drivers/net/wireless/iwlegacy/iwl-4965.c
drivers/net/wireless/iwlegacy/iwl-eeprom.c
drivers/net/wireless/iwlwifi/iwl-1000.c
drivers/net/wireless/iwlwifi/iwl-2000.c
drivers/net/wireless/iwlwifi/iwl-5000.c
drivers/net/wireless/iwlwifi/iwl-6000.c
drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c
drivers/net/wireless/iwlwifi/iwl-agn-lib.c
drivers/net/wireless/iwlwifi/iwl-agn-rs.c
drivers/net/wireless/iwlwifi/iwl-agn-rxon.c
drivers/net/wireless/iwlwifi/iwl-agn-tx.c
drivers/net/wireless/iwlwifi/iwl-agn.c
drivers/net/wireless/iwlwifi/iwl-core.c
drivers/net/wireless/iwlwifi/iwl-core.h
drivers/net/wireless/iwlwifi/iwl-dev.h
drivers/net/wireless/iwlwifi/iwl-rx.c
drivers/net/wireless/iwlwifi/iwl-scan.c
drivers/net/wireless/iwlwifi/iwl-tx.c
drivers/net/wireless/libertas/if_sdio.c
drivers/net/wireless/mac80211_hwsim.c
drivers/net/wireless/mac80211_hwsim.h [new file with mode: 0644]
drivers/net/wireless/mwifiex/11n_aggr.c
drivers/net/wireless/mwifiex/main.c
drivers/net/wireless/mwifiex/main.h
drivers/net/wireless/mwifiex/sdio.c
drivers/net/wireless/mwifiex/sdio.h
drivers/net/wireless/mwifiex/wmm.c
drivers/net/wireless/rt2x00/Kconfig
drivers/net/wireless/rt2x00/rt2800.h
drivers/net/wireless/rt2x00/rt2800lib.c
drivers/net/wireless/rt2x00/rt2800lib.h
drivers/net/wireless/rt2x00/rt2800pci.c
drivers/net/wireless/rt2x00/rt2800usb.c
drivers/net/wireless/rt2x00/rt2x00config.c
drivers/net/wireless/rt2x00/rt2x00dev.c
drivers/net/wireless/rt2x00/rt2x00queue.c
drivers/net/wireless/rtlwifi/base.c
drivers/net/wireless/rtlwifi/efuse.c
drivers/net/wireless/rtlwifi/pci.c
drivers/net/wireless/rtlwifi/ps.c
drivers/net/wireless/rtlwifi/regd.c
drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c
drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c
drivers/net/wireless/rtlwifi/rtl8192ce/hw.c
drivers/net/wireless/rtlwifi/rtl8192ce/phy.c
drivers/net/wireless/rtlwifi/rtl8192ce/trx.c
drivers/net/wireless/rtlwifi/rtl8192cu/mac.c
drivers/net/wireless/rtlwifi/rtl8192cu/phy.c
drivers/net/wireless/rtlwifi/rtl8192se/dm.c
drivers/net/wireless/rtlwifi/rtl8192se/fw.c
drivers/net/wireless/rtlwifi/rtl8192se/hw.c
drivers/net/wireless/rtlwifi/rtl8192se/phy.c
drivers/net/wireless/rtlwifi/rtl8192se/trx.c
drivers/net/wireless/rtlwifi/wifi.h
drivers/net/wireless/wl12xx/boot.c
drivers/net/wireless/wl12xx/event.c
drivers/net/wireless/wl12xx/event.h
drivers/net/wireless/wl12xx/init.c
drivers/net/wireless/wl12xx/main.c
drivers/net/wireless/wl12xx/wl12xx.h
drivers/ssb/driver_pcicore.c
include/linux/bcma/bcma.h
include/linux/bcma/bcma_driver_chipcommon.h
include/linux/cordic.h [new file with mode: 0644]
include/linux/crc8.h [new file with mode: 0644]
include/net/cfg80211.h
include/net/mac80211.h
lib/Kconfig
lib/Makefile
lib/cordic.c [new file with mode: 0644]
lib/crc8.c [new file with mode: 0644]
net/mac80211/agg-rx.c
net/mac80211/cfg.c
net/mac80211/ht.c
net/mac80211/ieee80211_i.h
net/mac80211/iface.c
net/mac80211/key.c
net/mac80211/rc80211_minstrel.c
net/mac80211/rc80211_minstrel.h
net/mac80211/rc80211_minstrel_ht.c
net/mac80211/sta_info.h
net/mac80211/tx.c
net/wireless/nl80211.c

index 353781b5b78b26bd7eeff712a3df1a1e6e77c626..83e9adf46441b549c619bc6c13da391e00781cf2 100644 (file)
@@ -13,6 +13,11 @@ config BCMA
          Bus driver for Broadcom specific Advanced Microcontroller Bus
          Architecture.
 
+# Support for Block-I/O. SELECT this from the driver that needs it.
+config BCMA_BLOCKIO
+       bool
+       depends on BCMA
+
 config BCMA_HOST_PCI_POSSIBLE
        bool
        depends on BCMA && PCI = y
index 0d56245bcb79776657315ac6b3620d6abbfd2173..cde0182bd1dcdb4b1d680b8b3fac1e60840c4956 100644 (file)
@@ -1,4 +1,4 @@
-bcma-y                                 += main.o scan.o core.o
+bcma-y                                 += main.o scan.o core.o sprom.o
 bcma-y                                 += driver_chipcommon.o driver_chipcommon_pmu.o
 bcma-y                                 += driver_pci.o
 bcma-$(CONFIG_BCMA_HOST_PCI)           += host_pci.o
index 2f72e9c585fd966514d8b3598f3e9b5fb0db8519..12a75ab3dd239b503a84826ec5ba7e8d935accd1 100644 (file)
@@ -19,6 +19,9 @@ extern void bcma_bus_unregister(struct bcma_bus *bus);
 /* scan.c */
 int bcma_bus_scan(struct bcma_bus *bus);
 
+/* sprom.c */
+int bcma_sprom_get(struct bcma_bus *bus);
+
 #ifdef CONFIG_BCMA_HOST_PCI
 /* host_pci.c */
 extern int __init bcma_host_pci_init(void);
index e757e4e3c7e29959808376c7d7e5491ffe1e9fcf..789d68b4858baa56872e290e7d4780b258702092 100644 (file)
@@ -161,3 +161,26 @@ void bcma_core_pci_init(struct bcma_drv_pci *pc)
 {
        bcma_pcicore_serdes_workaround(pc);
 }
+
+int bcma_core_pci_irq_ctl(struct bcma_drv_pci *pc, struct bcma_device *core,
+                         bool enable)
+{
+       struct pci_dev *pdev = pc->core->bus->host_pci;
+       u32 coremask, tmp;
+       int err;
+
+       err = pci_read_config_dword(pdev, BCMA_PCI_IRQMASK, &tmp);
+       if (err)
+               goto out;
+
+       coremask = BIT(core->core_index) << 8;
+       if (enable)
+               tmp |= coremask;
+       else
+               tmp &= ~coremask;
+
+       err = pci_write_config_dword(pdev, BCMA_PCI_IRQMASK, tmp);
+
+out:
+       return err;
+}
index 471a04013fe01771bc4b4bf41396af350c50e456..2a526bc3342ffaa05cd9f0cbbbda2b39b0c8272e 100644 (file)
@@ -65,6 +65,54 @@ static void bcma_host_pci_write32(struct bcma_device *core, u16 offset,
        iowrite32(value, core->bus->mmio + offset);
 }
 
+#ifdef CONFIG_BCMA_BLOCKIO
+void bcma_host_pci_block_read(struct bcma_device *core, void *buffer,
+                             size_t count, u16 offset, u8 reg_width)
+{
+       void __iomem *addr = core->bus->mmio + offset;
+       if (core->bus->mapped_core != core)
+               bcma_host_pci_switch_core(core);
+       switch (reg_width) {
+       case sizeof(u8):
+               ioread8_rep(addr, buffer, count);
+               break;
+       case sizeof(u16):
+               WARN_ON(count & 1);
+               ioread16_rep(addr, buffer, count >> 1);
+               break;
+       case sizeof(u32):
+               WARN_ON(count & 3);
+               ioread32_rep(addr, buffer, count >> 2);
+               break;
+       default:
+               WARN_ON(1);
+       }
+}
+
+void bcma_host_pci_block_write(struct bcma_device *core, const void *buffer,
+                              size_t count, u16 offset, u8 reg_width)
+{
+       void __iomem *addr = core->bus->mmio + offset;
+       if (core->bus->mapped_core != core)
+               bcma_host_pci_switch_core(core);
+       switch (reg_width) {
+       case sizeof(u8):
+               iowrite8_rep(addr, buffer, count);
+               break;
+       case sizeof(u16):
+               WARN_ON(count & 1);
+               iowrite16_rep(addr, buffer, count >> 1);
+               break;
+       case sizeof(u32):
+               WARN_ON(count & 3);
+               iowrite32_rep(addr, buffer, count >> 2);
+               break;
+       default:
+               WARN_ON(1);
+       }
+}
+#endif
+
 static u32 bcma_host_pci_aread32(struct bcma_device *core, u16 offset)
 {
        if (core->bus->mapped_core != core)
@@ -87,6 +135,10 @@ const struct bcma_host_ops bcma_host_pci_ops = {
        .write8         = bcma_host_pci_write8,
        .write16        = bcma_host_pci_write16,
        .write32        = bcma_host_pci_write32,
+#ifdef CONFIG_BCMA_BLOCKIO
+       .block_read     = bcma_host_pci_block_read,
+       .block_write    = bcma_host_pci_block_write,
+#endif
        .aread32        = bcma_host_pci_aread32,
        .awrite32       = bcma_host_pci_awrite32,
 };
index be52344ed19d4a1dc905d25ca9b0e478ae1e6c95..11e96dc6011afcc89dd2e72d93a6898b15a97e60 100644 (file)
@@ -89,6 +89,8 @@ static int bcma_register_cores(struct bcma_bus *bus)
                switch (bus->hosttype) {
                case BCMA_HOSTTYPE_PCI:
                        core->dev.parent = &bus->host_pci->dev;
+                       core->dma_dev = &bus->host_pci->dev;
+                       core->irq = bus->host_pci->irq;
                        break;
                case BCMA_HOSTTYPE_NONE:
                case BCMA_HOSTTYPE_SDIO:
@@ -144,6 +146,13 @@ int bcma_bus_register(struct bcma_bus *bus)
                bcma_core_pci_init(&bus->drv_pci);
        }
 
+       /* Try to get SPROM */
+       err = bcma_sprom_get(bus);
+       if (err) {
+               pr_err("Failed to get SPROM: %d\n", err);
+               return -ENOENT;
+       }
+
        /* Register found cores */
        bcma_register_cores(bus);
 
diff --git a/drivers/bcma/sprom.c b/drivers/bcma/sprom.c
new file mode 100644 (file)
index 0000000..ffbb0e3
--- /dev/null
@@ -0,0 +1,162 @@
+/*
+ * Broadcom specific AMBA
+ * SPROM reading
+ *
+ * Licensed under the GNU/GPL. See COPYING for details.
+ */
+
+#include "bcma_private.h"
+
+#include <linux/bcma/bcma.h>
+#include <linux/bcma/bcma_regs.h>
+#include <linux/pci.h>
+#include <linux/io.h>
+#include <linux/dma-mapping.h>
+#include <linux/slab.h>
+
+#define SPOFF(offset)  ((offset) / sizeof(u16))
+
+/**************************************************
+ * R/W ops.
+ **************************************************/
+
+static void bcma_sprom_read(struct bcma_bus *bus, u16 *sprom)
+{
+       int i;
+       for (i = 0; i < SSB_SPROMSIZE_WORDS_R4; i++)
+               sprom[i] = bcma_read16(bus->drv_cc.core,
+                                      BCMA_CC_SPROM + (i * 2));
+}
+
+/**************************************************
+ * Validation.
+ **************************************************/
+
+static inline u8 bcma_crc8(u8 crc, u8 data)
+{
+       /* Polynomial:   x^8 + x^7 + x^6 + x^4 + x^2 + 1   */
+       static const u8 t[] = {
+               0x00, 0xF7, 0xB9, 0x4E, 0x25, 0xD2, 0x9C, 0x6B,
+               0x4A, 0xBD, 0xF3, 0x04, 0x6F, 0x98, 0xD6, 0x21,
+               0x94, 0x63, 0x2D, 0xDA, 0xB1, 0x46, 0x08, 0xFF,
+               0xDE, 0x29, 0x67, 0x90, 0xFB, 0x0C, 0x42, 0xB5,
+               0x7F, 0x88, 0xC6, 0x31, 0x5A, 0xAD, 0xE3, 0x14,
+               0x35, 0xC2, 0x8C, 0x7B, 0x10, 0xE7, 0xA9, 0x5E,
+               0xEB, 0x1C, 0x52, 0xA5, 0xCE, 0x39, 0x77, 0x80,
+               0xA1, 0x56, 0x18, 0xEF, 0x84, 0x73, 0x3D, 0xCA,
+               0xFE, 0x09, 0x47, 0xB0, 0xDB, 0x2C, 0x62, 0x95,
+               0xB4, 0x43, 0x0D, 0xFA, 0x91, 0x66, 0x28, 0xDF,
+               0x6A, 0x9D, 0xD3, 0x24, 0x4F, 0xB8, 0xF6, 0x01,
+               0x20, 0xD7, 0x99, 0x6E, 0x05, 0xF2, 0xBC, 0x4B,
+               0x81, 0x76, 0x38, 0xCF, 0xA4, 0x53, 0x1D, 0xEA,
+               0xCB, 0x3C, 0x72, 0x85, 0xEE, 0x19, 0x57, 0xA0,
+               0x15, 0xE2, 0xAC, 0x5B, 0x30, 0xC7, 0x89, 0x7E,
+               0x5F, 0xA8, 0xE6, 0x11, 0x7A, 0x8D, 0xC3, 0x34,
+               0xAB, 0x5C, 0x12, 0xE5, 0x8E, 0x79, 0x37, 0xC0,
+               0xE1, 0x16, 0x58, 0xAF, 0xC4, 0x33, 0x7D, 0x8A,
+               0x3F, 0xC8, 0x86, 0x71, 0x1A, 0xED, 0xA3, 0x54,
+               0x75, 0x82, 0xCC, 0x3B, 0x50, 0xA7, 0xE9, 0x1E,
+               0xD4, 0x23, 0x6D, 0x9A, 0xF1, 0x06, 0x48, 0xBF,
+               0x9E, 0x69, 0x27, 0xD0, 0xBB, 0x4C, 0x02, 0xF5,
+               0x40, 0xB7, 0xF9, 0x0E, 0x65, 0x92, 0xDC, 0x2B,
+               0x0A, 0xFD, 0xB3, 0x44, 0x2F, 0xD8, 0x96, 0x61,
+               0x55, 0xA2, 0xEC, 0x1B, 0x70, 0x87, 0xC9, 0x3E,
+               0x1F, 0xE8, 0xA6, 0x51, 0x3A, 0xCD, 0x83, 0x74,
+               0xC1, 0x36, 0x78, 0x8F, 0xE4, 0x13, 0x5D, 0xAA,
+               0x8B, 0x7C, 0x32, 0xC5, 0xAE, 0x59, 0x17, 0xE0,
+               0x2A, 0xDD, 0x93, 0x64, 0x0F, 0xF8, 0xB6, 0x41,
+               0x60, 0x97, 0xD9, 0x2E, 0x45, 0xB2, 0xFC, 0x0B,
+               0xBE, 0x49, 0x07, 0xF0, 0x9B, 0x6C, 0x22, 0xD5,
+               0xF4, 0x03, 0x4D, 0xBA, 0xD1, 0x26, 0x68, 0x9F,
+       };
+       return t[crc ^ data];
+}
+
+static u8 bcma_sprom_crc(const u16 *sprom)
+{
+       int word;
+       u8 crc = 0xFF;
+
+       for (word = 0; word < SSB_SPROMSIZE_WORDS_R4 - 1; word++) {
+               crc = bcma_crc8(crc, sprom[word] & 0x00FF);
+               crc = bcma_crc8(crc, (sprom[word] & 0xFF00) >> 8);
+       }
+       crc = bcma_crc8(crc, sprom[SSB_SPROMSIZE_WORDS_R4 - 1] & 0x00FF);
+       crc ^= 0xFF;
+
+       return crc;
+}
+
+static int bcma_sprom_check_crc(const u16 *sprom)
+{
+       u8 crc;
+       u8 expected_crc;
+       u16 tmp;
+
+       crc = bcma_sprom_crc(sprom);
+       tmp = sprom[SSB_SPROMSIZE_WORDS_R4 - 1] & SSB_SPROM_REVISION_CRC;
+       expected_crc = tmp >> SSB_SPROM_REVISION_CRC_SHIFT;
+       if (crc != expected_crc)
+               return -EPROTO;
+
+       return 0;
+}
+
+static int bcma_sprom_valid(const u16 *sprom)
+{
+       u16 revision;
+       int err;
+
+       err = bcma_sprom_check_crc(sprom);
+       if (err)
+               return err;
+
+       revision = sprom[SSB_SPROMSIZE_WORDS_R4 - 1] & SSB_SPROM_REVISION_REV;
+       if (revision != 8) {
+               pr_err("Unsupported SPROM revision: %d\n", revision);
+               return -ENOENT;
+       }
+
+       return 0;
+}
+
+/**************************************************
+ * SPROM extraction.
+ **************************************************/
+
+static void bcma_sprom_extract_r8(struct bcma_bus *bus, const u16 *sprom)
+{
+       u16 v;
+       int i;
+
+       for (i = 0; i < 3; i++) {
+               v = sprom[SPOFF(SSB_SPROM8_IL0MAC) + i];
+               *(((__be16 *)bus->sprom.il0mac) + i) = cpu_to_be16(v);
+       }
+}
+
+int bcma_sprom_get(struct bcma_bus *bus)
+{
+       u16 *sprom;
+       int err = 0;
+
+       if (!bus->drv_cc.core)
+               return -EOPNOTSUPP;
+
+       sprom = kcalloc(SSB_SPROMSIZE_WORDS_R4, sizeof(u16),
+                       GFP_KERNEL);
+       if (!sprom)
+               return -ENOMEM;
+
+       bcma_sprom_read(bus, sprom);
+
+       err = bcma_sprom_valid(sprom);
+       if (err)
+               goto out;
+
+       bcma_sprom_extract_r8(bus, sprom);
+
+out:
+       kfree(sprom);
+       return err;
+}
index 7cf4317a2a84b35dc8c19c277746aec8345220e1..17c4b56c3874306eab45aea4d927c5b2915946d6 100644 (file)
@@ -161,6 +161,7 @@ struct ath_common {
        const struct ath_bus_ops *bus_ops;
 
        bool btcoex_enabled;
+       bool disable_ani;
 };
 
 struct sk_buff *ath_rxbuf_alloc(struct ath_common *common,
index 22047628ccfa83bbd59242c511192e52ab04a12e..b6c5d3715b963e73f6b962070f6e78256449d107 100644 (file)
@@ -72,6 +72,11 @@ static int modparam_all_channels;
 module_param_named(all_channels, modparam_all_channels, bool, S_IRUGO);
 MODULE_PARM_DESC(all_channels, "Expose all channels the device can use.");
 
+static int modparam_fastchanswitch;
+module_param_named(fastchanswitch, modparam_fastchanswitch, bool, S_IRUGO);
+MODULE_PARM_DESC(fastchanswitch, "Enable fast channel switching for AR2413/AR5413 radios.");
+
+
 /* Module info */
 MODULE_AUTHOR("Jiri Slaby");
 MODULE_AUTHOR("Nick Kossifidis");
@@ -2686,6 +2691,7 @@ ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan,
        struct ath5k_hw *ah = sc->ah;
        struct ath_common *common = ath5k_hw_common(ah);
        int ret, ani_mode;
+       bool fast;
 
        ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "resetting\n");
 
@@ -2705,7 +2711,10 @@ ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan,
        ath5k_drain_tx_buffs(sc);
        if (chan)
                sc->curchan = chan;
-       ret = ath5k_hw_reset(ah, sc->opmode, sc->curchan, chan != NULL,
+
+       fast = ((chan != NULL) && modparam_fastchanswitch) ? 1 : 0;
+
+       ret = ath5k_hw_reset(ah, sc->opmode, sc->curchan, fast,
                                                                skip_pcu);
        if (ret) {
                ATH5K_ERR(sc, "can't reset hardware (%d)\n", ret);
index 3510de2cf6224c6ec11b091cfb3f50dd1fccf6b9..126a4eab35f39d7a10995f0f20ff814a87def88c 100644 (file)
@@ -1124,8 +1124,11 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
                        /* Non fatal, can happen eg.
                         * on mode change */
                        ret = 0;
-               } else
+               } else {
+                       ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_RESET,
+                               "fast chan change successful\n");
                        return 0;
+               }
        }
 
        /*
index 077e8a6983fab5637fb8bdc9a949f38a018d7d09..45b262fe2c259c1f3d7556a4dec12022925b0d36 100644 (file)
@@ -28,11 +28,6 @@ static void ar9002_hw_set_desc_link(void *ds, u32 ds_link)
        ((struct ath_desc*) ds)->ds_link = ds_link;
 }
 
-static void ar9002_hw_get_desc_link(void *ds, u32 **ds_link)
-{
-       *ds_link = &((struct ath_desc *)ds)->ds_link;
-}
-
 static bool ar9002_hw_get_isr(struct ath_hw *ah, enum ath9k_int *masked)
 {
        u32 isr = 0;
@@ -437,7 +432,6 @@ void ar9002_hw_attach_mac_ops(struct ath_hw *ah)
 
        ops->rx_enable = ar9002_hw_rx_enable;
        ops->set_desc_link = ar9002_hw_set_desc_link;
-       ops->get_desc_link = ar9002_hw_get_desc_link;
        ops->get_isr = ar9002_hw_get_isr;
        ops->fill_txdesc = ar9002_hw_fill_txdesc;
        ops->proc_txdesc = ar9002_hw_proc_txdesc;
index 10d71f7d3fc22b7ed71bb8f5ad7f9097d910e82e..04e6be04acf9a9cfff70957f678efb4771c7b4f8 100644 (file)
@@ -43,13 +43,6 @@ static void ar9003_hw_set_desc_link(void *ds, u32 ds_link)
        ads->ctl10 |= ar9003_calc_ptr_chksum(ads);
 }
 
-static void ar9003_hw_get_desc_link(void *ds, u32 **ds_link)
-{
-       struct ar9003_txc *ads = ds;
-
-       *ds_link = &ads->link;
-}
-
 static bool ar9003_hw_get_isr(struct ath_hw *ah, enum ath9k_int *masked)
 {
        u32 isr = 0;
@@ -498,7 +491,6 @@ void ar9003_hw_attach_mac_ops(struct ath_hw *hw)
 
        ops->rx_enable = ar9003_hw_rx_enable;
        ops->set_desc_link = ar9003_hw_set_desc_link;
-       ops->get_desc_link = ar9003_hw_get_desc_link;
        ops->get_isr = ar9003_hw_get_isr;
        ops->fill_txdesc = ar9003_hw_fill_txdesc;
        ops->proc_txdesc = ar9003_hw_proc_txdesc;
index e4d6a87ec53830bf70126f29090a2349dea5cfef..2e7f0f2567eb8bf6db71b850c6dace62db8f8dd6 100644 (file)
@@ -46,11 +46,10 @@ EXPORT_SYMBOL(ar9003_paprd_enable);
 
 static int ar9003_get_training_power_2g(struct ath_hw *ah)
 {
-       struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
-       struct ar9300_modal_eep_header *hdr = &eep->modalHeader2G;
+       struct ath9k_channel *chan = ah->curchan;
        unsigned int power, scale, delta;
 
-       scale = MS(le32_to_cpu(hdr->papdRateMaskHt20), AR9300_PAPRD_SCALE_1);
+       scale = ar9003_get_paprd_scale_factor(ah, chan);
        power = REG_READ_FIELD(ah, AR_PHY_POWERTX_RATE5,
                               AR_PHY_POWERTX_RATE5_POWERTXHT20_0);
 
@@ -67,20 +66,10 @@ static int ar9003_get_training_power_2g(struct ath_hw *ah)
 static int ar9003_get_training_power_5g(struct ath_hw *ah)
 {
        struct ath_common *common = ath9k_hw_common(ah);
-       struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
-       struct ar9300_modal_eep_header *hdr = &eep->modalHeader5G;
        struct ath9k_channel *chan = ah->curchan;
        unsigned int power, scale, delta;
 
-       if (chan->channel >= 5700)
-               scale = MS(le32_to_cpu(hdr->papdRateMaskHt20),
-                          AR9300_PAPRD_SCALE_1);
-       else if (chan->channel >= 5400)
-               scale = MS(le32_to_cpu(hdr->papdRateMaskHt40),
-                          AR9300_PAPRD_SCALE_2);
-       else
-               scale = MS(le32_to_cpu(hdr->papdRateMaskHt40),
-                          AR9300_PAPRD_SCALE_1);
+       scale = ar9003_get_paprd_scale_factor(ah, chan);
 
        if (IS_CHAN_HT40(chan))
                power = REG_READ_FIELD(ah, AR_PHY_POWERTX_RATE8,
@@ -119,15 +108,16 @@ static int ar9003_paprd_setup_single_table(struct ath_hw *ah)
        else
                training_power = ar9003_get_training_power_5g(ah);
 
+       ath_dbg(common, ATH_DBG_CALIBRATE,
+               "Training power: %d, Target power: %d\n",
+               training_power, ah->paprd_target_power);
+
        if (training_power < 0) {
                ath_dbg(common, ATH_DBG_CALIBRATE,
                        "PAPRD target power delta out of range");
                return -ERANGE;
        }
        ah->paprd_training_power = training_power;
-       ath_dbg(common, ATH_DBG_CALIBRATE,
-               "Training power: %d, Target power: %d\n",
-               ah->paprd_training_power, ah->paprd_target_power);
 
        REG_RMW_FIELD(ah, AR_PHY_PAPRD_AM2AM, AR_PHY_PAPRD_AM2AM_MASK,
                      ah->paprd_ratemask);
index e99dfe6065bf826c3e476679185f1cf85d4792b9..57933db57633fdfc1122be14f63cd084d6723e9c 100644 (file)
@@ -180,7 +180,7 @@ enum ATH_AGGR_STATUS {
 struct ath_txq {
        int mac80211_qnum; /* mac80211 queue number, -1 means not mac80211 Q */
        u32 axq_qnum; /* ath9k hardware queue number */
-       u32 *axq_link;
+       void *axq_link;
        struct list_head axq_q;
        spinlock_t axq_lock;
        u32 axq_depth;
@@ -189,7 +189,6 @@ struct ath_txq {
        bool axq_tx_inprogress;
        struct list_head axq_acq;
        struct list_head txq_fifo[ATH_TXFIFO_DEPTH];
-       struct list_head txq_fifo_pending;
        u8 txq_headidx;
        u8 txq_tailidx;
        int pending_frames;
@@ -429,6 +428,7 @@ void ath_hw_check(struct work_struct *work);
 void ath_hw_pll_work(struct work_struct *work);
 void ath_paprd_calibrate(struct work_struct *work);
 void ath_ani_calibrate(unsigned long data);
+void ath_start_ani(struct ath_common *common);
 
 /**********/
 /* BTCOEX */
@@ -670,12 +670,8 @@ int ath9k_init_device(u16 devid, struct ath_softc *sc, u16 subsysid,
                    const struct ath_bus_ops *bus_ops);
 void ath9k_deinit_device(struct ath_softc *sc);
 void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw);
-int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw,
-                   struct ath9k_channel *hchan);
 
-void ath_radio_enable(struct ath_softc *sc, struct ieee80211_hw *hw);
 void ath_radio_disable(struct ath_softc *sc, struct ieee80211_hw *hw);
-bool ath9k_setpower(struct ath_softc *sc, enum ath9k_power_mode mode);
 bool ath9k_uses_beacons(int type);
 
 #ifdef CONFIG_ATH9K_PCI
index d4d8ceced89b754c1babef1ba41d11cfe456efcc..0174cdb65a838e9334848f999b721539a2d352f0 100644 (file)
@@ -496,7 +496,7 @@ static void ath_beacon_config_ap(struct ath_softc *sc,
        u32 nexttbtt, intval;
 
        /* NB: the beacon interval is kept internally in TU's */
-       intval = TU_TO_USEC(conf->beacon_interval & ATH9K_BEACON_PERIOD);
+       intval = TU_TO_USEC(conf->beacon_interval);
        intval /= ATH_BCBUF;    /* for staggered beacons */
        nexttbtt = intval;
 
@@ -543,7 +543,7 @@ static void ath_beacon_config_sta(struct ath_softc *sc,
        }
 
        memset(&bs, 0, sizeof(bs));
-       intval = conf->beacon_interval & ATH9K_BEACON_PERIOD;
+       intval = conf->beacon_interval;
 
        /*
         * Setup dtim and cfp parameters according to
@@ -652,22 +652,13 @@ static void ath_beacon_config_adhoc(struct ath_softc *sc,
 {
        struct ath_hw *ah = sc->sc_ah;
        struct ath_common *common = ath9k_hw_common(ah);
-       u32 tsf, delta, intval, nexttbtt;
+       u32 tsf, intval, nexttbtt;
 
        ath9k_reset_beacon_status(sc);
 
-       tsf = ath9k_hw_gettsf32(ah) + TU_TO_USEC(FUDGE);
-       intval = TU_TO_USEC(conf->beacon_interval & ATH9K_BEACON_PERIOD);
-
-       if (!sc->beacon.bc_tstamp)
-               nexttbtt = tsf + intval;
-       else {
-               if (tsf > sc->beacon.bc_tstamp)
-                       delta = (tsf - sc->beacon.bc_tstamp);
-               else
-                       delta = (tsf + 1 + (~0U - sc->beacon.bc_tstamp));
-               nexttbtt = tsf + intval - (delta % intval);
-       }
+       intval = TU_TO_USEC(conf->beacon_interval);
+       tsf = roundup(ath9k_hw_gettsf32(ah) + TU_TO_USEC(FUDGE), intval);
+       nexttbtt = tsf + intval;
 
        ath_dbg(common, ATH_DBG_BEACON,
                "IBSS nexttbtt %u intval %u (%u)\n",
index d55ffd7d4bd28565df7d93b5e1ed65c010b99ba5..22d3a26e684d518a77f4af691943a0b035ce55c7 100644 (file)
@@ -176,6 +176,56 @@ static const struct file_operations fops_rx_chainmask = {
        .llseek = default_llseek,
 };
 
+static ssize_t read_file_disable_ani(struct file *file, char __user *user_buf,
+                            size_t count, loff_t *ppos)
+{
+       struct ath_softc *sc = file->private_data;
+       struct ath_common *common = ath9k_hw_common(sc->sc_ah);
+       char buf[32];
+       unsigned int len;
+
+       len = sprintf(buf, "%d\n", common->disable_ani);
+       return simple_read_from_buffer(user_buf, count, ppos, buf, len);
+}
+
+static ssize_t write_file_disable_ani(struct file *file,
+                                     const char __user *user_buf,
+                                     size_t count, loff_t *ppos)
+{
+       struct ath_softc *sc = file->private_data;
+       struct ath_common *common = ath9k_hw_common(sc->sc_ah);
+       unsigned long disable_ani;
+       char buf[32];
+       ssize_t len;
+
+       len = min(count, sizeof(buf) - 1);
+       if (copy_from_user(buf, user_buf, len))
+               return -EFAULT;
+
+       buf[len] = '\0';
+       if (strict_strtoul(buf, 0, &disable_ani))
+               return -EINVAL;
+
+       common->disable_ani = !!disable_ani;
+
+       if (disable_ani) {
+               sc->sc_flags &= ~SC_OP_ANI_RUN;
+               del_timer_sync(&common->ani.timer);
+       } else {
+               sc->sc_flags |= SC_OP_ANI_RUN;
+               ath_start_ani(common);
+       }
+
+       return count;
+}
+
+static const struct file_operations fops_disable_ani = {
+       .read = read_file_disable_ani,
+       .write = write_file_disable_ani,
+       .open = ath9k_debugfs_open,
+       .owner = THIS_MODULE,
+       .llseek = default_llseek,
+};
 
 static ssize_t read_file_dma(struct file *file, char __user *user_buf,
                             size_t count, loff_t *ppos)
@@ -550,6 +600,7 @@ static ssize_t read_file_xmit(struct file *file, char __user *user_buf,
 
        PR("MPDUs Queued:    ", queued);
        PR("MPDUs Completed: ", completed);
+       PR("MPDUs XRetried:  ", xretries);
        PR("Aggregates:      ", a_aggr);
        PR("AMPDUs Queued HW:", a_queued_hw);
        PR("AMPDUs Queued SW:", a_queued_sw);
@@ -587,7 +638,6 @@ static ssize_t read_file_xmit(struct file *file, char __user *user_buf,
 
        PRQLE("axq_q empty:       ", axq_q);
        PRQLE("axq_acq empty:     ", axq_acq);
-       PRQLE("txq_fifo_pending:  ", txq_fifo_pending);
        for (i = 0; i < ATH_TXFIFO_DEPTH; i++) {
                snprintf(tmp, sizeof(tmp) - 1, "txq_fifo[%i] empty: ", i);
                PRQLE(tmp, txq_fifo[i]);
@@ -807,7 +857,10 @@ void ath_debug_stat_tx(struct ath_softc *sc, struct ath_buf *bf,
                else
                        TX_STAT_INC(qnum, a_completed);
        } else {
-               TX_STAT_INC(qnum, completed);
+               if (bf_isxretried(bf))
+                       TX_STAT_INC(qnum, xretries);
+               else
+                       TX_STAT_INC(qnum, completed);
        }
 
        if (ts->ts_status & ATH9K_TXERR_FIFO)
@@ -1160,6 +1213,8 @@ int ath9k_init_debug(struct ath_hw *ah)
                            sc->debug.debugfs_phy, sc, &fops_rx_chainmask);
        debugfs_create_file("tx_chainmask", S_IRUSR | S_IWUSR,
                            sc->debug.debugfs_phy, sc, &fops_tx_chainmask);
+       debugfs_create_file("disable_ani", S_IRUSR | S_IWUSR,
+                           sc->debug.debugfs_phy, sc, &fops_disable_ani);
        debugfs_create_file("regidx", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy,
                            sc, &fops_regidx);
        debugfs_create_file("regval", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy,
index 8ce6ad80f4e208461469ecbb7b90172ae460a044..4a04510e1111c49845ceadb90f35deef2a670af7 100644 (file)
@@ -116,6 +116,7 @@ struct ath_tx_stats {
        u32 tx_bytes_all;
        u32 queued;
        u32 completed;
+       u32 xretries;
        u32 a_aggr;
        u32 a_queued_hw;
        u32 a_queued_sw;
index aa6a73118706753d6d70ac608f8473f7c218c780..57fe22b242477c03c18a6e0372d8a8fd80d12379 100644 (file)
@@ -79,7 +79,7 @@ static void ath9k_htc_beacon_config_sta(struct ath9k_htc_priv *priv,
 
        memset(&bs, 0, sizeof(bs));
 
-       intval = bss_conf->beacon_interval & ATH9K_BEACON_PERIOD;
+       intval = bss_conf->beacon_interval;
        bmiss_timeout = (ATH_DEFAULT_BMISS_LIMIT * bss_conf->beacon_interval);
 
        /*
@@ -194,7 +194,7 @@ static void ath9k_htc_beacon_config_ap(struct ath9k_htc_priv *priv,
        u8 cmd_rsp;
        u64 tsf;
 
-       intval = bss_conf->beacon_interval & ATH9K_BEACON_PERIOD;
+       intval = bss_conf->beacon_interval;
        intval /= ATH9K_HTC_MAX_BCN_VIF;
        nexttbtt = intval;
 
@@ -250,7 +250,7 @@ static void ath9k_htc_beacon_config_adhoc(struct ath9k_htc_priv *priv,
        u8 cmd_rsp;
        u64 tsf;
 
-       intval = bss_conf->beacon_interval & ATH9K_BEACON_PERIOD;
+       intval = bss_conf->beacon_interval;
        nexttbtt = intval;
 
        /*
@@ -427,7 +427,7 @@ static int ath9k_htc_choose_bslot(struct ath9k_htc_priv *priv,
        u16 intval;
        int slot;
 
-       intval = priv->cur_beacon_conf.beacon_interval & ATH9K_BEACON_PERIOD;
+       intval = priv->cur_beacon_conf.beacon_interval;
 
        tsf = be64_to_cpu(swba->tsf);
        tsftu = TSF_TO_TU(tsf >> 32, tsf);
index 2f3e07263fcbaae598b5be8b6c77760e3c566358..cb29e8875386d7966334273748f2e7c97abab69d 100644 (file)
@@ -39,11 +39,6 @@ static inline void ath9k_hw_set_desc_link(struct ath_hw *ah, void *ds,
        ath9k_hw_ops(ah)->set_desc_link(ds, link);
 }
 
-static inline void ath9k_hw_get_desc_link(struct ath_hw *ah, void *ds,
-                                         u32 **link)
-{
-       ath9k_hw_ops(ah)->get_desc_link(ds, link);
-}
 static inline bool ath9k_hw_calibrate(struct ath_hw *ah,
                                      struct ath9k_channel *chan,
                                      u8 rxchainmask,
index 1be7c8bbef842f5cef15e10f60e47eb46d7d9aa7..6de2655e07dd314c08903071866d6fe67c401125 100644 (file)
@@ -1785,16 +1785,16 @@ void ath9k_hw_set_sta_beacon_timers(struct ath_hw *ah,
        REG_WRITE(ah, AR_NEXT_TBTT_TIMER, TU_TO_USEC(bs->bs_nexttbtt));
 
        REG_WRITE(ah, AR_BEACON_PERIOD,
-                 TU_TO_USEC(bs->bs_intval & ATH9K_BEACON_PERIOD));
+                 TU_TO_USEC(bs->bs_intval));
        REG_WRITE(ah, AR_DMA_BEACON_PERIOD,
-                 TU_TO_USEC(bs->bs_intval & ATH9K_BEACON_PERIOD));
+                 TU_TO_USEC(bs->bs_intval));
 
        REGWRITE_BUFFER_FLUSH(ah);
 
        REG_RMW_FIELD(ah, AR_RSSI_THR,
                      AR_RSSI_THR_BM_THR, bs->bs_bmissthreshold);
 
-       beaconintval = bs->bs_intval & ATH9K_BEACON_PERIOD;
+       beaconintval = bs->bs_intval;
 
        if (bs->bs_sleepduration > beaconintval)
                beaconintval = bs->bs_sleepduration;
index 4b157c53d1a8da11ec217a498c5bdf94b12d3e93..6a6fb5439831aad159cdace6d6648eeb6c818df1 100644 (file)
@@ -403,7 +403,6 @@ struct ath9k_beacon_state {
        u32 bs_nexttbtt;
        u32 bs_nextdtim;
        u32 bs_intval;
-#define ATH9K_BEACON_PERIOD       0x0000ffff
 #define ATH9K_TSFOOR_THRESHOLD    0x00004240 /* 16k us */
        u32 bs_dtimperiod;
        u16 bs_cfpperiod;
@@ -603,7 +602,6 @@ struct ath_hw_ops {
                                     int power_off);
        void (*rx_enable)(struct ath_hw *ah);
        void (*set_desc_link)(void *ds, u32 link);
-       void (*get_desc_link)(void *ds, u32 **link);
        bool (*calibrate)(struct ath_hw *ah,
                          struct ath9k_channel *chan,
                          u8 rxchainmask,
index 45c585a337e9885b336f1ae50731170f6f63344c..d4b166cfdf6047935b6faad502ef59fae2f1d64a 100644 (file)
@@ -519,7 +519,6 @@ static void ath9k_init_misc(struct ath_softc *sc)
 {
        struct ath_common *common = ath9k_hw_common(sc->sc_ah);
        int i = 0;
-
        setup_timer(&common->ani.timer, ath_ani_calibrate, (unsigned long)sc);
 
        sc->config.txpowlimit = ATH_TXPOWER_MAX;
@@ -585,6 +584,7 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid,
        common->priv = sc;
        common->debug_mask = ath9k_debug;
        common->btcoex_enabled = ath9k_btcoex_enable == 1;
+       common->disable_ani = false;
        spin_lock_init(&common->cc_lock);
 
        spin_lock_init(&sc->sc_serial_rw);
index 2ca351fe6d3c0b056d4ecb8be14388aac195e85b..7f945333e2d80bae3438c350a4ed9e1a6c3d5ef3 100644 (file)
@@ -62,14 +62,12 @@ static bool ath9k_has_pending_frames(struct ath_softc *sc, struct ath_txq *txq)
 
        if (txq->axq_depth || !list_empty(&txq->axq_acq))
                pending = true;
-       else if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)
-               pending = !list_empty(&txq->txq_fifo_pending);
 
        spin_unlock_bh(&txq->axq_lock);
        return pending;
 }
 
-bool ath9k_setpower(struct ath_softc *sc, enum ath9k_power_mode mode)
+static bool ath9k_setpower(struct ath_softc *sc, enum ath9k_power_mode mode)
 {
        unsigned long flags;
        bool ret;
@@ -136,7 +134,7 @@ void ath9k_ps_restore(struct ath_softc *sc)
        spin_unlock_irqrestore(&sc->sc_pm_lock, flags);
 }
 
-static void ath_start_ani(struct ath_common *common)
+void ath_start_ani(struct ath_common *common)
 {
        struct ath_hw *ah = common->ah;
        unsigned long timestamp = jiffies_to_msecs(jiffies);
@@ -219,7 +217,7 @@ static int ath_update_survey_stats(struct ath_softc *sc)
  * by reseting the chip.  To accomplish this we must first cleanup any pending
  * DMA, then restart stuff.
 */
-int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw,
+static int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw,
                    struct ath9k_channel *hchan)
 {
        struct ath_hw *ah = sc->sc_ah;
@@ -302,7 +300,8 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw,
                        ath_set_beacon(sc);
                ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, 0);
                ieee80211_queue_delayed_work(sc->hw, &sc->hw_pll_work, HZ/2);
-               ath_start_ani(common);
+               if (!common->disable_ani)
+                       ath_start_ani(common);
        }
 
  ps_restore:
@@ -394,12 +393,14 @@ void ath_paprd_calibrate(struct work_struct *work)
        if (!caldata)
                return;
 
+       ath9k_ps_wakeup(sc);
+
        if (ar9003_paprd_init_table(ah) < 0)
-               return;
+               goto fail_paprd;
 
        skb = alloc_skb(len, GFP_KERNEL);
        if (!skb)
-               return;
+               goto fail_paprd;
 
        skb_put(skb, len);
        memset(skb->data, 0, len);
@@ -411,7 +412,6 @@ void ath_paprd_calibrate(struct work_struct *work)
        memcpy(hdr->addr2, hw->wiphy->perm_addr, ETH_ALEN);
        memcpy(hdr->addr3, hw->wiphy->perm_addr, ETH_ALEN);
 
-       ath9k_ps_wakeup(sc);
        for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) {
                if (!(common->tx_chainmask & BIT(chain)))
                        continue;
@@ -515,24 +515,19 @@ void ath_ani_calibrate(unsigned long data)
                common->ani.checkani_timer = timestamp;
        }
 
-       /* Skip all processing if there's nothing to do. */
-       if (longcal || shortcal || aniflag) {
-               /* Call ANI routine if necessary */
-               if (aniflag) {
-                       spin_lock_irqsave(&common->cc_lock, flags);
-                       ath9k_hw_ani_monitor(ah, ah->curchan);
-                       ath_update_survey_stats(sc);
-                       spin_unlock_irqrestore(&common->cc_lock, flags);
-               }
+       /* Call ANI routine if necessary */
+       if (aniflag) {
+               spin_lock_irqsave(&common->cc_lock, flags);
+               ath9k_hw_ani_monitor(ah, ah->curchan);
+               ath_update_survey_stats(sc);
+               spin_unlock_irqrestore(&common->cc_lock, flags);
+       }
 
-               /* Perform calibration if necessary */
-               if (longcal || shortcal) {
-                       common->ani.caldone =
-                               ath9k_hw_calibrate(ah,
-                                                  ah->curchan,
-                                                  common->rx_chainmask,
-                                                  longcal);
-               }
+       /* Perform calibration if necessary */
+       if (longcal || shortcal) {
+               common->ani.caldone =
+                       ath9k_hw_calibrate(ah, ah->curchan,
+                                               common->rx_chainmask, longcal);
        }
 
        ath9k_ps_restore(sc);
@@ -868,7 +863,7 @@ chip_reset:
 #undef SCHED_INTR
 }
 
-void ath_radio_enable(struct ath_softc *sc, struct ieee80211_hw *hw)
+static void ath_radio_enable(struct ath_softc *sc, struct ieee80211_hw *hw)
 {
        struct ath_hw *ah = sc->sc_ah;
        struct ath_common *common = ath9k_hw_common(ah);
@@ -974,6 +969,7 @@ int ath_reset(struct ath_softc *sc, bool retry_tx)
        sc->hw_busy_count = 0;
 
        /* Stop ANI */
+
        del_timer_sync(&common->ani.timer);
 
        ath9k_ps_wakeup(sc);
@@ -1023,7 +1019,9 @@ int ath_reset(struct ath_softc *sc, bool retry_tx)
        spin_unlock_bh(&sc->sc_pcu_lock);
 
        /* Start ANI */
-       ath_start_ani(common);
+       if (!common->disable_ani)
+               ath_start_ani(common);
+
        ath9k_ps_restore(sc);
 
        return r;
@@ -1412,10 +1410,14 @@ static void ath9k_calculate_summary_state(struct ieee80211_hw *hw,
        ath9k_hw_set_interrupts(ah, ah->imask);
 
        /* Set up ANI */
-       if ((iter_data.naps + iter_data.nadhocs) > 0) {
+       if (iter_data.naps > 0) {
                sc->sc_ah->stats.avgbrssi = ATH_RSSI_DUMMY_MARKER;
-               sc->sc_flags |= SC_OP_ANI_RUN;
-               ath_start_ani(common);
+
+               if (!common->disable_ani) {
+                       sc->sc_flags |= SC_OP_ANI_RUN;
+                       ath_start_ani(common);
+               }
+
        } else {
                sc->sc_flags &= ~SC_OP_ANI_RUN;
                del_timer_sync(&common->ani.timer);
@@ -1952,50 +1954,38 @@ static void ath9k_bss_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
        struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
        struct ath_vif *avp = (void *)vif->drv_priv;
 
-       switch (sc->sc_ah->opmode) {
-       case NL80211_IFTYPE_ADHOC:
-               /* There can be only one vif available */
+       /*
+        * Skip iteration if primary station vif's bss info
+        * was not changed
+        */
+       if (sc->sc_flags & SC_OP_PRIM_STA_VIF)
+               return;
+
+       if (bss_conf->assoc) {
+               sc->sc_flags |= SC_OP_PRIM_STA_VIF;
+               avp->primary_sta_vif = true;
                memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN);
                common->curaid = bss_conf->aid;
                ath9k_hw_write_associd(sc->sc_ah);
-               /* configure beacon */
-               if (bss_conf->enable_beacon)
-                       ath_beacon_config(sc, vif);
-               break;
-       case NL80211_IFTYPE_STATION:
-               /*
-                * Skip iteration if primary station vif's bss info
-                * was not changed
-                */
-               if (sc->sc_flags & SC_OP_PRIM_STA_VIF)
-                       break;
-
-               if (bss_conf->assoc) {
-                       sc->sc_flags |= SC_OP_PRIM_STA_VIF;
-                       avp->primary_sta_vif = true;
-                       memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN);
-                       common->curaid = bss_conf->aid;
-                       ath9k_hw_write_associd(sc->sc_ah);
-                       ath_dbg(common, ATH_DBG_CONFIG,
+               ath_dbg(common, ATH_DBG_CONFIG,
                                "Bss Info ASSOC %d, bssid: %pM\n",
                                bss_conf->aid, common->curbssid);
-                       ath_beacon_config(sc, vif);
-                       /*
-                        * Request a re-configuration of Beacon related timers
-                        * on the receipt of the first Beacon frame (i.e.,
-                        * after time sync with the AP).
-                        */
-                       sc->ps_flags |= PS_BEACON_SYNC | PS_WAIT_FOR_BEACON;
-                       /* Reset rssi stats */
-                       sc->last_rssi = ATH_RSSI_DUMMY_MARKER;
-                       sc->sc_ah->stats.avgbrssi = ATH_RSSI_DUMMY_MARKER;
+               ath_beacon_config(sc, vif);
+               /*
+                * Request a re-configuration of Beacon related timers
+                * on the receipt of the first Beacon frame (i.e.,
+                * after time sync with the AP).
+                */
+               sc->ps_flags |= PS_BEACON_SYNC | PS_WAIT_FOR_BEACON;
+               /* Reset rssi stats */
+               sc->last_rssi = ATH_RSSI_DUMMY_MARKER;
+               sc->sc_ah->stats.avgbrssi = ATH_RSSI_DUMMY_MARKER;
 
+               if (!common->disable_ani) {
                        sc->sc_flags |= SC_OP_ANI_RUN;
                        ath_start_ani(common);
                }
-               break;
-       default:
-               break;
+
        }
 }
 
@@ -2005,6 +1995,9 @@ static void ath9k_config_bss(struct ath_softc *sc, struct ieee80211_vif *vif)
        struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
        struct ath_vif *avp = (void *)vif->drv_priv;
 
+       if (sc->sc_ah->opmode != NL80211_IFTYPE_STATION)
+               return;
+
        /* Reconfigure bss info */
        if (avp->primary_sta_vif && !bss_conf->assoc) {
                ath_dbg(common, ATH_DBG_CONFIG,
@@ -2023,8 +2016,7 @@ static void ath9k_config_bss(struct ath_softc *sc, struct ieee80211_vif *vif)
         * None of station vifs are associated.
         * Clear bssid & aid
         */
-       if ((sc->sc_ah->opmode == NL80211_IFTYPE_STATION) &&
-           !(sc->sc_flags & SC_OP_PRIM_STA_VIF)) {
+       if (!(sc->sc_flags & SC_OP_PRIM_STA_VIF)) {
                ath9k_hw_write_associd(sc->sc_ah);
                /* Stop ANI */
                sc->sc_flags &= ~SC_OP_ANI_RUN;
@@ -2054,6 +2046,26 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw,
                        common->curbssid, common->curaid);
        }
 
+       if (changed & BSS_CHANGED_IBSS) {
+               /* There can be only one vif available */
+               memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN);
+               common->curaid = bss_conf->aid;
+               ath9k_hw_write_associd(sc->sc_ah);
+
+               if (bss_conf->ibss_joined) {
+                       sc->sc_ah->stats.avgbrssi = ATH_RSSI_DUMMY_MARKER;
+
+                       if (!common->disable_ani) {
+                               sc->sc_flags |= SC_OP_ANI_RUN;
+                               ath_start_ani(common);
+                       }
+
+               } else {
+                       sc->sc_flags &= ~SC_OP_ANI_RUN;
+                       del_timer_sync(&common->ani.timer);
+               }
+       }
+
        /* Enable transmission of beacons (AP, IBSS, MESH) */
        if ((changed & BSS_CHANGED_BEACON) ||
            ((changed & BSS_CHANGED_BEACON_ENABLED) && bss_conf->enable_beacon)) {
@@ -2334,7 +2346,7 @@ static bool ath9k_tx_frames_pending(struct ieee80211_hw *hw)
        return false;
 }
 
-int ath9k_tx_last_beacon(struct ieee80211_hw *hw)
+static int ath9k_tx_last_beacon(struct ieee80211_hw *hw)
 {
        struct ath_softc *sc = hw->priv;
        struct ath_hw *ah = sc->sc_ah;
index 3779b8977d4709a9ce68d85a8b2458d472deaea4..ec012b4317afb1ccdf5ea4b7014ac7448094f38d 100644 (file)
@@ -53,7 +53,7 @@ static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf,
                                struct ath_txq *txq, struct list_head *bf_q,
                                struct ath_tx_status *ts, int txok, int sendbar);
 static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq,
-                            struct list_head *head);
+                            struct list_head *head, bool internal);
 static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf, int len);
 static void ath_tx_rc_status(struct ath_softc *sc, struct ath_buf *bf,
                             struct ath_tx_status *ts, int nframes, int nbad,
@@ -377,8 +377,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
                        bf_next = bf->bf_next;
 
                        bf->bf_state.bf_type |= BUF_XRETRY;
-                       if ((sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) ||
-                           !bf->bf_stale || bf_next != NULL)
+                       if (!bf->bf_stale || bf_next != NULL)
                                list_move_tail(&bf->list, &bf_head);
 
                        ath_tx_rc_status(sc, bf, ts, 1, 1, 0, false);
@@ -463,20 +462,14 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
                        }
                }
 
-               if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) &&
-                   bf_next == NULL) {
-                       /*
-                        * Make sure the last desc is reclaimed if it
-                        * not a holding desc.
-                        */
-                       if (!bf_last->bf_stale)
-                               list_move_tail(&bf->list, &bf_head);
-                       else
-                               INIT_LIST_HEAD(&bf_head);
-               } else {
-                       BUG_ON(list_empty(bf_q));
+               /*
+                * Make sure the last desc is reclaimed if it
+                * not a holding desc.
+                */
+               if (!bf_last->bf_stale || bf_next != NULL)
                        list_move_tail(&bf->list, &bf_head);
-               }
+               else
+                       INIT_LIST_HEAD(&bf_head);
 
                if (!txpending || (tid->state & AGGR_CLEANUP)) {
                        /*
@@ -837,7 +830,7 @@ static void ath_tx_sched_aggr(struct ath_softc *sc, struct ath_txq *txq,
                        bf->bf_state.bf_type &= ~BUF_AGGR;
                        ath9k_hw_clr11n_aggr(sc->sc_ah, bf->bf_desc);
                        ath_buf_set_rate(sc, bf, fi->framelen);
-                       ath_tx_txqaddbuf(sc, txq, &bf_q);
+                       ath_tx_txqaddbuf(sc, txq, &bf_q, false);
                        continue;
                }
 
@@ -849,7 +842,7 @@ static void ath_tx_sched_aggr(struct ath_softc *sc, struct ath_txq *txq,
                /* anchor last desc of aggregate */
                ath9k_hw_set11n_aggr_last(sc->sc_ah, bf->bf_lastbf->bf_desc);
 
-               ath_tx_txqaddbuf(sc, txq, &bf_q);
+               ath_tx_txqaddbuf(sc, txq, &bf_q, false);
                TX_STAT_INC(txq->axq_qnum, a_aggr);
 
        } while (txq->axq_ampdu_depth < ATH_AGGR_MIN_QDEPTH &&
@@ -1085,7 +1078,6 @@ struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype)
                txq->txq_headidx = txq->txq_tailidx = 0;
                for (i = 0; i < ATH_TXFIFO_DEPTH; i++)
                        INIT_LIST_HEAD(&txq->txq_fifo[i]);
-               INIT_LIST_HEAD(&txq->txq_fifo_pending);
        }
        return &sc->tx.txq[axq_qnum];
 }
@@ -1155,13 +1147,8 @@ static bool bf_is_ampdu_not_probing(struct ath_buf *bf)
     return bf_isampdu(bf) && !(info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE);
 }
 
-/*
- * Drain a given TX queue (could be Beacon or Data)
- *
- * This assumes output has been stopped and
- * we do not need to block ath_tx_tasklet.
- */
-void ath_draintxq(struct ath_softc *sc, struct ath_txq *txq, bool retry_tx)
+static void ath_drain_txq_list(struct ath_softc *sc, struct ath_txq *txq,
+                              struct list_head *list, bool retry_tx)
 {
        struct ath_buf *bf, *lastbf;
        struct list_head bf_head;
@@ -1170,93 +1157,63 @@ void ath_draintxq(struct ath_softc *sc, struct ath_txq *txq, bool retry_tx)
        memset(&ts, 0, sizeof(ts));
        INIT_LIST_HEAD(&bf_head);
 
-       for (;;) {
-               spin_lock_bh(&txq->axq_lock);
+       while (!list_empty(list)) {
+               bf = list_first_entry(list, struct ath_buf, list);
 
-               if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) {
-                       if (list_empty(&txq->txq_fifo[txq->txq_tailidx])) {
-                               txq->txq_headidx = txq->txq_tailidx = 0;
-                               spin_unlock_bh(&txq->axq_lock);
-                               break;
-                       } else {
-                               bf = list_first_entry(&txq->txq_fifo[txq->txq_tailidx],
-                                                     struct ath_buf, list);
-                       }
-               } else {
-                       if (list_empty(&txq->axq_q)) {
-                               txq->axq_link = NULL;
-                               spin_unlock_bh(&txq->axq_lock);
-                               break;
-                       }
-                       bf = list_first_entry(&txq->axq_q, struct ath_buf,
-                                             list);
-
-                       if (bf->bf_stale) {
-                               list_del(&bf->list);
-                               spin_unlock_bh(&txq->axq_lock);
+               if (bf->bf_stale) {
+                       list_del(&bf->list);
 
-                               ath_tx_return_buffer(sc, bf);
-                               continue;
-                       }
+                       ath_tx_return_buffer(sc, bf);
+                       continue;
                }
 
                lastbf = bf->bf_lastbf;
-
-               if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) {
-                       list_cut_position(&bf_head,
-                                         &txq->txq_fifo[txq->txq_tailidx],
-                                         &lastbf->list);
-                       INCR(txq->txq_tailidx, ATH_TXFIFO_DEPTH);
-               } else {
-                       /* remove ath_buf's of the same mpdu from txq */
-                       list_cut_position(&bf_head, &txq->axq_q, &lastbf->list);
-               }
+               list_cut_position(&bf_head, list, &lastbf->list);
 
                txq->axq_depth--;
                if (bf_is_ampdu_not_probing(bf))
                        txq->axq_ampdu_depth--;
-               spin_unlock_bh(&txq->axq_lock);
 
+               spin_unlock_bh(&txq->axq_lock);
                if (bf_isampdu(bf))
                        ath_tx_complete_aggr(sc, txq, bf, &bf_head, &ts, 0,
                                             retry_tx);
                else
                        ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0, 0);
+               spin_lock_bh(&txq->axq_lock);
        }
+}
 
+/*
+ * Drain a given TX queue (could be Beacon or Data)
+ *
+ * This assumes output has been stopped and
+ * we do not need to block ath_tx_tasklet.
+ */
+void ath_draintxq(struct ath_softc *sc, struct ath_txq *txq, bool retry_tx)
+{
        spin_lock_bh(&txq->axq_lock);
-       txq->axq_tx_inprogress = false;
-       spin_unlock_bh(&txq->axq_lock);
-
        if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) {
-               spin_lock_bh(&txq->axq_lock);
-               while (!list_empty(&txq->txq_fifo_pending)) {
-                       bf = list_first_entry(&txq->txq_fifo_pending,
-                                             struct ath_buf, list);
-                       list_cut_position(&bf_head,
-                                         &txq->txq_fifo_pending,
-                                         &bf->bf_lastbf->list);
-                       spin_unlock_bh(&txq->axq_lock);
+               int idx = txq->txq_tailidx;
 
-                       if (bf_isampdu(bf))
-                               ath_tx_complete_aggr(sc, txq, bf, &bf_head,
-                                                    &ts, 0, retry_tx);
-                       else
-                               ath_tx_complete_buf(sc, bf, txq, &bf_head,
-                                                   &ts, 0, 0);
-                       spin_lock_bh(&txq->axq_lock);
+               while (!list_empty(&txq->txq_fifo[idx])) {
+                       ath_drain_txq_list(sc, txq, &txq->txq_fifo[idx],
+                                          retry_tx);
+
+                       INCR(idx, ATH_TXFIFO_DEPTH);
                }
-               spin_unlock_bh(&txq->axq_lock);
+               txq->txq_tailidx = idx;
        }
 
+       txq->axq_link = NULL;
+       txq->axq_tx_inprogress = false;
+       ath_drain_txq_list(sc, txq, &txq->axq_q, retry_tx);
+
        /* flush any pending frames if aggregation is enabled */
-       if (sc->sc_flags & SC_OP_TXAGGR) {
-               if (!retry_tx) {
-                       spin_lock_bh(&txq->axq_lock);
-                       ath_txq_drain_pending_buffers(sc, txq);
-                       spin_unlock_bh(&txq->axq_lock);
-               }
-       }
+       if ((sc->sc_flags & SC_OP_TXAGGR) && !retry_tx)
+               ath_txq_drain_pending_buffers(sc, txq);
+
+       spin_unlock_bh(&txq->axq_lock);
 }
 
 bool ath_drain_all_txq(struct ath_softc *sc, bool retry_tx)
@@ -1370,11 +1327,13 @@ void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq)
  * assume the descriptors are already chained together by caller.
  */
 static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq,
-                            struct list_head *head)
+                            struct list_head *head, bool internal)
 {
        struct ath_hw *ah = sc->sc_ah;
        struct ath_common *common = ath9k_hw_common(ah);
-       struct ath_buf *bf;
+       struct ath_buf *bf, *bf_last;
+       bool puttxbuf = false;
+       bool edma;
 
        /*
         * Insert the frame on the outbound list and
@@ -1384,51 +1343,49 @@ static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq,
        if (list_empty(head))
                return;
 
+       edma = !!(ah->caps.hw_caps & ATH9K_HW_CAP_EDMA);
        bf = list_first_entry(head, struct ath_buf, list);
+       bf_last = list_entry(head->prev, struct ath_buf, list);
 
        ath_dbg(common, ATH_DBG_QUEUE,
                "qnum: %d, txq depth: %d\n", txq->axq_qnum, txq->axq_depth);
 
-       if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) {
-               if (txq->axq_depth >= ATH_TXFIFO_DEPTH) {
-                       list_splice_tail_init(head, &txq->txq_fifo_pending);
-                       return;
-               }
-               if (!list_empty(&txq->txq_fifo[txq->txq_headidx]))
-                       ath_dbg(common, ATH_DBG_XMIT,
-                               "Initializing tx fifo %d which is non-empty\n",
-                               txq->txq_headidx);
-               INIT_LIST_HEAD(&txq->txq_fifo[txq->txq_headidx]);
-               list_splice_init(head, &txq->txq_fifo[txq->txq_headidx]);
+       if (edma && list_empty(&txq->txq_fifo[txq->txq_headidx])) {
+               list_splice_tail_init(head, &txq->txq_fifo[txq->txq_headidx]);
                INCR(txq->txq_headidx, ATH_TXFIFO_DEPTH);
-               TX_STAT_INC(txq->axq_qnum, puttxbuf);
-               ath9k_hw_puttxbuf(ah, txq->axq_qnum, bf->bf_daddr);
-               ath_dbg(common, ATH_DBG_XMIT, "TXDP[%u] = %llx (%p)\n",
-                       txq->axq_qnum, ito64(bf->bf_daddr), bf->bf_desc);
+               puttxbuf = true;
        } else {
                list_splice_tail_init(head, &txq->axq_q);
 
-               if (txq->axq_link == NULL) {
-                       TX_STAT_INC(txq->axq_qnum, puttxbuf);
-                       ath9k_hw_puttxbuf(ah, txq->axq_qnum, bf->bf_daddr);
-                       ath_dbg(common, ATH_DBG_XMIT, "TXDP[%u] = %llx (%p)\n",
-                               txq->axq_qnum, ito64(bf->bf_daddr),
-                               bf->bf_desc);
-               } else {
-                       *txq->axq_link = bf->bf_daddr;
+               if (txq->axq_link) {
+                       ath9k_hw_set_desc_link(ah, txq->axq_link, bf->bf_daddr);
                        ath_dbg(common, ATH_DBG_XMIT,
                                "link[%u] (%p)=%llx (%p)\n",
                                txq->axq_qnum, txq->axq_link,
                                ito64(bf->bf_daddr), bf->bf_desc);
-               }
-               ath9k_hw_get_desc_link(ah, bf->bf_lastbf->bf_desc,
-                                      &txq->axq_link);
+               } else if (!edma)
+                       puttxbuf = true;
+
+               txq->axq_link = bf_last->bf_desc;
+       }
+
+       if (puttxbuf) {
+               TX_STAT_INC(txq->axq_qnum, puttxbuf);
+               ath9k_hw_puttxbuf(ah, txq->axq_qnum, bf->bf_daddr);
+               ath_dbg(common, ATH_DBG_XMIT, "TXDP[%u] = %llx (%p)\n",
+                       txq->axq_qnum, ito64(bf->bf_daddr), bf->bf_desc);
+       }
+
+       if (!edma) {
                TX_STAT_INC(txq->axq_qnum, txstart);
                ath9k_hw_txstart(ah, txq->axq_qnum);
        }
-       txq->axq_depth++;
-       if (bf_is_ampdu_not_probing(bf))
-               txq->axq_ampdu_depth++;
+
+       if (!internal) {
+               txq->axq_depth++;
+               if (bf_is_ampdu_not_probing(bf))
+                       txq->axq_ampdu_depth++;
+       }
 }
 
 static void ath_tx_send_ampdu(struct ath_softc *sc, struct ath_atx_tid *tid,
@@ -1470,7 +1427,7 @@ static void ath_tx_send_ampdu(struct ath_softc *sc, struct ath_atx_tid *tid,
        TX_STAT_INC(txctl->txq->axq_qnum, a_queued_hw);
        bf->bf_lastbf = bf;
        ath_buf_set_rate(sc, bf, fi->framelen);
-       ath_tx_txqaddbuf(sc, txctl->txq, &bf_head);
+       ath_tx_txqaddbuf(sc, txctl->txq, &bf_head, false);
 }
 
 static void ath_tx_send_normal(struct ath_softc *sc, struct ath_txq *txq,
@@ -1490,7 +1447,7 @@ static void ath_tx_send_normal(struct ath_softc *sc, struct ath_txq *txq,
        bf->bf_lastbf = bf;
        fi = get_frame_info(bf->bf_mpdu);
        ath_buf_set_rate(sc, bf, fi->framelen);
-       ath_tx_txqaddbuf(sc, txq, bf_head);
+       ath_tx_txqaddbuf(sc, txq, bf_head, false);
        TX_STAT_INC(txq->axq_qnum, queued);
 }
 
@@ -2077,6 +2034,38 @@ static void ath_tx_rc_status(struct ath_softc *sc, struct ath_buf *bf,
        tx_info->status.rates[tx_rateindex].count = ts->ts_longretry + 1;
 }
 
+static void ath_tx_process_buffer(struct ath_softc *sc, struct ath_txq *txq,
+                                 struct ath_tx_status *ts, struct ath_buf *bf,
+                                 struct list_head *bf_head)
+{
+       int txok;
+
+       txq->axq_depth--;
+       txok = !(ts->ts_status & ATH9K_TXERR_MASK);
+       txq->axq_tx_inprogress = false;
+       if (bf_is_ampdu_not_probing(bf))
+               txq->axq_ampdu_depth--;
+
+       spin_unlock_bh(&txq->axq_lock);
+
+       if (!bf_isampdu(bf)) {
+               /*
+                * This frame is sent out as a single frame.
+                * Use hardware retry status for this frame.
+                */
+               if (ts->ts_status & ATH9K_TXERR_XRETRY)
+                       bf->bf_state.bf_type |= BUF_XRETRY;
+               ath_tx_rc_status(sc, bf, ts, 1, txok ? 0 : 1, txok, true);
+               ath_tx_complete_buf(sc, bf, txq, bf_head, ts, txok, 0);
+       } else
+               ath_tx_complete_aggr(sc, txq, bf, bf_head, ts, txok, true);
+
+       spin_lock_bh(&txq->axq_lock);
+
+       if (sc->sc_flags & SC_OP_TXAGGR)
+               ath_txq_schedule(sc, txq);
+}
+
 static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
 {
        struct ath_hw *ah = sc->sc_ah;
@@ -2085,20 +2074,18 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
        struct list_head bf_head;
        struct ath_desc *ds;
        struct ath_tx_status ts;
-       int txok;
        int status;
 
        ath_dbg(common, ATH_DBG_QUEUE, "tx queue %d (%x), link %p\n",
                txq->axq_qnum, ath9k_hw_gettxbuf(sc->sc_ah, txq->axq_qnum),
                txq->axq_link);
 
+       spin_lock_bh(&txq->axq_lock);
        for (;;) {
-               spin_lock_bh(&txq->axq_lock);
                if (list_empty(&txq->axq_q)) {
                        txq->axq_link = NULL;
                        if (sc->sc_flags & SC_OP_TXAGGR)
                                ath_txq_schedule(sc, txq);
-                       spin_unlock_bh(&txq->axq_lock);
                        break;
                }
                bf = list_first_entry(&txq->axq_q, struct ath_buf, list);
@@ -2114,13 +2101,11 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
                bf_held = NULL;
                if (bf->bf_stale) {
                        bf_held = bf;
-                       if (list_is_last(&bf_held->list, &txq->axq_q)) {
-                               spin_unlock_bh(&txq->axq_lock);
+                       if (list_is_last(&bf_held->list, &txq->axq_q))
                                break;
-                       } else {
-                               bf = list_entry(bf_held->list.next,
-                                               struct ath_buf, list);
-                       }
+
+                       bf = list_entry(bf_held->list.next, struct ath_buf,
+                                       list);
                }
 
                lastbf = bf->bf_lastbf;
@@ -2128,10 +2113,9 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
 
                memset(&ts, 0, sizeof(ts));
                status = ath9k_hw_txprocdesc(ah, ds, &ts);
-               if (status == -EINPROGRESS) {
-                       spin_unlock_bh(&txq->axq_lock);
+               if (status == -EINPROGRESS)
                        break;
-               }
+
                TX_STAT_INC(txq->axq_qnum, txprocdesc);
 
                /*
@@ -2145,42 +2129,14 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
                        list_cut_position(&bf_head,
                                &txq->axq_q, lastbf->list.prev);
 
-               txq->axq_depth--;
-               txok = !(ts.ts_status & ATH9K_TXERR_MASK);
-               txq->axq_tx_inprogress = false;
-               if (bf_held)
+               if (bf_held) {
                        list_del(&bf_held->list);
-
-               if (bf_is_ampdu_not_probing(bf))
-                       txq->axq_ampdu_depth--;
-
-               spin_unlock_bh(&txq->axq_lock);
-
-               if (bf_held)
                        ath_tx_return_buffer(sc, bf_held);
-
-               if (!bf_isampdu(bf)) {
-                       /*
-                        * This frame is sent out as a single frame.
-                        * Use hardware retry status for this frame.
-                        */
-                       if (ts.ts_status & ATH9K_TXERR_XRETRY)
-                               bf->bf_state.bf_type |= BUF_XRETRY;
-                       ath_tx_rc_status(sc, bf, &ts, 1, txok ? 0 : 1, txok, true);
                }
 
-               if (bf_isampdu(bf))
-                       ath_tx_complete_aggr(sc, txq, bf, &bf_head, &ts, txok,
-                                            true);
-               else
-                       ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, txok, 0);
-
-               spin_lock_bh(&txq->axq_lock);
-
-               if (sc->sc_flags & SC_OP_TXAGGR)
-                       ath_txq_schedule(sc, txq);
-               spin_unlock_bh(&txq->axq_lock);
+               ath_tx_process_buffer(sc, txq, &ts, bf, &bf_head);
        }
+       spin_unlock_bh(&txq->axq_lock);
 }
 
 static void ath_tx_complete_poll_work(struct work_struct *work)
@@ -2237,17 +2193,16 @@ void ath_tx_tasklet(struct ath_softc *sc)
 
 void ath_tx_edma_tasklet(struct ath_softc *sc)
 {
-       struct ath_tx_status txs;
+       struct ath_tx_status ts;
        struct ath_common *common = ath9k_hw_common(sc->sc_ah);
        struct ath_hw *ah = sc->sc_ah;
        struct ath_txq *txq;
        struct ath_buf *bf, *lastbf;
        struct list_head bf_head;
        int status;
-       int txok;
 
        for (;;) {
-               status = ath9k_hw_txprocdesc(ah, NULL, (void *)&txs);
+               status = ath9k_hw_txprocdesc(ah, NULL, (void *)&ts);
                if (status == -EINPROGRESS)
                        break;
                if (status == -EIO) {
@@ -2257,12 +2212,13 @@ void ath_tx_edma_tasklet(struct ath_softc *sc)
                }
 
                /* Skip beacon completions */
-               if (txs.qid == sc->beacon.beaconq)
+               if (ts.qid == sc->beacon.beaconq)
                        continue;
 
-               txq = &sc->tx.txq[txs.qid];
+               txq = &sc->tx.txq[ts.qid];
 
                spin_lock_bh(&txq->axq_lock);
+
                if (list_empty(&txq->txq_fifo[txq->txq_tailidx])) {
                        spin_unlock_bh(&txq->axq_lock);
                        return;
@@ -2275,41 +2231,21 @@ void ath_tx_edma_tasklet(struct ath_softc *sc)
                INIT_LIST_HEAD(&bf_head);
                list_cut_position(&bf_head, &txq->txq_fifo[txq->txq_tailidx],
                                  &lastbf->list);
-               INCR(txq->txq_tailidx, ATH_TXFIFO_DEPTH);
-               txq->axq_depth--;
-               txq->axq_tx_inprogress = false;
-               if (bf_is_ampdu_not_probing(bf))
-                       txq->axq_ampdu_depth--;
-               spin_unlock_bh(&txq->axq_lock);
 
-               txok = !(txs.ts_status & ATH9K_TXERR_MASK);
-
-               if (!bf_isampdu(bf)) {
-                       if (txs.ts_status & ATH9K_TXERR_XRETRY)
-                               bf->bf_state.bf_type |= BUF_XRETRY;
-                       ath_tx_rc_status(sc, bf, &txs, 1, txok ? 0 : 1, txok, true);
-               }
-
-               if (bf_isampdu(bf))
-                       ath_tx_complete_aggr(sc, txq, bf, &bf_head, &txs,
-                                            txok, true);
-               else
-                       ath_tx_complete_buf(sc, bf, txq, &bf_head,
-                                           &txs, txok, 0);
+               if (list_empty(&txq->txq_fifo[txq->txq_tailidx])) {
+                       INCR(txq->txq_tailidx, ATH_TXFIFO_DEPTH);
 
-               spin_lock_bh(&txq->axq_lock);
+                       if (!list_empty(&txq->axq_q)) {
+                               struct list_head bf_q;
 
-               if (!list_empty(&txq->txq_fifo_pending)) {
-                       INIT_LIST_HEAD(&bf_head);
-                       bf = list_first_entry(&txq->txq_fifo_pending,
-                                             struct ath_buf, list);
-                       list_cut_position(&bf_head,
-                                         &txq->txq_fifo_pending,
-                                         &bf->bf_lastbf->list);
-                       ath_tx_txqaddbuf(sc, txq, &bf_head);
-               } else if (sc->sc_flags & SC_OP_TXAGGR)
-                       ath_txq_schedule(sc, txq);
+                               INIT_LIST_HEAD(&bf_q);
+                               txq->axq_link = NULL;
+                               list_splice_tail_init(&txq->axq_q, &bf_q);
+                               ath_tx_txqaddbuf(sc, txq, &bf_q, true);
+                       }
+               }
 
+               ath_tx_process_buffer(sc, txq, &ts, bf, &bf_head);
                spin_unlock_bh(&txq->axq_lock);
        }
 }
index 480595f04411a0523537df7e82549a414eb4b415..fe26bf448fdbf5b54f0acfdff41aa8a4f860d235 100644 (file)
@@ -26,6 +26,11 @@ config B43
          This driver can be built as a module (recommended) that will be called "b43".
          If unsure, say M.
 
+config B43_BCMA
+       bool "Support for BCMA bus"
+       depends on B43 && BCMA && BROKEN
+       default y
+
 # Auto-select SSB PCI-HOST support, if possible
 config B43_PCI_AUTOSELECT
        bool
index cef334a8c66992ee3da78cefd7dcc286fb89f15d..95f7c001fda1c130bd2338f4c3d63bed34aecbb0 100644 (file)
@@ -1,4 +1,5 @@
 b43-y                          += main.o
+b43-y                          += bus.o
 b43-y                          += tables.o
 b43-$(CONFIG_B43_PHY_N)                += tables_nphy.o
 b43-$(CONFIG_B43_PHY_N)                += radio_2055.o
index 25a78cfb7d15ebb7119264e2ea05e6afb188f7eb..1cb2ddee9dcfbc501eaf9f873db390efe5b4d890 100644 (file)
@@ -5,12 +5,14 @@
 #include <linux/spinlock.h>
 #include <linux/interrupt.h>
 #include <linux/hw_random.h>
+#include <linux/bcma/bcma.h>
 #include <linux/ssb/ssb.h>
 #include <net/mac80211.h>
 
 #include "debugfs.h"
 #include "leds.h"
 #include "rfkill.h"
+#include "bus.h"
 #include "lo.h"
 #include "phy_common.h"
 
@@ -414,6 +416,17 @@ enum {
 #define B43_MACCMD_CCA                 0x00000008      /* Clear channel assessment */
 #define B43_MACCMD_BGNOISE             0x00000010      /* Background noise */
 
+/* BCMA 802.11 core specific IO Control (BCMA_IOCTL) flags */
+#define B43_BCMA_IOCTL_PHY_CLKEN       0x00000004      /* PHY Clock Enable */
+#define B43_BCMA_IOCTL_PHY_RESET       0x00000008      /* PHY Reset */
+#define B43_BCMA_IOCTL_MACPHYCLKEN     0x00000010      /* MAC PHY Clock Control Enable */
+#define B43_BCMA_IOCTL_PLLREFSEL       0x00000020      /* PLL Frequency Reference Select */
+#define B43_BCMA_IOCTL_PHY_BW          0x000000C0      /* PHY band width and clock speed mask (N-PHY+ only?) */
+#define  B43_BCMA_IOCTL_PHY_BW_10MHZ   0x00000000      /* 10 MHz bandwidth, 40 MHz PHY */
+#define  B43_BCMA_IOCTL_PHY_BW_20MHZ   0x00000040      /* 20 MHz bandwidth, 80 MHz PHY */
+#define  B43_BCMA_IOCTL_PHY_BW_40MHZ   0x00000080      /* 40 MHz bandwidth, 160 MHz PHY */
+#define B43_BCMA_IOCTL_GMODE           0x00002000      /* G Mode Enable */
+
 /* 802.11 core specific TM State Low (SSB_TMSLOW) flags */
 #define B43_TMSLOW_GMODE               0x20000000      /* G Mode Enable */
 #define B43_TMSLOW_PHY_BANDWIDTH       0x00C00000      /* PHY band width and clock speed mask (N-PHY only) */
@@ -707,7 +720,8 @@ enum {
 
 /* Data structure for one wireless device (802.11 core) */
 struct b43_wldev {
-       struct ssb_device *sdev;
+       struct ssb_device *sdev; /* TODO: remove when b43_bus_dev is ready */
+       struct b43_bus_dev *dev;
        struct b43_wl *wl;
 
        /* The device initialization status.
@@ -879,36 +893,59 @@ static inline enum ieee80211_band b43_current_band(struct b43_wl *wl)
        return wl->hw->conf.channel->band;
 }
 
+static inline int b43_bus_may_powerdown(struct b43_wldev *wldev)
+{
+       return wldev->dev->bus_may_powerdown(wldev->dev);
+}
+static inline int b43_bus_powerup(struct b43_wldev *wldev, bool dynamic_pctl)
+{
+       return wldev->dev->bus_powerup(wldev->dev, dynamic_pctl);
+}
+static inline int b43_device_is_enabled(struct b43_wldev *wldev)
+{
+       return wldev->dev->device_is_enabled(wldev->dev);
+}
+static inline void b43_device_enable(struct b43_wldev *wldev,
+                                    u32 core_specific_flags)
+{
+       wldev->dev->device_enable(wldev->dev, core_specific_flags);
+}
+static inline void b43_device_disable(struct b43_wldev *wldev,
+                                     u32 core_specific_flags)
+{
+       wldev->dev->device_disable(wldev->dev, core_specific_flags);
+}
+
 static inline u16 b43_read16(struct b43_wldev *dev, u16 offset)
 {
-       return ssb_read16(dev->sdev, offset);
+       return dev->dev->read16(dev->dev, offset);
 }
 
 static inline void b43_write16(struct b43_wldev *dev, u16 offset, u16 value)
 {
-       ssb_write16(dev->sdev, offset, value);
+       dev->dev->write16(dev->dev, offset, value);
 }
 
 static inline u32 b43_read32(struct b43_wldev *dev, u16 offset)
 {
-       return ssb_read32(dev->sdev, offset);
+       return dev->dev->read32(dev->dev, offset);
 }
 
 static inline void b43_write32(struct b43_wldev *dev, u16 offset, u32 value)
 {
-       ssb_write32(dev->sdev, offset, value);
+       dev->dev->write32(dev->dev, offset, value);
 }
 
 static inline void b43_block_read(struct b43_wldev *dev, void *buffer,
                                 size_t count, u16 offset, u8 reg_width)
 {
-       ssb_block_read(dev->sdev, buffer, count, offset, reg_width);
+       dev->dev->block_read(dev->dev, buffer, count, offset, reg_width);
 }
 
 static inline void b43_block_write(struct b43_wldev *dev, const void *buffer,
                                   size_t count, u16 offset, u8 reg_width)
 {
-       ssb_block_write(dev->sdev, buffer, count, offset, reg_width);
+       dev->dev->block_write(dev->dev, buffer, count, offset, reg_width);
 }
 
 static inline bool b43_using_pio_transfers(struct b43_wldev *dev)
diff --git a/drivers/net/wireless/b43/bus.c b/drivers/net/wireless/b43/bus.c
new file mode 100644 (file)
index 0000000..6c63aec
--- /dev/null
@@ -0,0 +1,122 @@
+/*
+
+  Broadcom B43 wireless driver
+  Bus abstraction layer
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 2 of the License, or
+  (at your option) any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program; see the file COPYING.  If not, write to
+  the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
+  Boston, MA 02110-1301, USA.
+
+*/
+
+#include "b43.h"
+#include "bus.h"
+
+
+/* SSB */
+
+static inline int b43_bus_ssb_bus_may_powerdown(struct b43_bus_dev *dev)
+{
+       return ssb_bus_may_powerdown(dev->sdev->bus);
+}
+static inline int b43_bus_ssb_bus_powerup(struct b43_bus_dev *dev,
+                                         bool dynamic_pctl)
+{
+       return ssb_bus_powerup(dev->sdev->bus, dynamic_pctl);
+}
+static inline int b43_bus_ssb_device_is_enabled(struct b43_bus_dev *dev)
+{
+       return ssb_device_is_enabled(dev->sdev);
+}
+static inline void b43_bus_ssb_device_enable(struct b43_bus_dev *dev,
+                                            u32 core_specific_flags)
+{
+       ssb_device_enable(dev->sdev, core_specific_flags);
+}
+static inline void b43_bus_ssb_device_disable(struct b43_bus_dev *dev,
+                                             u32 core_specific_flags)
+{
+       ssb_device_disable(dev->sdev, core_specific_flags);
+}
+
+static inline u16 b43_bus_ssb_read16(struct b43_bus_dev *dev, u16 offset)
+{
+       return ssb_read16(dev->sdev, offset);
+}
+static inline u32 b43_bus_ssb_read32(struct b43_bus_dev *dev, u16 offset)
+{
+       return ssb_read32(dev->sdev, offset);
+}
+static inline
+void b43_bus_ssb_write16(struct b43_bus_dev *dev, u16 offset, u16 value)
+{
+       ssb_write16(dev->sdev, offset, value);
+}
+static inline
+void b43_bus_ssb_write32(struct b43_bus_dev *dev, u16 offset, u32 value)
+{
+       ssb_write32(dev->sdev, offset, value);
+}
+static inline
+void b43_bus_ssb_block_read(struct b43_bus_dev *dev, void *buffer,
+                           size_t count, u16 offset, u8 reg_width)
+{
+       ssb_block_read(dev->sdev, buffer, count, offset, reg_width);
+}
+static inline
+void b43_bus_ssb_block_write(struct b43_bus_dev *dev, const void *buffer,
+                            size_t count, u16 offset, u8 reg_width)
+{
+       ssb_block_write(dev->sdev, buffer, count, offset, reg_width);
+}
+
+struct b43_bus_dev *b43_bus_dev_ssb_init(struct ssb_device *sdev)
+{
+       struct b43_bus_dev *dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+
+       dev->bus_type = B43_BUS_SSB;
+       dev->sdev = sdev;
+
+       dev->bus_may_powerdown = b43_bus_ssb_bus_may_powerdown;
+       dev->bus_powerup = b43_bus_ssb_bus_powerup;
+       dev->device_is_enabled = b43_bus_ssb_device_is_enabled;
+       dev->device_enable = b43_bus_ssb_device_enable;
+       dev->device_disable = b43_bus_ssb_device_disable;
+
+       dev->read16 = b43_bus_ssb_read16;
+       dev->read32 = b43_bus_ssb_read32;
+       dev->write16 = b43_bus_ssb_write16;
+       dev->write32 = b43_bus_ssb_write32;
+       dev->block_read = b43_bus_ssb_block_read;
+       dev->block_write = b43_bus_ssb_block_write;
+
+       dev->dev = sdev->dev;
+       dev->dma_dev = sdev->dma_dev;
+       dev->irq = sdev->irq;
+
+       dev->board_vendor = sdev->bus->boardinfo.vendor;
+       dev->board_type = sdev->bus->boardinfo.type;
+       dev->board_rev = sdev->bus->boardinfo.rev;
+
+       dev->chip_id = sdev->bus->chip_id;
+       dev->chip_rev = sdev->bus->chip_rev;
+       dev->chip_pkg = sdev->bus->chip_package;
+
+       dev->bus_sprom = &sdev->bus->sprom;
+
+       dev->core_id = sdev->id.coreid;
+       dev->core_rev = sdev->id.revision;
+
+       return dev;
+}
diff --git a/drivers/net/wireless/b43/bus.h b/drivers/net/wireless/b43/bus.h
new file mode 100644 (file)
index 0000000..79a5ab4
--- /dev/null
@@ -0,0 +1,62 @@
+#ifndef B43_BUS_H_
+#define B43_BUS_H_
+
+enum b43_bus_type {
+       B43_BUS_SSB,
+};
+
+struct b43_bus_dev {
+       enum b43_bus_type bus_type;
+       union {
+               struct ssb_device *sdev;
+       };
+
+       int (*bus_may_powerdown)(struct b43_bus_dev *dev);
+       int (*bus_powerup)(struct b43_bus_dev *dev, bool dynamic_pctl);
+       int (*device_is_enabled)(struct b43_bus_dev *dev);
+       void (*device_enable)(struct b43_bus_dev *dev,
+                             u32 core_specific_flags);
+       void (*device_disable)(struct b43_bus_dev *dev,
+                              u32 core_specific_flags);
+
+       u16 (*read16)(struct b43_bus_dev *dev, u16 offset);
+       u32 (*read32)(struct b43_bus_dev *dev, u16 offset);
+       void (*write16)(struct b43_bus_dev *dev, u16 offset, u16 value);
+       void (*write32)(struct b43_bus_dev *dev, u16 offset, u32 value);
+       void (*block_read)(struct b43_bus_dev *dev, void *buffer,
+                          size_t count, u16 offset, u8 reg_width);
+       void (*block_write)(struct b43_bus_dev *dev, const void *buffer,
+                           size_t count, u16 offset, u8 reg_width);
+
+       struct device *dev;
+       struct device *dma_dev;
+       unsigned int irq;
+
+       u16 board_vendor;
+       u16 board_type;
+       u16 board_rev;
+
+       u16 chip_id;
+       u8 chip_rev;
+       u8 chip_pkg;
+
+       struct ssb_sprom *bus_sprom;
+
+       u16 core_id;
+       u8 core_rev;
+};
+
+static inline bool b43_bus_host_is_pcmcia(struct b43_bus_dev *dev)
+{
+       return (dev->bus_type == B43_BUS_SSB &&
+               dev->sdev->bus->bustype == SSB_BUSTYPE_PCMCIA);
+}
+static inline bool b43_bus_host_is_sdio(struct b43_bus_dev *dev)
+{
+       return (dev->bus_type == B43_BUS_SSB &&
+               dev->sdev->bus->bustype == SSB_BUSTYPE_SDIO);
+}
+
+struct b43_bus_dev *b43_bus_dev_ssb_init(struct ssb_device *sdev);
+
+#endif /* B43_BUS_H_ */
index 47d44bcff37dccb73705e4a2575470010650f83b..d02cf8300e3eee0407c0dcf4dec5b2e18de55d86 100644 (file)
@@ -333,10 +333,10 @@ static inline
        dma_addr_t dmaaddr;
 
        if (tx) {
-               dmaaddr = dma_map_single(ring->dev->sdev->dma_dev,
+               dmaaddr = dma_map_single(ring->dev->dev->dma_dev,
                                         buf, len, DMA_TO_DEVICE);
        } else {
-               dmaaddr = dma_map_single(ring->dev->sdev->dma_dev,
+               dmaaddr = dma_map_single(ring->dev->dev->dma_dev,
                                         buf, len, DMA_FROM_DEVICE);
        }
 
@@ -348,10 +348,10 @@ static inline
                          dma_addr_t addr, size_t len, int tx)
 {
        if (tx) {
-               dma_unmap_single(ring->dev->sdev->dma_dev,
+               dma_unmap_single(ring->dev->dev->dma_dev,
                                 addr, len, DMA_TO_DEVICE);
        } else {
-               dma_unmap_single(ring->dev->sdev->dma_dev,
+               dma_unmap_single(ring->dev->dev->dma_dev,
                                 addr, len, DMA_FROM_DEVICE);
        }
 }
@@ -361,7 +361,7 @@ static inline
                                 dma_addr_t addr, size_t len)
 {
        B43_WARN_ON(ring->tx);
-       dma_sync_single_for_cpu(ring->dev->sdev->dma_dev,
+       dma_sync_single_for_cpu(ring->dev->dev->dma_dev,
                                    addr, len, DMA_FROM_DEVICE);
 }
 
@@ -370,7 +370,7 @@ static inline
                                    dma_addr_t addr, size_t len)
 {
        B43_WARN_ON(ring->tx);
-       dma_sync_single_for_device(ring->dev->sdev->dma_dev,
+       dma_sync_single_for_device(ring->dev->dev->dma_dev,
                                   addr, len, DMA_FROM_DEVICE);
 }
 
@@ -401,7 +401,7 @@ static int alloc_ringmemory(struct b43_dmaring *ring)
         */
        if (ring->type == B43_DMA_64BIT)
                flags |= GFP_DMA;
-       ring->descbase = dma_alloc_coherent(ring->dev->sdev->dma_dev,
+       ring->descbase = dma_alloc_coherent(ring->dev->dev->dma_dev,
                                            B43_DMA_RINGMEMSIZE,
                                            &(ring->dmabase), flags);
        if (!ring->descbase) {
@@ -415,7 +415,7 @@ static int alloc_ringmemory(struct b43_dmaring *ring)
 
 static void free_ringmemory(struct b43_dmaring *ring)
 {
-       dma_free_coherent(ring->dev->sdev->dma_dev, B43_DMA_RINGMEMSIZE,
+       dma_free_coherent(ring->dev->dev->dma_dev, B43_DMA_RINGMEMSIZE,
                          ring->descbase, ring->dmabase);
 }
 
@@ -523,7 +523,7 @@ static bool b43_dma_mapping_error(struct b43_dmaring *ring,
                                  dma_addr_t addr,
                                  size_t buffersize, bool dma_to_device)
 {
-       if (unlikely(dma_mapping_error(ring->dev->sdev->dma_dev, addr)))
+       if (unlikely(dma_mapping_error(ring->dev->dev->dma_dev, addr)))
                return 1;
 
        switch (ring->type) {
@@ -757,14 +757,14 @@ static void dmacontroller_cleanup(struct b43_dmaring *ring)
 
 static void free_all_descbuffers(struct b43_dmaring *ring)
 {
-       struct b43_dmadesc_generic *desc;
        struct b43_dmadesc_meta *meta;
        int i;
 
        if (!ring->used_slots)
                return;
        for (i = 0; i < ring->nr_slots; i++) {
-               desc = ring->ops->idx2desc(ring, i, &meta);
+               /* get meta - ignore returned value */
+               ring->ops->idx2desc(ring, i, &meta);
 
                if (!meta->skb || b43_dma_ptr_is_poisoned(meta->skb)) {
                        B43_WARN_ON(!ring->tx);
@@ -869,7 +869,7 @@ struct b43_dmaring *b43_setup_dmaring(struct b43_wldev *dev,
                        goto err_kfree_meta;
 
                /* test for ability to dma to txhdr_cache */
-               dma_test = dma_map_single(dev->sdev->dma_dev,
+               dma_test = dma_map_single(dev->dev->dma_dev,
                                          ring->txhdr_cache,
                                          b43_txhdr_size(dev),
                                          DMA_TO_DEVICE);
@@ -884,7 +884,7 @@ struct b43_dmaring *b43_setup_dmaring(struct b43_wldev *dev,
                        if (!ring->txhdr_cache)
                                goto err_kfree_meta;
 
-                       dma_test = dma_map_single(dev->sdev->dma_dev,
+                       dma_test = dma_map_single(dev->dev->dma_dev,
                                                  ring->txhdr_cache,
                                                  b43_txhdr_size(dev),
                                                  DMA_TO_DEVICE);
@@ -898,7 +898,7 @@ struct b43_dmaring *b43_setup_dmaring(struct b43_wldev *dev,
                        }
                }
 
-               dma_unmap_single(dev->sdev->dma_dev,
+               dma_unmap_single(dev->dev->dma_dev,
                                 dma_test, b43_txhdr_size(dev),
                                 DMA_TO_DEVICE);
        }
@@ -1013,9 +1013,9 @@ static int b43_dma_set_mask(struct b43_wldev *dev, u64 mask)
        /* Try to set the DMA mask. If it fails, try falling back to a
         * lower mask, as we can always also support a lower one. */
        while (1) {
-               err = dma_set_mask(dev->sdev->dma_dev, mask);
+               err = dma_set_mask(dev->dev->dma_dev, mask);
                if (!err) {
-                       err = dma_set_coherent_mask(dev->sdev->dma_dev, mask);
+                       err = dma_set_coherent_mask(dev->dev->dma_dev, mask);
                        if (!err)
                                break;
                }
@@ -1085,7 +1085,7 @@ int b43_dma_init(struct b43_wldev *dev)
                goto err_destroy_mcast;
 
        /* No support for the TX status DMA ring. */
-       B43_WARN_ON(dev->sdev->id.revision < 5);
+       B43_WARN_ON(dev->dev->core_rev < 5);
 
        b43dbg(dev->wl, "%u-bit DMA initialized\n",
               (unsigned int)type);
@@ -1388,7 +1388,6 @@ void b43_dma_handle_txstatus(struct b43_wldev *dev,
 {
        const struct b43_dma_ops *ops;
        struct b43_dmaring *ring;
-       struct b43_dmadesc_generic *desc;
        struct b43_dmadesc_meta *meta;
        int slot, firstused;
        bool frame_succeed;
@@ -1416,7 +1415,8 @@ void b43_dma_handle_txstatus(struct b43_wldev *dev,
        ops = ring->ops;
        while (1) {
                B43_WARN_ON(slot < 0 || slot >= ring->nr_slots);
-               desc = ops->idx2desc(ring, slot, &meta);
+               /* get meta - ignore returned value */
+               ops->idx2desc(ring, slot, &meta);
 
                if (b43_dma_ptr_is_poisoned(meta->skb)) {
                        b43dbg(dev->wl, "Poisoned TX slot %d (first=%d) "
index 0cafafe368af0467f16fd7eb4072010466ce0184..b56ed41fc1bd31c55a7abc7b799b1d47bf97191a 100644 (file)
@@ -138,7 +138,7 @@ static int b43_register_led(struct b43_wldev *dev, struct b43_led *led,
        led->led_dev.default_trigger = default_trigger;
        led->led_dev.brightness_set = b43_led_brightness_set;
 
-       err = led_classdev_register(dev->sdev->dev, &led->led_dev);
+       err = led_classdev_register(dev->dev->dev, &led->led_dev);
        if (err) {
                b43warn(dev->wl, "LEDs: Failed to register %s\n", name);
                led->wl = NULL;
@@ -215,13 +215,12 @@ static void b43_led_get_sprominfo(struct b43_wldev *dev,
                                  enum b43_led_behaviour *behaviour,
                                  bool *activelow)
 {
-       struct ssb_bus *bus = dev->sdev->bus;
        u8 sprom[4];
 
-       sprom[0] = bus->sprom.gpio0;
-       sprom[1] = bus->sprom.gpio1;
-       sprom[2] = bus->sprom.gpio2;
-       sprom[3] = bus->sprom.gpio3;
+       sprom[0] = dev->dev->bus_sprom->gpio0;
+       sprom[1] = dev->dev->bus_sprom->gpio1;
+       sprom[2] = dev->dev->bus_sprom->gpio2;
+       sprom[3] = dev->dev->bus_sprom->gpio3;
 
        if (sprom[led_index] == 0xFF) {
                /* There is no LED information in the SPROM
@@ -231,12 +230,12 @@ static void b43_led_get_sprominfo(struct b43_wldev *dev,
                case 0:
                        *behaviour = B43_LED_ACTIVITY;
                        *activelow = 1;
-                       if (bus->boardinfo.vendor == PCI_VENDOR_ID_COMPAQ)
+                       if (dev->dev->board_vendor == PCI_VENDOR_ID_COMPAQ)
                                *behaviour = B43_LED_RADIO_ALL;
                        break;
                case 1:
                        *behaviour = B43_LED_RADIO_B;
-                       if (bus->boardinfo.vendor == PCI_VENDOR_ID_ASUSTEK)
+                       if (dev->dev->board_vendor == PCI_VENDOR_ID_ASUSTEK)
                                *behaviour = B43_LED_ASSOC;
                        break;
                case 2:
index 2ef7d4b3854021fbfcec018225c309efa3d39daa..a3dc8bb8ca956d3d9a5465647c01e46e65a0d153 100644 (file)
@@ -98,7 +98,7 @@ static u16 lo_measure_feedthrough(struct b43_wldev *dev,
                rfover |= pga;
                rfover |= lna;
                rfover |= trsw_rx;
-               if ((dev->sdev->bus->sprom.boardflags_lo & B43_BFL_EXTLNA)
+               if ((dev->dev->bus_sprom->boardflags_lo & B43_BFL_EXTLNA)
                    && phy->rev > 6)
                        rfover |= B43_PHY_RFOVERVAL_EXTLNA;
 
@@ -301,14 +301,12 @@ static void lo_measure_gain_values(struct b43_wldev *dev,
                max_rx_gain = 0;
 
        if (has_loopback_gain(phy)) {
-               int trsw_rx = 0;
                int trsw_rx_gain;
 
                if (use_trsw_rx) {
                        trsw_rx_gain = gphy->trsw_rx_gain / 2;
                        if (max_rx_gain >= trsw_rx_gain) {
                                trsw_rx_gain = max_rx_gain - trsw_rx_gain;
-                               trsw_rx = 0x20;
                        }
                } else
                        trsw_rx_gain = max_rx_gain;
@@ -387,7 +385,7 @@ struct lo_g_saved_values {
 static void lo_measure_setup(struct b43_wldev *dev,
                             struct lo_g_saved_values *sav)
 {
-       struct ssb_sprom *sprom = &dev->sdev->bus->sprom;
+       struct ssb_sprom *sprom = dev->dev->bus_sprom;
        struct b43_phy *phy = &dev->phy;
        struct b43_phy_g *gphy = phy->g;
        struct b43_txpower_lo_control *lo = gphy->lo_control;
index d74bc5ff8e1356e5c4318fe1c4b2156c025b51ab..cae31463ead93810838b025171e3775de5260ee3 100644 (file)
@@ -113,6 +113,16 @@ static int b43_modparam_pio = B43_PIO_DEFAULT;
 module_param_named(pio, b43_modparam_pio, int, 0644);
 MODULE_PARM_DESC(pio, "Use PIO accesses by default: 0=DMA, 1=PIO");
 
+#ifdef CONFIG_B43_BCMA
+static const struct bcma_device_id b43_bcma_tbl[] = {
+       BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x17, BCMA_ANY_CLASS),
+       BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x18, BCMA_ANY_CLASS),
+       BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x1D, BCMA_ANY_CLASS),
+       BCMA_CORETABLE_END
+};
+MODULE_DEVICE_TABLE(bcma, b43_bcma_tbl);
+#endif
+
 static const struct ssb_device_id b43_ssb_tbl[] = {
        SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 5),
        SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 6),
@@ -548,7 +558,7 @@ void b43_tsf_read(struct b43_wldev *dev, u64 *tsf)
 {
        u32 low, high;
 
-       B43_WARN_ON(dev->sdev->id.revision < 3);
+       B43_WARN_ON(dev->dev->core_rev < 3);
 
        /* The hardware guarantees us an atomic read, if we
         * read the low register first. */
@@ -586,7 +596,7 @@ static void b43_tsf_write_locked(struct b43_wldev *dev, u64 tsf)
 {
        u32 low, high;
 
-       B43_WARN_ON(dev->sdev->id.revision < 3);
+       B43_WARN_ON(dev->dev->core_rev < 3);
 
        low = tsf;
        high = (tsf >> 32);
@@ -714,7 +724,7 @@ void b43_dummy_transmission(struct b43_wldev *dev, bool ofdm, bool pa_on)
                b43_ram_write(dev, i * 4, buffer[i]);
 
        b43_write16(dev, 0x0568, 0x0000);
-       if (dev->sdev->id.revision < 11)
+       if (dev->dev->core_rev < 11)
                b43_write16(dev, 0x07C0, 0x0000);
        else
                b43_write16(dev, 0x07C0, 0x0100);
@@ -1132,7 +1142,7 @@ void b43_power_saving_ctl_bits(struct b43_wldev *dev, unsigned int ps_flags)
        b43_write32(dev, B43_MMIO_MACCTL, macctl);
        /* Commit write */
        b43_read32(dev, B43_MMIO_MACCTL);
-       if (awake && dev->sdev->id.revision >= 5) {
+       if (awake && dev->dev->core_rev >= 5) {
                /* Wait for the microcode to wake up. */
                for (i = 0; i < 100; i++) {
                        ucstat = b43_shm_read16(dev, B43_SHM_SHARED,
@@ -1144,35 +1154,39 @@ void b43_power_saving_ctl_bits(struct b43_wldev *dev, unsigned int ps_flags)
        }
 }
 
-static void b43_ssb_wireless_core_reset(struct b43_wldev *dev, u32 flags)
+static void b43_ssb_wireless_core_reset(struct b43_wldev *dev, bool gmode)
 {
+       struct ssb_device *sdev = dev->dev->sdev;
        u32 tmslow;
+       u32 flags = 0;
 
+       if (gmode)
+               flags |= B43_TMSLOW_GMODE;
        flags |= B43_TMSLOW_PHYCLKEN;
        flags |= B43_TMSLOW_PHYRESET;
        if (dev->phy.type == B43_PHYTYPE_N)
                flags |= B43_TMSLOW_PHY_BANDWIDTH_20MHZ; /* Make 20 MHz def */
-       ssb_device_enable(dev->sdev, flags);
+       b43_device_enable(dev, flags);
        msleep(2);              /* Wait for the PLL to turn on. */
 
        /* Now take the PHY out of Reset again */
-       tmslow = ssb_read32(dev->sdev, SSB_TMSLOW);
+       tmslow = ssb_read32(sdev, SSB_TMSLOW);
        tmslow |= SSB_TMSLOW_FGC;
        tmslow &= ~B43_TMSLOW_PHYRESET;
-       ssb_write32(dev->sdev, SSB_TMSLOW, tmslow);
-       ssb_read32(dev->sdev, SSB_TMSLOW);      /* flush */
+       ssb_write32(sdev, SSB_TMSLOW, tmslow);
+       ssb_read32(sdev, SSB_TMSLOW);   /* flush */
        msleep(1);
        tmslow &= ~SSB_TMSLOW_FGC;
-       ssb_write32(dev->sdev, SSB_TMSLOW, tmslow);
-       ssb_read32(dev->sdev, SSB_TMSLOW);      /* flush */
+       ssb_write32(sdev, SSB_TMSLOW, tmslow);
+       ssb_read32(sdev, SSB_TMSLOW);   /* flush */
        msleep(1);
 }
 
-void b43_wireless_core_reset(struct b43_wldev *dev, u32 flags)
+void b43_wireless_core_reset(struct b43_wldev *dev, bool gmode)
 {
        u32 macctl;
 
-       b43_ssb_wireless_core_reset(dev, flags);
+       b43_ssb_wireless_core_reset(dev, gmode);
 
        /* Turn Analog ON, but only if we already know the PHY-type.
         * This protects against very early setup where we don't know the
@@ -1183,7 +1197,7 @@ void b43_wireless_core_reset(struct b43_wldev *dev, u32 flags)
 
        macctl = b43_read32(dev, B43_MMIO_MACCTL);
        macctl &= ~B43_MACCTL_GMODE;
-       if (flags & B43_TMSLOW_GMODE)
+       if (gmode)
                macctl |= B43_MACCTL_GMODE;
        macctl |= B43_MACCTL_IHR_ENABLED;
        b43_write32(dev, B43_MMIO_MACCTL, macctl);
@@ -1221,7 +1235,7 @@ static void drain_txstatus_queue(struct b43_wldev *dev)
 {
        u32 dummy;
 
-       if (dev->sdev->id.revision < 5)
+       if (dev->dev->core_rev < 5)
                return;
        /* Read all entries from the microcode TXstatus FIFO
         * and throw them away.
@@ -1427,9 +1441,9 @@ u8 b43_ieee80211_antenna_sanitize(struct b43_wldev *dev,
 
        /* Get the mask of available antennas. */
        if (dev->phy.gmode)
-               antenna_mask = dev->sdev->bus->sprom.ant_available_bg;
+               antenna_mask = dev->dev->bus_sprom->ant_available_bg;
        else
-               antenna_mask = dev->sdev->bus->sprom.ant_available_a;
+               antenna_mask = dev->dev->bus_sprom->ant_available_a;
 
        if (!(antenna_mask & (1 << (antenna_nr - 1)))) {
                /* This antenna is not available. Fall back to default. */
@@ -1644,7 +1658,7 @@ static void b43_beacon_update_trigger_work(struct work_struct *work)
        mutex_lock(&wl->mutex);
        dev = wl->current_dev;
        if (likely(dev && (b43_status(dev) >= B43_STAT_INITIALIZED))) {
-               if (dev->sdev->bus->bustype == SSB_BUSTYPE_SDIO) {
+               if (b43_bus_host_is_sdio(dev->dev)) {
                        /* wl->mutex is enough. */
                        b43_do_beacon_update_trigger_work(dev);
                        mmiowb();
@@ -1689,7 +1703,7 @@ static void b43_update_templates(struct b43_wl *wl)
 static void b43_set_beacon_int(struct b43_wldev *dev, u16 beacon_int)
 {
        b43_time_lock(dev);
-       if (dev->sdev->id.revision >= 3) {
+       if (dev->dev->core_rev >= 3) {
                b43_write32(dev, B43_MMIO_TSF_CFP_REP, (beacon_int << 16));
                b43_write32(dev, B43_MMIO_TSF_CFP_START, (beacon_int << 10));
        } else {
@@ -2063,7 +2077,7 @@ int b43_do_request_fw(struct b43_request_fw_context *ctx,
                B43_WARN_ON(1);
                return -ENOSYS;
        }
-       err = request_firmware(&blob, ctx->fwname, ctx->dev->sdev->dev);
+       err = request_firmware(&blob, ctx->fwname, ctx->dev->dev->dev);
        if (err == -ENOENT) {
                snprintf(ctx->errors[ctx->req_type],
                         sizeof(ctx->errors[ctx->req_type]),
@@ -2113,7 +2127,7 @@ static int b43_try_request_fw(struct b43_request_fw_context *ctx)
 {
        struct b43_wldev *dev = ctx->dev;
        struct b43_firmware *fw = &ctx->dev->fw;
-       const u8 rev = ctx->dev->sdev->id.revision;
+       const u8 rev = ctx->dev->dev->core_rev;
        const char *filename;
        u32 tmshigh;
        int err;
@@ -2157,7 +2171,7 @@ static int b43_try_request_fw(struct b43_request_fw_context *ctx)
        switch (dev->phy.type) {
        case B43_PHYTYPE_A:
                if ((rev >= 5) && (rev <= 10)) {
-                       tmshigh = ssb_read32(dev->sdev, SSB_TMSHIGH);
+                       tmshigh = ssb_read32(dev->dev->sdev, SSB_TMSHIGH);
                        if (tmshigh & B43_TMSHIGH_HAVE_2GHZ_PHY)
                                filename = "a0g1initvals5";
                        else
@@ -2202,7 +2216,7 @@ static int b43_try_request_fw(struct b43_request_fw_context *ctx)
        switch (dev->phy.type) {
        case B43_PHYTYPE_A:
                if ((rev >= 5) && (rev <= 10)) {
-                       tmshigh = ssb_read32(dev->sdev, SSB_TMSHIGH);
+                       tmshigh = ssb_read32(dev->dev->sdev, SSB_TMSHIGH);
                        if (tmshigh & B43_TMSHIGH_HAVE_2GHZ_PHY)
                                filename = "a0g1bsinitvals5";
                        else
@@ -2448,7 +2462,7 @@ static int b43_upload_microcode(struct b43_wldev *dev)
 
        snprintf(wiphy->fw_version, sizeof(wiphy->fw_version), "%u.%u",
                        dev->fw.rev, dev->fw.patch);
-       wiphy->hw_version = dev->sdev->id.coreid;
+       wiphy->hw_version = dev->dev->core_id;
 
        if (b43_is_old_txhdr_format(dev)) {
                /* We're over the deadline, but we keep support for old fw
@@ -2566,7 +2580,7 @@ out:
  */
 static struct ssb_device *b43_ssb_gpio_dev(struct b43_wldev *dev)
 {
-       struct ssb_bus *bus = dev->sdev->bus;
+       struct ssb_bus *bus = dev->dev->sdev->bus;
 
 #ifdef CONFIG_SSB_DRIVER_PCICORE
        return (bus->chipco.dev ? bus->chipco.dev : bus->pcicore.dev);
@@ -2588,7 +2602,7 @@ static int b43_gpio_init(struct b43_wldev *dev)
 
        mask = 0x0000001F;
        set = 0x0000000F;
-       if (dev->sdev->bus->chip_id == 0x4301) {
+       if (dev->dev->chip_id == 0x4301) {
                mask |= 0x0060;
                set |= 0x0060;
        }
@@ -2599,14 +2613,14 @@ static int b43_gpio_init(struct b43_wldev *dev)
                mask |= 0x0180;
                set |= 0x0180;
        }
-       if (dev->sdev->bus->sprom.boardflags_lo & B43_BFL_PACTRL) {
+       if (dev->dev->bus_sprom->boardflags_lo & B43_BFL_PACTRL) {
                b43_write16(dev, B43_MMIO_GPIO_MASK,
                            b43_read16(dev, B43_MMIO_GPIO_MASK)
                            | 0x0200);
                mask |= 0x0200;
                set |= 0x0200;
        }
-       if (dev->sdev->id.revision >= 2)
+       if (dev->dev->core_rev >= 2)
                mask |= 0x0010; /* FIXME: This is redundant. */
 
        gpiodev = b43_ssb_gpio_dev(dev);
@@ -2741,15 +2755,15 @@ static void b43_adjust_opmode(struct b43_wldev *dev)
        /* Workaround: On old hardware the HW-MAC-address-filter
         * doesn't work properly, so always run promisc in filter
         * it in software. */
-       if (dev->sdev->id.revision <= 4)
+       if (dev->dev->core_rev <= 4)
                ctl |= B43_MACCTL_PROMISC;
 
        b43_write32(dev, B43_MMIO_MACCTL, ctl);
 
        cfp_pretbtt = 2;
        if ((ctl & B43_MACCTL_INFRA) && !(ctl & B43_MACCTL_AP)) {
-               if (dev->sdev->bus->chip_id == 0x4306 &&
-                   dev->sdev->bus->chip_rev == 3)
+               if (dev->dev->chip_id == 0x4306 &&
+                   dev->dev->chip_rev == 3)
                        cfp_pretbtt = 100;
                else
                        cfp_pretbtt = 50;
@@ -2907,7 +2921,7 @@ static int b43_chip_init(struct b43_wldev *dev)
                b43_write16(dev, 0x005E, value16);
        }
        b43_write32(dev, 0x0100, 0x01000000);
-       if (dev->sdev->id.revision < 5)
+       if (dev->dev->core_rev < 5)
                b43_write32(dev, 0x010C, 0x01000000);
 
        b43_write32(dev, B43_MMIO_MACCTL, b43_read32(dev, B43_MMIO_MACCTL)
@@ -2922,7 +2936,7 @@ static int b43_chip_init(struct b43_wldev *dev)
        /* Initially set the wireless operation mode. */
        b43_adjust_opmode(dev);
 
-       if (dev->sdev->id.revision < 3) {
+       if (dev->dev->core_rev < 3) {
                b43_write16(dev, 0x060E, 0x0000);
                b43_write16(dev, 0x0610, 0x8000);
                b43_write16(dev, 0x0604, 0x0000);
@@ -3105,7 +3119,7 @@ static int b43_validate_chipaccess(struct b43_wldev *dev)
        b43_shm_write32(dev, B43_SHM_SHARED, 0, backup0);
        b43_shm_write32(dev, B43_SHM_SHARED, 4, backup4);
 
-       if ((dev->sdev->id.revision >= 3) && (dev->sdev->id.revision <= 10)) {
+       if ((dev->dev->core_rev >= 3) && (dev->dev->core_rev <= 10)) {
                /* The 32bit register shadows the two 16bit registers
                 * with update sideeffects. Validate this. */
                b43_write16(dev, B43_MMIO_TSF_CFP_START, 0xAAAA);
@@ -3954,7 +3968,7 @@ redo:
 
        /* Disable interrupts on the device. */
        b43_set_status(dev, B43_STAT_INITIALIZED);
-       if (dev->sdev->bus->bustype == SSB_BUSTYPE_SDIO) {
+       if (b43_bus_host_is_sdio(dev->dev)) {
                /* wl->mutex is locked. That is enough. */
                b43_write32(dev, B43_MMIO_GEN_IRQ_MASK, 0);
                b43_read32(dev, B43_MMIO_GEN_IRQ_MASK); /* Flush */
@@ -3967,11 +3981,11 @@ redo:
        /* Synchronize and free the interrupt handlers. Unlock to avoid deadlocks. */
        orig_dev = dev;
        mutex_unlock(&wl->mutex);
-       if (dev->sdev->bus->bustype == SSB_BUSTYPE_SDIO) {
+       if (b43_bus_host_is_sdio(dev->dev)) {
                b43_sdio_free_irq(dev);
        } else {
-               synchronize_irq(dev->sdev->irq);
-               free_irq(dev->sdev->irq, dev);
+               synchronize_irq(dev->dev->irq);
+               free_irq(dev->dev->irq, dev);
        }
        mutex_lock(&wl->mutex);
        dev = wl->current_dev;
@@ -4004,19 +4018,19 @@ static int b43_wireless_core_start(struct b43_wldev *dev)
        B43_WARN_ON(b43_status(dev) != B43_STAT_INITIALIZED);
 
        drain_txstatus_queue(dev);
-       if (dev->sdev->bus->bustype == SSB_BUSTYPE_SDIO) {
+       if (b43_bus_host_is_sdio(dev->dev)) {
                err = b43_sdio_request_irq(dev, b43_sdio_interrupt_handler);
                if (err) {
                        b43err(dev->wl, "Cannot request SDIO IRQ\n");
                        goto out;
                }
        } else {
-               err = request_threaded_irq(dev->sdev->irq, b43_interrupt_handler,
+               err = request_threaded_irq(dev->dev->irq, b43_interrupt_handler,
                                           b43_interrupt_thread_handler,
                                           IRQF_SHARED, KBUILD_MODNAME, dev);
                if (err) {
                        b43err(dev->wl, "Cannot request IRQ-%d\n",
-                              dev->sdev->irq);
+                              dev->dev->irq);
                        goto out;
                }
        }
@@ -4096,10 +4110,10 @@ static int b43_phy_versioning(struct b43_wldev *dev)
               analog_type, phy_type, phy_rev);
 
        /* Get RADIO versioning */
-       if (dev->sdev->bus->chip_id == 0x4317) {
-               if (dev->sdev->bus->chip_rev == 0)
+       if (dev->dev->chip_id == 0x4317) {
+               if (dev->dev->chip_rev == 0)
                        tmp = 0x3205017F;
-               else if (dev->sdev->bus->chip_rev == 1)
+               else if (dev->dev->chip_rev == 1)
                        tmp = 0x4205017F;
                else
                        tmp = 0x5205017F;
@@ -4204,7 +4218,7 @@ static void setup_struct_wldev_for_init(struct b43_wldev *dev)
 
 static void b43_bluetooth_coext_enable(struct b43_wldev *dev)
 {
-       struct ssb_sprom *sprom = &dev->sdev->bus->sprom;
+       struct ssb_sprom *sprom = dev->dev->bus_sprom;
        u64 hf;
 
        if (!modparam_btcoex)
@@ -4231,16 +4245,21 @@ static void b43_bluetooth_coext_disable(struct b43_wldev *dev)
 
 static void b43_imcfglo_timeouts_workaround(struct b43_wldev *dev)
 {
-       struct ssb_bus *bus = dev->sdev->bus;
+       struct ssb_bus *bus;
        u32 tmp;
 
+       if (dev->dev->bus_type != B43_BUS_SSB)
+               return;
+
+       bus = dev->dev->sdev->bus;
+
        if ((bus->chip_id == 0x4311 && bus->chip_rev == 2) ||
            (bus->chip_id == 0x4312)) {
-               tmp = ssb_read32(dev->sdev, SSB_IMCFGLO);
+               tmp = ssb_read32(dev->dev->sdev, SSB_IMCFGLO);
                tmp &= ~SSB_IMCFGLO_REQTO;
                tmp &= ~SSB_IMCFGLO_SERTO;
                tmp |= 0x3;
-               ssb_write32(dev->sdev, SSB_IMCFGLO, tmp);
+               ssb_write32(dev->dev->sdev, SSB_IMCFGLO, tmp);
                ssb_commit_settings(bus);
        }
 }
@@ -4310,29 +4329,26 @@ static void b43_wireless_core_exit(struct b43_wldev *dev)
                dev->wl->current_beacon = NULL;
        }
 
-       ssb_device_disable(dev->sdev, 0);
-       ssb_bus_may_powerdown(dev->sdev->bus);
+       b43_device_disable(dev, 0);
+       b43_bus_may_powerdown(dev);
 }
 
 /* Initialize a wireless core */
 static int b43_wireless_core_init(struct b43_wldev *dev)
 {
        struct ssb_bus *bus = dev->sdev->bus;
-       struct ssb_sprom *sprom = &bus->sprom;
+       struct ssb_sprom *sprom = dev->dev->bus_sprom;
        struct b43_phy *phy = &dev->phy;
        int err;
        u64 hf;
-       u32 tmp;
 
        B43_WARN_ON(b43_status(dev) != B43_STAT_UNINIT);
 
-       err = ssb_bus_powerup(bus, 0);
+       err = b43_bus_powerup(dev, 0);
        if (err)
                goto out;
-       if (!ssb_device_is_enabled(dev->sdev)) {
-               tmp = phy->gmode ? B43_TMSLOW_GMODE : 0;
-               b43_wireless_core_reset(dev, tmp);
-       }
+       if (!b43_device_is_enabled(dev))
+               b43_wireless_core_reset(dev, phy->gmode);
 
        /* Reset all data structures. */
        setup_struct_wldev_for_init(dev);
@@ -4352,7 +4368,7 @@ static int b43_wireless_core_init(struct b43_wldev *dev)
        if (err)
                goto err_busdown;
        b43_shm_write16(dev, B43_SHM_SHARED,
-                       B43_SHM_SH_WLCOREREV, dev->sdev->id.revision);
+                       B43_SHM_SH_WLCOREREV, dev->dev->core_rev);
        hf = b43_hf_read(dev);
        if (phy->type == B43_PHYTYPE_G) {
                hf |= B43_HF_SYMW;
@@ -4399,8 +4415,8 @@ static int b43_wireless_core_init(struct b43_wldev *dev)
        /* Maximum Contention Window */
        b43_shm_write16(dev, B43_SHM_SCRATCH, B43_SHM_SC_MAXCONT, 0x3FF);
 
-       if ((dev->sdev->bus->bustype == SSB_BUSTYPE_PCMCIA) ||
-           (dev->sdev->bus->bustype == SSB_BUSTYPE_SDIO) ||
+       if (b43_bus_host_is_pcmcia(dev->dev) ||
+           b43_bus_host_is_sdio(dev->dev) ||
            dev->use_pio) {
                dev->__using_pio_transfers = 1;
                err = b43_pio_init(dev);
@@ -4414,7 +4430,7 @@ static int b43_wireless_core_init(struct b43_wldev *dev)
        b43_set_synth_pu_delay(dev, 1);
        b43_bluetooth_coext_enable(dev);
 
-       ssb_bus_powerup(bus, !(sprom->boardflags_lo & B43_BFL_XTAL_NOSLOW));
+       b43_bus_powerup(dev, !(sprom->boardflags_lo & B43_BFL_XTAL_NOSLOW));
        b43_upload_card_macaddress(dev);
        b43_security_init(dev);
 
@@ -4431,7 +4447,7 @@ out:
 err_chip_exit:
        b43_chip_exit(dev);
 err_busdown:
-       ssb_bus_may_powerdown(bus);
+       b43_bus_may_powerdown(dev);
        B43_WARN_ON(b43_status(dev) != B43_STAT_UNINIT);
        return err;
 }
@@ -4741,7 +4757,6 @@ static int b43_wireless_core_attach(struct b43_wldev *dev)
        struct pci_dev *pdev = (bus->bustype == SSB_BUSTYPE_PCI) ? bus->host_pci : NULL;
        int err;
        bool have_2ghz_phy = 0, have_5ghz_phy = 0;
-       u32 tmp;
 
        /* Do NOT do any device initialization here.
         * Do it in wireless_core_init() instead.
@@ -4750,13 +4765,13 @@ static int b43_wireless_core_attach(struct b43_wldev *dev)
         * that in core_init(), too.
         */
 
-       err = ssb_bus_powerup(bus, 0);
+       err = b43_bus_powerup(dev, 0);
        if (err) {
                b43err(wl, "Bus powerup failed\n");
                goto out;
        }
        /* Get the PHY type. */
-       if (dev->sdev->id.revision >= 5) {
+       if (dev->dev->core_rev >= 5) {
                u32 tmshigh;
 
                tmshigh = ssb_read32(dev->sdev, SSB_TMSHIGH);
@@ -4767,8 +4782,7 @@ static int b43_wireless_core_attach(struct b43_wldev *dev)
 
        dev->phy.gmode = have_2ghz_phy;
        dev->phy.radio_on = 1;
-       tmp = dev->phy.gmode ? B43_TMSLOW_GMODE : 0;
-       b43_wireless_core_reset(dev, tmp);
+       b43_wireless_core_reset(dev, dev->phy.gmode);
 
        err = b43_phy_versioning(dev);
        if (err)
@@ -4816,8 +4830,7 @@ static int b43_wireless_core_attach(struct b43_wldev *dev)
                goto err_powerdown;
 
        dev->phy.gmode = have_2ghz_phy;
-       tmp = dev->phy.gmode ? B43_TMSLOW_GMODE : 0;
-       b43_wireless_core_reset(dev, tmp);
+       b43_wireless_core_reset(dev, dev->phy.gmode);
 
        err = b43_validate_chipaccess(dev);
        if (err)
@@ -4832,8 +4845,8 @@ static int b43_wireless_core_attach(struct b43_wldev *dev)
        INIT_WORK(&dev->restart_work, b43_chip_reset);
 
        dev->phy.ops->switch_analog(dev, 0);
-       ssb_device_disable(dev->sdev, 0);
-       ssb_bus_may_powerdown(bus);
+       b43_device_disable(dev, 0);
+       b43_bus_may_powerdown(dev);
 
 out:
        return err;
@@ -4841,11 +4854,11 @@ out:
 err_phy_free:
        b43_phy_free(dev);
 err_powerdown:
-       ssb_bus_may_powerdown(bus);
+       b43_bus_may_powerdown(dev);
        return err;
 }
 
-static void b43_one_core_detach(struct ssb_device *dev)
+static void b43_one_core_detach(struct b43_bus_dev *dev)
 {
        struct b43_wldev *wldev;
        struct b43_wl *wl;
@@ -4853,17 +4866,17 @@ static void b43_one_core_detach(struct ssb_device *dev)
        /* Do not cancel ieee80211-workqueue based work here.
         * See comment in b43_remove(). */
 
-       wldev = ssb_get_drvdata(dev);
+       wldev = ssb_get_drvdata(dev->sdev);
        wl = wldev->wl;
        b43_debugfs_remove_device(wldev);
        b43_wireless_core_detach(wldev);
        list_del(&wldev->list);
        wl->nr_devs--;
-       ssb_set_drvdata(dev, NULL);
+       ssb_set_drvdata(dev->sdev, NULL);
        kfree(wldev);
 }
 
-static int b43_one_core_attach(struct ssb_device *dev, struct b43_wl *wl)
+static int b43_one_core_attach(struct b43_bus_dev *dev, struct b43_wl *wl)
 {
        struct b43_wldev *wldev;
        int err = -ENOMEM;
@@ -4873,7 +4886,8 @@ static int b43_one_core_attach(struct ssb_device *dev, struct b43_wl *wl)
                goto out;
 
        wldev->use_pio = b43_modparam_pio;
-       wldev->sdev = dev;
+       wldev->dev = dev;
+       wldev->sdev = dev->sdev; /* TODO: Remove when not needed */
        wldev->wl = wl;
        b43_set_status(wldev, B43_STAT_UNINIT);
        wldev->bad_frames_preempt = modparam_bad_frames_preempt;
@@ -4885,7 +4899,7 @@ static int b43_one_core_attach(struct ssb_device *dev, struct b43_wl *wl)
 
        list_add(&wldev->list, &wl->devlist);
        wl->nr_devs++;
-       ssb_set_drvdata(dev, wldev);
+       ssb_set_drvdata(dev->sdev, wldev);
        b43_debugfs_add_device(wldev);
 
       out:
@@ -4926,11 +4940,11 @@ static void b43_sprom_fixup(struct ssb_bus *bus)
        }
 }
 
-static void b43_wireless_exit(struct ssb_device *dev, struct b43_wl *wl)
+static void b43_wireless_exit(struct b43_bus_dev *dev, struct b43_wl *wl)
 {
        struct ieee80211_hw *hw = wl->hw;
 
-       ssb_set_devtypedata(dev, NULL);
+       ssb_set_devtypedata(dev->sdev, NULL);
        ieee80211_free_hw(hw);
 }
 
@@ -4982,24 +4996,48 @@ static struct b43_wl *b43_wireless_init(struct ssb_device *dev)
        return wl;
 }
 
-static int b43_ssb_probe(struct ssb_device *dev, const struct ssb_device_id *id)
+#ifdef CONFIG_B43_BCMA
+static int b43_bcma_probe(struct bcma_device *core)
+{
+       b43err(NULL, "BCMA is not supported yet!");
+       return -EOPNOTSUPP;
+}
+
+static void b43_bcma_remove(struct bcma_device *core)
+{
+       /* TODO */
+}
+
+static struct bcma_driver b43_bcma_driver = {
+       .name           = KBUILD_MODNAME,
+       .id_table       = b43_bcma_tbl,
+       .probe          = b43_bcma_probe,
+       .remove         = b43_bcma_remove,
+};
+#endif
+
+static
+int b43_ssb_probe(struct ssb_device *sdev, const struct ssb_device_id *id)
 {
+       struct b43_bus_dev *dev;
        struct b43_wl *wl;
        int err;
        int first = 0;
 
-       wl = ssb_get_devtypedata(dev);
+       dev = b43_bus_dev_ssb_init(sdev);
+
+       wl = ssb_get_devtypedata(sdev);
        if (!wl) {
                /* Probing the first core. Must setup common struct b43_wl */
                first = 1;
-               b43_sprom_fixup(dev->bus);
-               wl = b43_wireless_init(dev);
+               b43_sprom_fixup(sdev->bus);
+               wl = b43_wireless_init(sdev);
                if (IS_ERR(wl)) {
                        err = PTR_ERR(wl);
                        goto out;
                }
-               ssb_set_devtypedata(dev, wl);
-               B43_WARN_ON(ssb_get_devtypedata(dev) != wl);
+               ssb_set_devtypedata(sdev, wl);
+               B43_WARN_ON(ssb_get_devtypedata(sdev) != wl);
        }
        err = b43_one_core_attach(dev, wl);
        if (err)
@@ -5023,10 +5061,10 @@ static int b43_ssb_probe(struct ssb_device *dev, const struct ssb_device_id *id)
        return err;
 }
 
-static void b43_ssb_remove(struct ssb_device *dev)
+static void b43_ssb_remove(struct ssb_device *sdev)
 {
-       struct b43_wl *wl = ssb_get_devtypedata(dev);
-       struct b43_wldev *wldev = ssb_get_drvdata(dev);
+       struct b43_wl *wl = ssb_get_devtypedata(sdev);
+       struct b43_wldev *wldev = ssb_get_drvdata(sdev);
 
        /* We must cancel any work here before unregistering from ieee80211,
         * as the ieee80211 unreg will destroy the workqueue. */
@@ -5042,14 +5080,14 @@ static void b43_ssb_remove(struct ssb_device *dev)
                ieee80211_unregister_hw(wl->hw);
        }
 
-       b43_one_core_detach(dev);
+       b43_one_core_detach(wldev->dev);
 
        if (list_empty(&wl->devlist)) {
                b43_leds_unregister(wl);
                /* Last core on the chip unregistered.
                 * We can destroy common struct b43_wl.
                 */
-               b43_wireless_exit(dev, wl);
+               b43_wireless_exit(wldev->dev, wl);
        }
 }
 
@@ -5108,14 +5146,23 @@ static int __init b43_init(void)
        err = b43_sdio_init();
        if (err)
                goto err_pcmcia_exit;
-       err = ssb_driver_register(&b43_ssb_driver);
+#ifdef CONFIG_B43_BCMA
+       err = bcma_driver_register(&b43_bcma_driver);
        if (err)
                goto err_sdio_exit;
+#endif
+       err = ssb_driver_register(&b43_ssb_driver);
+       if (err)
+               goto err_bcma_driver_exit;
        b43_print_driverinfo();
 
        return err;
 
+err_bcma_driver_exit:
+#ifdef CONFIG_B43_BCMA
+       bcma_driver_unregister(&b43_bcma_driver);
 err_sdio_exit:
+#endif
        b43_sdio_exit();
 err_pcmcia_exit:
        b43_pcmcia_exit();
@@ -5127,6 +5174,9 @@ err_dfs_exit:
 static void __exit b43_exit(void)
 {
        ssb_driver_unregister(&b43_ssb_driver);
+#ifdef CONFIG_B43_BCMA
+       bcma_driver_unregister(&b43_bcma_driver);
+#endif
        b43_sdio_exit();
        b43_pcmcia_exit();
        b43_debugfs_exit();
index a0d327f1318356029bcca97e40926f4a4aa32243..e4ebce9be5921663a4971927d5055a9a4aa979c5 100644 (file)
@@ -121,7 +121,7 @@ void b43_hf_write(struct b43_wldev *dev, u64 value);
 
 void b43_dummy_transmission(struct b43_wldev *dev, bool ofdm, bool pa_on);
 
-void b43_wireless_core_reset(struct b43_wldev *dev, u32 flags);
+void b43_wireless_core_reset(struct b43_wldev *dev, bool gmode);
 
 void b43_controller_restart(struct b43_wldev *dev, const char *reason);
 
index b01c8ced57c3938099990b46220431108f521943..73ace5552bad42770fd8085aefaaf4601ee804a4 100644 (file)
@@ -265,7 +265,6 @@ static void hardware_pctl_init_aphy(struct b43_wldev *dev)
 
 void b43_phy_inita(struct b43_wldev *dev)
 {
-       struct ssb_bus *bus = dev->sdev->bus;
        struct b43_phy *phy = &dev->phy;
 
        /* This lowlevel A-PHY init is also called from G-PHY init.
@@ -296,9 +295,9 @@ void b43_phy_inita(struct b43_wldev *dev)
 
                b43_radio_init2060(dev);
 
-               if ((bus->boardinfo.vendor == SSB_BOARDVENDOR_BCM) &&
-                   ((bus->boardinfo.type == SSB_BOARD_BU4306) ||
-                    (bus->boardinfo.type == SSB_BOARD_BU4309))) {
+               if ((dev->dev->board_vendor == SSB_BOARDVENDOR_BCM) &&
+                   ((dev->dev->board_type == SSB_BOARD_BU4306) ||
+                    (dev->dev->board_type == SSB_BOARD_BU4309))) {
                        ; //TODO: A PHY LO
                }
 
@@ -311,7 +310,7 @@ void b43_phy_inita(struct b43_wldev *dev)
        }
 
        if ((phy->type == B43_PHYTYPE_G) &&
-           (dev->sdev->bus->sprom.boardflags_lo & B43_BFL_PACTRL)) {
+           (dev->dev->bus_sprom->boardflags_lo & B43_BFL_PACTRL)) {
                b43_phy_maskset(dev, B43_PHY_OFDM(0x6E), 0xE000, 0x3CF);
        }
 }
@@ -323,17 +322,17 @@ static int b43_aphy_init_tssi2dbm_table(struct b43_wldev *dev)
        struct b43_phy_a *aphy = phy->a;
        s16 pab0, pab1, pab2;
 
-       pab0 = (s16) (dev->sdev->bus->sprom.pa1b0);
-       pab1 = (s16) (dev->sdev->bus->sprom.pa1b1);
-       pab2 = (s16) (dev->sdev->bus->sprom.pa1b2);
+       pab0 = (s16) (dev->dev->bus_sprom->pa1b0);
+       pab1 = (s16) (dev->dev->bus_sprom->pa1b1);
+       pab2 = (s16) (dev->dev->bus_sprom->pa1b2);
 
        if (pab0 != 0 && pab1 != 0 && pab2 != 0 &&
            pab0 != -1 && pab1 != -1 && pab2 != -1) {
                /* The pabX values are set in SPROM. Use them. */
-               if ((s8) dev->sdev->bus->sprom.itssi_a != 0 &&
-                   (s8) dev->sdev->bus->sprom.itssi_a != -1)
+               if ((s8) dev->dev->bus_sprom->itssi_a != 0 &&
+                   (s8) dev->dev->bus_sprom->itssi_a != -1)
                        aphy->tgt_idle_tssi =
-                           (s8) (dev->sdev->bus->sprom.itssi_a);
+                           (s8) (dev->dev->bus_sprom->itssi_a);
                else
                        aphy->tgt_idle_tssi = 62;
                aphy->tssi2dbm = b43_generate_dyn_tssi2dbm_tab(dev, pab0,
index e46b2f4f0920d0ce202dc2b21678603148a5baa8..425af28ea4e5dd445cbbcae917d1a6aab7ac814c 100644 (file)
@@ -168,7 +168,7 @@ void b43_phy_lock(struct b43_wldev *dev)
        B43_WARN_ON(dev->phy.phy_locked);
        dev->phy.phy_locked = 1;
 #endif
-       B43_WARN_ON(dev->sdev->id.revision < 3);
+       B43_WARN_ON(dev->dev->core_rev < 3);
 
        if (!b43_is_mode(dev->wl, NL80211_IFTYPE_AP))
                b43_power_saving_ctl_bits(dev, B43_PS_AWAKE);
@@ -180,7 +180,7 @@ void b43_phy_unlock(struct b43_wldev *dev)
        B43_WARN_ON(!dev->phy.phy_locked);
        dev->phy.phy_locked = 0;
 #endif
-       B43_WARN_ON(dev->sdev->id.revision < 3);
+       B43_WARN_ON(dev->dev->core_rev < 3);
 
        if (!b43_is_mode(dev->wl, NL80211_IFTYPE_AP))
                b43_power_saving_ctl_bits(dev, 0);
@@ -368,8 +368,8 @@ void b43_phy_txpower_check(struct b43_wldev *dev, unsigned int flags)
        /* The next check will be needed in two seconds, or later. */
        phy->next_txpwr_check_time = round_jiffies(now + (HZ * 2));
 
-       if ((dev->sdev->bus->boardinfo.vendor == SSB_BOARDVENDOR_BCM) &&
-           (dev->sdev->bus->boardinfo.type == SSB_BOARD_BU4306))
+       if ((dev->dev->board_vendor == SSB_BOARDVENDOR_BCM) &&
+           (dev->dev->board_type == SSB_BOARD_BU4306))
                return; /* No software txpower adjustment needed */
 
        result = phy->ops->recalc_txpower(dev, !!(flags & B43_TXPWR_IGNORE_TSSI));
index 1758a282f913548403ee0a6b55dacac832ac92f5..83532d19347f8b812909d20b2dfcfb1df09769ec 100644 (file)
@@ -718,7 +718,7 @@ static void b43_calc_nrssi_threshold(struct b43_wldev *dev)
        B43_WARN_ON(phy->type != B43_PHYTYPE_G);
 
        if (!phy->gmode ||
-           !(dev->sdev->bus->sprom.boardflags_lo & B43_BFL_RSSI)) {
+           !(dev->dev->bus_sprom->boardflags_lo & B43_BFL_RSSI)) {
                tmp16 = b43_nrssi_hw_read(dev, 0x20);
                if (tmp16 >= 0x20)
                        tmp16 -= 0x40;
@@ -1114,7 +1114,7 @@ static u16 radio2050_rfover_val(struct b43_wldev *dev,
 {
        struct b43_phy *phy = &dev->phy;
        struct b43_phy_g *gphy = phy->g;
-       struct ssb_sprom *sprom = &(dev->sdev->bus->sprom);
+       struct ssb_sprom *sprom = dev->dev->bus_sprom;
 
        if (!phy->gmode)
                return 0;
@@ -1491,7 +1491,6 @@ static u16 b43_radio_init2050(struct b43_wldev *dev)
 
 static void b43_phy_initb5(struct b43_wldev *dev)
 {
-       struct ssb_bus *bus = dev->sdev->bus;
        struct b43_phy *phy = &dev->phy;
        struct b43_phy_g *gphy = phy->g;
        u16 offset, value;
@@ -1500,8 +1499,8 @@ static void b43_phy_initb5(struct b43_wldev *dev)
        if (phy->analog == 1) {
                b43_radio_set(dev, 0x007A, 0x0050);
        }
-       if ((bus->boardinfo.vendor != SSB_BOARDVENDOR_BCM) &&
-           (bus->boardinfo.type != SSB_BOARD_BU4306)) {
+       if ((dev->dev->board_vendor != SSB_BOARDVENDOR_BCM) &&
+           (dev->dev->board_type != SSB_BOARD_BU4306)) {
                value = 0x2120;
                for (offset = 0x00A8; offset < 0x00C7; offset++) {
                        b43_phy_write(dev, offset, value);
@@ -1620,7 +1619,7 @@ static void b43_phy_initb6(struct b43_wldev *dev)
                b43_radio_write16(dev, 0x5A, 0x88);
                b43_radio_write16(dev, 0x5B, 0x6B);
                b43_radio_write16(dev, 0x5C, 0x0F);
-               if (dev->sdev->bus->sprom.boardflags_lo & B43_BFL_ALTIQ) {
+               if (dev->dev->bus_sprom->boardflags_lo & B43_BFL_ALTIQ) {
                        b43_radio_write16(dev, 0x5D, 0xFA);
                        b43_radio_write16(dev, 0x5E, 0xD8);
                } else {
@@ -1787,7 +1786,7 @@ static void b43_calc_loopback_gain(struct b43_wldev *dev)
        b43_phy_set(dev, B43_PHY_RFOVER, 0x0100);
        b43_phy_mask(dev, B43_PHY_RFOVERVAL, 0xCFFF);
 
-       if (dev->sdev->bus->sprom.boardflags_lo & B43_BFL_EXTLNA) {
+       if (dev->dev->bus_sprom->boardflags_lo & B43_BFL_EXTLNA) {
                if (phy->rev >= 7) {
                        b43_phy_set(dev, B43_PHY_RFOVER, 0x0800);
                        b43_phy_set(dev, B43_PHY_RFOVERVAL, 0x8000);
@@ -1922,7 +1921,6 @@ static void b43_hardware_pctl_init_gphy(struct b43_wldev *dev)
 /* Initialize B/G PHY power control */
 static void b43_phy_init_pctl(struct b43_wldev *dev)
 {
-       struct ssb_bus *bus = dev->sdev->bus;
        struct b43_phy *phy = &dev->phy;
        struct b43_phy_g *gphy = phy->g;
        struct b43_rfatt old_rfatt;
@@ -1931,8 +1929,8 @@ static void b43_phy_init_pctl(struct b43_wldev *dev)
 
        B43_WARN_ON(phy->type != B43_PHYTYPE_G);
 
-       if ((bus->boardinfo.vendor == SSB_BOARDVENDOR_BCM) &&
-           (bus->boardinfo.type == SSB_BOARD_BU4306))
+       if ((dev->dev->board_vendor == SSB_BOARDVENDOR_BCM) &&
+           (dev->dev->board_type == SSB_BOARD_BU4306))
                return;
 
        b43_phy_write(dev, 0x0028, 0x8018);
@@ -2053,7 +2051,7 @@ static void b43_phy_initg(struct b43_wldev *dev)
        if (phy->rev >= 6) {
                b43_phy_maskset(dev, B43_PHY_CCK(0x36), 0x0FFF, (gphy->lo_control->tx_bias << 12));
        }
-       if (dev->sdev->bus->sprom.boardflags_lo & B43_BFL_PACTRL)
+       if (dev->dev->bus_sprom->boardflags_lo & B43_BFL_PACTRL)
                b43_phy_write(dev, B43_PHY_CCK(0x2E), 0x8075);
        else
                b43_phy_write(dev, B43_PHY_CCK(0x2E), 0x807F);
@@ -2066,7 +2064,7 @@ static void b43_phy_initg(struct b43_wldev *dev)
                b43_phy_write(dev, B43_PHY_LO_MASK, 0x8078);
        }
 
-       if (!(dev->sdev->bus->sprom.boardflags_lo & B43_BFL_RSSI)) {
+       if (!(dev->dev->bus_sprom->boardflags_lo & B43_BFL_RSSI)) {
                /* The specs state to update the NRSSI LT with
                 * the value 0x7FFFFFFF here. I think that is some weird
                 * compiler optimization in the original driver.
@@ -2088,8 +2086,8 @@ static void b43_phy_initg(struct b43_wldev *dev)
        /* FIXME: The spec says in the following if, the 0 should be replaced
           'if OFDM may not be used in the current locale'
           but OFDM is legal everywhere */
-       if ((dev->sdev->bus->chip_id == 0x4306
-            && dev->sdev->bus->chip_package == 2) || 0) {
+       if ((dev->dev->chip_id == 0x4306
+            && dev->dev->chip_pkg == 2) || 0) {
                b43_phy_mask(dev, B43_PHY_CRS0, 0xBFFF);
                b43_phy_mask(dev, B43_PHY_OFDM(0xC3), 0x7FFF);
        }
@@ -2105,7 +2103,7 @@ void b43_gphy_channel_switch(struct b43_wldev *dev,
        b43_write16(dev, B43_MMIO_CHANNEL, channel2freq_bg(channel));
 
        if (channel == 14) {
-               if (dev->sdev->bus->sprom.country_code ==
+               if (dev->dev->bus_sprom->country_code ==
                    SSB_SPROM1CCODE_JAPAN)
                        b43_hf_write(dev,
                                     b43_hf_read(dev) & ~B43_HF_ACPR);
@@ -2136,17 +2134,17 @@ static void default_baseband_attenuation(struct b43_wldev *dev,
 static void default_radio_attenuation(struct b43_wldev *dev,
                                      struct b43_rfatt *rf)
 {
-       struct ssb_bus *bus = dev->sdev->bus;
+       struct b43_bus_dev *bdev = dev->dev;
        struct b43_phy *phy = &dev->phy;
 
        rf->with_padmix = 0;
 
-       if (bus->boardinfo.vendor == SSB_BOARDVENDOR_BCM &&
-           bus->boardinfo.type == SSB_BOARD_BCM4309G) {
-               if (bus->boardinfo.rev < 0x43) {
+       if (dev->dev->board_vendor == SSB_BOARDVENDOR_BCM &&
+           dev->dev->board_type == SSB_BOARD_BCM4309G) {
+               if (dev->dev->board_rev < 0x43) {
                        rf->att = 2;
                        return;
-               } else if (bus->boardinfo.rev < 0x51) {
+               } else if (dev->dev->board_rev < 0x51) {
                        rf->att = 3;
                        return;
                }
@@ -2172,21 +2170,21 @@ static void default_radio_attenuation(struct b43_wldev *dev,
                        return;
                case 1:
                        if (phy->type == B43_PHYTYPE_G) {
-                               if (bus->boardinfo.vendor == SSB_BOARDVENDOR_BCM
-                                   && bus->boardinfo.type == SSB_BOARD_BCM4309G
-                                   && bus->boardinfo.rev >= 30)
+                               if (bdev->board_vendor == SSB_BOARDVENDOR_BCM
+                                   && bdev->board_type == SSB_BOARD_BCM4309G
+                                   && bdev->board_rev >= 30)
                                        rf->att = 3;
-                               else if (bus->boardinfo.vendor ==
+                               else if (bdev->board_vendor ==
                                         SSB_BOARDVENDOR_BCM
-                                        && bus->boardinfo.type ==
+                                        && bdev->board_type ==
                                         SSB_BOARD_BU4306)
                                        rf->att = 3;
                                else
                                        rf->att = 1;
                        } else {
-                               if (bus->boardinfo.vendor == SSB_BOARDVENDOR_BCM
-                                   && bus->boardinfo.type == SSB_BOARD_BCM4309G
-                                   && bus->boardinfo.rev >= 30)
+                               if (bdev->board_vendor == SSB_BOARDVENDOR_BCM
+                                   && bdev->board_type == SSB_BOARD_BCM4309G
+                                   && bdev->board_rev >= 30)
                                        rf->att = 7;
                                else
                                        rf->att = 6;
@@ -2194,16 +2192,16 @@ static void default_radio_attenuation(struct b43_wldev *dev,
                        return;
                case 2:
                        if (phy->type == B43_PHYTYPE_G) {
-                               if (bus->boardinfo.vendor == SSB_BOARDVENDOR_BCM
-                                   && bus->boardinfo.type == SSB_BOARD_BCM4309G
-                                   && bus->boardinfo.rev >= 30)
+                               if (bdev->board_vendor == SSB_BOARDVENDOR_BCM
+                                   && bdev->board_type == SSB_BOARD_BCM4309G
+                                   && bdev->board_rev >= 30)
                                        rf->att = 3;
-                               else if (bus->boardinfo.vendor ==
+                               else if (bdev->board_vendor ==
                                         SSB_BOARDVENDOR_BCM
-                                        && bus->boardinfo.type ==
+                                        && bdev->board_type ==
                                         SSB_BOARD_BU4306)
                                        rf->att = 5;
-                               else if (bus->chip_id == 0x4320)
+                               else if (bdev->chip_id == 0x4320)
                                        rf->att = 4;
                                else
                                        rf->att = 3;
@@ -2384,11 +2382,11 @@ static int b43_gphy_init_tssi2dbm_table(struct b43_wldev *dev)
        struct b43_phy_g *gphy = phy->g;
        s16 pab0, pab1, pab2;
 
-       pab0 = (s16) (dev->sdev->bus->sprom.pa0b0);
-       pab1 = (s16) (dev->sdev->bus->sprom.pa0b1);
-       pab2 = (s16) (dev->sdev->bus->sprom.pa0b2);
+       pab0 = (s16) (dev->dev->bus_sprom->pa0b0);
+       pab1 = (s16) (dev->dev->bus_sprom->pa0b1);
+       pab2 = (s16) (dev->dev->bus_sprom->pa0b2);
 
-       B43_WARN_ON((dev->sdev->bus->chip_id == 0x4301) &&
+       B43_WARN_ON((dev->dev->chip_id == 0x4301) &&
                    (phy->radio_ver != 0x2050)); /* Not supported anymore */
 
        gphy->dyn_tssi_tbl = 0;
@@ -2396,10 +2394,10 @@ static int b43_gphy_init_tssi2dbm_table(struct b43_wldev *dev)
        if (pab0 != 0 && pab1 != 0 && pab2 != 0 &&
            pab0 != -1 && pab1 != -1 && pab2 != -1) {
                /* The pabX values are set in SPROM. Use them. */
-               if ((s8) dev->sdev->bus->sprom.itssi_bg != 0 &&
-                   (s8) dev->sdev->bus->sprom.itssi_bg != -1) {
+               if ((s8) dev->dev->bus_sprom->itssi_bg != 0 &&
+                   (s8) dev->dev->bus_sprom->itssi_bg != -1) {
                        gphy->tgt_idle_tssi =
-                               (s8) (dev->sdev->bus->sprom.itssi_bg);
+                               (s8) (dev->dev->bus_sprom->itssi_bg);
                } else
                        gphy->tgt_idle_tssi = 62;
                gphy->tssi2dbm = b43_generate_dyn_tssi2dbm_tab(dev, pab0,
@@ -2537,7 +2535,7 @@ static int b43_gphy_op_prepare_hardware(struct b43_wldev *dev)
                b43_wireless_core_reset(dev, 0);
                b43_phy_initg(dev);
                phy->gmode = 1;
-               b43_wireless_core_reset(dev, B43_TMSLOW_GMODE);
+               b43_wireless_core_reset(dev, 1);
        }
 
        return 0;
@@ -2840,7 +2838,7 @@ static void b43_gphy_op_adjust_txpower(struct b43_wldev *dev)
                                    B43_TXCTL_TXMIX;
                                rfatt += 2;
                                bbatt += 2;
-                       } else if (dev->sdev->bus->sprom.
+                       } else if (dev->dev->bus_sprom->
                                   boardflags_lo &
                                   B43_BFL_PACTRL) {
                                bbatt += 4 * (rfatt - 2);
@@ -2914,14 +2912,14 @@ static enum b43_txpwr_result b43_gphy_op_recalc_txpower(struct b43_wldev *dev,
        estimated_pwr = b43_gphy_estimate_power_out(dev, average_tssi);
 
        B43_WARN_ON(phy->type != B43_PHYTYPE_G);
-       max_pwr = dev->sdev->bus->sprom.maxpwr_bg;
-       if (dev->sdev->bus->sprom.boardflags_lo & B43_BFL_PACTRL)
+       max_pwr = dev->dev->bus_sprom->maxpwr_bg;
+       if (dev->dev->bus_sprom->boardflags_lo & B43_BFL_PACTRL)
                max_pwr -= 3; /* minus 0.75 */
        if (unlikely(max_pwr >= INT_TO_Q52(30/*dBm*/))) {
                b43warn(dev->wl,
                        "Invalid max-TX-power value in SPROM.\n");
                max_pwr = INT_TO_Q52(20); /* fake it */
-               dev->sdev->bus->sprom.maxpwr_bg = max_pwr;
+               dev->dev->bus_sprom->maxpwr_bg = max_pwr;
        }
 
        /* Get desired power (in Q5.2) */
@@ -3014,7 +3012,7 @@ static void b43_gphy_op_pwork_60sec(struct b43_wldev *dev)
 {
        struct b43_phy *phy = &dev->phy;
 
-       if (!(dev->sdev->bus->sprom.boardflags_lo & B43_BFL_RSSI))
+       if (!(dev->dev->bus_sprom->boardflags_lo & B43_BFL_RSSI))
                return;
 
        b43_mac_suspend(dev);
index 012c8da2f9447eec120b5c3bd8d97021f4eb3c01..daec1d9e4a18304a8aff1bb563e48ea91a634a2d 100644 (file)
@@ -85,39 +85,39 @@ static void b43_lpphy_op_free(struct b43_wldev *dev)
 /* http://bcm-v4.sipsolutions.net/802.11/PHY/LP/ReadBandSrom */
 static void lpphy_read_band_sprom(struct b43_wldev *dev)
 {
+       struct ssb_sprom *sprom = dev->dev->bus_sprom;
        struct b43_phy_lp *lpphy = dev->phy.lp;
-       struct ssb_bus *bus = dev->sdev->bus;
        u16 cckpo, maxpwr;
        u32 ofdmpo;
        int i;
 
        if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
-               lpphy->tx_isolation_med_band = bus->sprom.tri2g;
-               lpphy->bx_arch = bus->sprom.bxa2g;
-               lpphy->rx_pwr_offset = bus->sprom.rxpo2g;
-               lpphy->rssi_vf = bus->sprom.rssismf2g;
-               lpphy->rssi_vc = bus->sprom.rssismc2g;
-               lpphy->rssi_gs = bus->sprom.rssisav2g;
-               lpphy->txpa[0] = bus->sprom.pa0b0;
-               lpphy->txpa[1] = bus->sprom.pa0b1;
-               lpphy->txpa[2] = bus->sprom.pa0b2;
-               maxpwr = bus->sprom.maxpwr_bg;
+               lpphy->tx_isolation_med_band = sprom->tri2g;
+               lpphy->bx_arch = sprom->bxa2g;
+               lpphy->rx_pwr_offset = sprom->rxpo2g;
+               lpphy->rssi_vf = sprom->rssismf2g;
+               lpphy->rssi_vc = sprom->rssismc2g;
+               lpphy->rssi_gs = sprom->rssisav2g;
+               lpphy->txpa[0] = sprom->pa0b0;
+               lpphy->txpa[1] = sprom->pa0b1;
+               lpphy->txpa[2] = sprom->pa0b2;
+               maxpwr = sprom->maxpwr_bg;
                lpphy->max_tx_pwr_med_band = maxpwr;
-               cckpo = bus->sprom.cck2gpo;
+               cckpo = sprom->cck2gpo;
                /*
                 * We don't read SPROM's opo as specs say. On rev8 SPROMs
                 * opo == ofdm2gpo and we don't know any SSB with LP-PHY
                 * and SPROM rev below 8.
                 */
-               B43_WARN_ON(bus->sprom.revision < 8);
-               ofdmpo = bus->sprom.ofdm2gpo;
+               B43_WARN_ON(sprom->revision < 8);
+               ofdmpo = sprom->ofdm2gpo;
                if (cckpo) {
                        for (i = 0; i < 4; i++) {
                                lpphy->tx_max_rate[i] =
                                        maxpwr - (ofdmpo & 0xF) * 2;
                                ofdmpo >>= 4;
                        }
-                       ofdmpo = bus->sprom.ofdm2gpo;
+                       ofdmpo = sprom->ofdm2gpo;
                        for (i = 4; i < 15; i++) {
                                lpphy->tx_max_rate[i] =
                                        maxpwr - (ofdmpo & 0xF) * 2;
@@ -131,39 +131,39 @@ static void lpphy_read_band_sprom(struct b43_wldev *dev)
                                lpphy->tx_max_rate[i] = maxpwr - ofdmpo;
                }
        } else { /* 5GHz */
-               lpphy->tx_isolation_low_band = bus->sprom.tri5gl;
-               lpphy->tx_isolation_med_band = bus->sprom.tri5g;
-               lpphy->tx_isolation_hi_band = bus->sprom.tri5gh;
-               lpphy->bx_arch = bus->sprom.bxa5g;
-               lpphy->rx_pwr_offset = bus->sprom.rxpo5g;
-               lpphy->rssi_vf = bus->sprom.rssismf5g;
-               lpphy->rssi_vc = bus->sprom.rssismc5g;
-               lpphy->rssi_gs = bus->sprom.rssisav5g;
-               lpphy->txpa[0] = bus->sprom.pa1b0;
-               lpphy->txpa[1] = bus->sprom.pa1b1;
-               lpphy->txpa[2] = bus->sprom.pa1b2;
-               lpphy->txpal[0] = bus->sprom.pa1lob0;
-               lpphy->txpal[1] = bus->sprom.pa1lob1;
-               lpphy->txpal[2] = bus->sprom.pa1lob2;
-               lpphy->txpah[0] = bus->sprom.pa1hib0;
-               lpphy->txpah[1] = bus->sprom.pa1hib1;
-               lpphy->txpah[2] = bus->sprom.pa1hib2;
-               maxpwr = bus->sprom.maxpwr_al;
-               ofdmpo = bus->sprom.ofdm5glpo;
+               lpphy->tx_isolation_low_band = sprom->tri5gl;
+               lpphy->tx_isolation_med_band = sprom->tri5g;
+               lpphy->tx_isolation_hi_band = sprom->tri5gh;
+               lpphy->bx_arch = sprom->bxa5g;
+               lpphy->rx_pwr_offset = sprom->rxpo5g;
+               lpphy->rssi_vf = sprom->rssismf5g;
+               lpphy->rssi_vc = sprom->rssismc5g;
+               lpphy->rssi_gs = sprom->rssisav5g;
+               lpphy->txpa[0] = sprom->pa1b0;
+               lpphy->txpa[1] = sprom->pa1b1;
+               lpphy->txpa[2] = sprom->pa1b2;
+               lpphy->txpal[0] = sprom->pa1lob0;
+               lpphy->txpal[1] = sprom->pa1lob1;
+               lpphy->txpal[2] = sprom->pa1lob2;
+               lpphy->txpah[0] = sprom->pa1hib0;
+               lpphy->txpah[1] = sprom->pa1hib1;
+               lpphy->txpah[2] = sprom->pa1hib2;
+               maxpwr = sprom->maxpwr_al;
+               ofdmpo = sprom->ofdm5glpo;
                lpphy->max_tx_pwr_low_band = maxpwr;
                for (i = 4; i < 12; i++) {
                        lpphy->tx_max_ratel[i] = maxpwr - (ofdmpo & 0xF) * 2;
                        ofdmpo >>= 4;
                }
-               maxpwr = bus->sprom.maxpwr_a;
-               ofdmpo = bus->sprom.ofdm5gpo;
+               maxpwr = sprom->maxpwr_a;
+               ofdmpo = sprom->ofdm5gpo;
                lpphy->max_tx_pwr_med_band = maxpwr;
                for (i = 4; i < 12; i++) {
                        lpphy->tx_max_rate[i] = maxpwr - (ofdmpo & 0xF) * 2;
                        ofdmpo >>= 4;
                }
-               maxpwr = bus->sprom.maxpwr_ah;
-               ofdmpo = bus->sprom.ofdm5ghpo;
+               maxpwr = sprom->maxpwr_ah;
+               ofdmpo = sprom->ofdm5ghpo;
                lpphy->max_tx_pwr_hi_band = maxpwr;
                for (i = 4; i < 12; i++) {
                        lpphy->tx_max_rateh[i] = maxpwr - (ofdmpo & 0xF) * 2;
@@ -214,7 +214,8 @@ static void lpphy_table_init(struct b43_wldev *dev)
 
 static void lpphy_baseband_rev0_1_init(struct b43_wldev *dev)
 {
-       struct ssb_bus *bus = dev->sdev->bus;
+       struct ssb_bus *bus = dev->dev->sdev->bus;
+       struct ssb_sprom *sprom = dev->dev->bus_sprom;
        struct b43_phy_lp *lpphy = dev->phy.lp;
        u16 tmp, tmp2;
 
@@ -242,9 +243,9 @@ static void lpphy_baseband_rev0_1_init(struct b43_wldev *dev)
        b43_phy_maskset(dev, B43_LPPHY_CRS_ED_THRESH, 0x00FF, 0xAD00);
        b43_phy_maskset(dev, B43_LPPHY_INPUT_PWRDB,
                        0xFF00, lpphy->rx_pwr_offset);
-       if ((bus->sprom.boardflags_lo & B43_BFL_FEM) &&
+       if ((sprom->boardflags_lo & B43_BFL_FEM) &&
           ((b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) ||
-          (bus->sprom.boardflags_hi & B43_BFH_PAREF))) {
+          (sprom->boardflags_hi & B43_BFH_PAREF))) {
                ssb_pmu_set_ldo_voltage(&bus->chipco, LDO_PAREF, 0x28);
                ssb_pmu_set_ldo_paref(&bus->chipco, true);
                if (dev->phy.rev == 0) {
@@ -260,7 +261,7 @@ static void lpphy_baseband_rev0_1_init(struct b43_wldev *dev)
        }
        tmp = lpphy->rssi_vf | lpphy->rssi_vc << 4 | 0xA000;
        b43_phy_write(dev, B43_LPPHY_AFE_RSSI_CTL_0, tmp);
-       if (bus->sprom.boardflags_hi & B43_BFH_RSSIINV)
+       if (sprom->boardflags_hi & B43_BFH_RSSIINV)
                b43_phy_maskset(dev, B43_LPPHY_AFE_RSSI_CTL_1, 0xF000, 0x0AAA);
        else
                b43_phy_maskset(dev, B43_LPPHY_AFE_RSSI_CTL_1, 0xF000, 0x02AA);
@@ -268,7 +269,7 @@ static void lpphy_baseband_rev0_1_init(struct b43_wldev *dev)
        b43_phy_maskset(dev, B43_LPPHY_RX_RADIO_CTL,
                        0xFFF9, (lpphy->bx_arch << 1));
        if (dev->phy.rev == 1 &&
-          (bus->sprom.boardflags_hi & B43_BFH_FEM_BT)) {
+          (sprom->boardflags_hi & B43_BFH_FEM_BT)) {
                b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_1, 0xFFC0, 0x000A);
                b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_1, 0x3F00, 0x0900);
                b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_2, 0xFFC0, 0x000A);
@@ -286,8 +287,8 @@ static void lpphy_baseband_rev0_1_init(struct b43_wldev *dev)
                b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_8, 0xFFC0, 0x000A);
                b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_8, 0xC0FF, 0x0B00);
        } else if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ ||
-                 (bus->boardinfo.type == 0x048A) || ((dev->phy.rev == 0) &&
-                 (bus->sprom.boardflags_lo & B43_BFL_FEM))) {
+                 (dev->dev->board_type == 0x048A) || ((dev->phy.rev == 0) &&
+                 (sprom->boardflags_lo & B43_BFL_FEM))) {
                b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_1, 0xFFC0, 0x0001);
                b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_1, 0xC0FF, 0x0400);
                b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_2, 0xFFC0, 0x0001);
@@ -297,7 +298,7 @@ static void lpphy_baseband_rev0_1_init(struct b43_wldev *dev)
                b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_4, 0xFFC0, 0x0002);
                b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_4, 0xC0FF, 0x0A00);
        } else if (dev->phy.rev == 1 ||
-                 (bus->sprom.boardflags_lo & B43_BFL_FEM)) {
+                 (sprom->boardflags_lo & B43_BFL_FEM)) {
                b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_1, 0xFFC0, 0x0004);
                b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_1, 0xC0FF, 0x0800);
                b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_2, 0xFFC0, 0x0004);
@@ -316,15 +317,15 @@ static void lpphy_baseband_rev0_1_init(struct b43_wldev *dev)
                b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_4, 0xFFC0, 0x0006);
                b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_4, 0xC0FF, 0x0700);
        }
-       if (dev->phy.rev == 1 && (bus->sprom.boardflags_hi & B43_BFH_PAREF)) {
+       if (dev->phy.rev == 1 && (sprom->boardflags_hi & B43_BFH_PAREF)) {
                b43_phy_copy(dev, B43_LPPHY_TR_LOOKUP_5, B43_LPPHY_TR_LOOKUP_1);
                b43_phy_copy(dev, B43_LPPHY_TR_LOOKUP_6, B43_LPPHY_TR_LOOKUP_2);
                b43_phy_copy(dev, B43_LPPHY_TR_LOOKUP_7, B43_LPPHY_TR_LOOKUP_3);
                b43_phy_copy(dev, B43_LPPHY_TR_LOOKUP_8, B43_LPPHY_TR_LOOKUP_4);
        }
-       if ((bus->sprom.boardflags_hi & B43_BFH_FEM_BT) &&
-           (bus->chip_id == 0x5354) &&
-           (bus->chip_package == SSB_CHIPPACK_BCM4712S)) {
+       if ((sprom->boardflags_hi & B43_BFH_FEM_BT) &&
+           (dev->dev->chip_id == 0x5354) &&
+           (dev->dev->chip_pkg == SSB_CHIPPACK_BCM4712S)) {
                b43_phy_set(dev, B43_LPPHY_CRSGAIN_CTL, 0x0006);
                b43_phy_write(dev, B43_LPPHY_GPIO_SELECT, 0x0005);
                b43_phy_write(dev, B43_LPPHY_GPIO_OUTEN, 0xFFFF);
@@ -412,7 +413,6 @@ static void lpphy_restore_dig_flt_state(struct b43_wldev *dev)
 
 static void lpphy_baseband_rev2plus_init(struct b43_wldev *dev)
 {
-       struct ssb_bus *bus = dev->sdev->bus;
        struct b43_phy_lp *lpphy = dev->phy.lp;
 
        b43_phy_write(dev, B43_LPPHY_AFE_DAC_CTL, 0x50);
@@ -432,7 +432,7 @@ static void lpphy_baseband_rev2plus_init(struct b43_wldev *dev)
        b43_phy_mask(dev, B43_LPPHY_CRSGAIN_CTL, ~0x4000);
        b43_phy_mask(dev, B43_LPPHY_CRSGAIN_CTL, ~0x2000);
        b43_phy_set(dev, B43_PHY_OFDM(0x10A), 0x1);
-       if (bus->boardinfo.rev >= 0x18) {
+       if (dev->dev->board_rev >= 0x18) {
                b43_lptab_write(dev, B43_LPTAB32(17, 65), 0xEC);
                b43_phy_maskset(dev, B43_PHY_OFDM(0x10A), 0xFF01, 0x14);
        } else {
@@ -449,7 +449,7 @@ static void lpphy_baseband_rev2plus_init(struct b43_wldev *dev)
        b43_phy_maskset(dev, B43_LPPHY_CLIPCTRTHRESH, 0xFC1F, 0xA0);
        b43_phy_maskset(dev, B43_LPPHY_GAINDIRECTMISMATCH, 0xE0FF, 0x300);
        b43_phy_maskset(dev, B43_LPPHY_HIGAINDB, 0x00FF, 0x2A00);
-       if ((bus->chip_id == 0x4325) && (bus->chip_rev == 0)) {
+       if ((dev->dev->chip_id == 0x4325) && (dev->dev->chip_rev == 0)) {
                b43_phy_maskset(dev, B43_LPPHY_LOWGAINDB, 0x00FF, 0x2100);
                b43_phy_maskset(dev, B43_LPPHY_VERYLOWGAINDB, 0xFF00, 0xA);
        } else {
@@ -467,7 +467,7 @@ static void lpphy_baseband_rev2plus_init(struct b43_wldev *dev)
        b43_phy_maskset(dev, B43_LPPHY_CLIPCTRTHRESH, 0xFFE0, 0x12);
        b43_phy_maskset(dev, B43_LPPHY_GAINMISMATCH, 0x0FFF, 0x9000);
 
-       if ((bus->chip_id == 0x4325) && (bus->chip_rev == 0)) {
+       if ((dev->dev->chip_id == 0x4325) && (dev->dev->chip_rev == 0)) {
                b43_lptab_write(dev, B43_LPTAB16(0x08, 0x14), 0);
                b43_lptab_write(dev, B43_LPTAB16(0x08, 0x12), 0x40);
        }
@@ -492,7 +492,7 @@ static void lpphy_baseband_rev2plus_init(struct b43_wldev *dev)
                      0x2000 | ((u16)lpphy->rssi_gs << 10) |
                      ((u16)lpphy->rssi_vc << 4) | lpphy->rssi_vf);
 
-       if ((bus->chip_id == 0x4325) && (bus->chip_rev == 0)) {
+       if ((dev->dev->chip_id == 0x4325) && (dev->dev->chip_rev == 0)) {
                b43_phy_set(dev, B43_LPPHY_AFE_ADC_CTL_0, 0x1C);
                b43_phy_maskset(dev, B43_LPPHY_AFE_CTL, 0x00FF, 0x8800);
                b43_phy_maskset(dev, B43_LPPHY_AFE_ADC_CTL_1, 0xFC3C, 0x0400);
@@ -519,7 +519,7 @@ struct b2062_freqdata {
 static void lpphy_2062_init(struct b43_wldev *dev)
 {
        struct b43_phy_lp *lpphy = dev->phy.lp;
-       struct ssb_bus *bus = dev->sdev->bus;
+       struct ssb_bus *bus = dev->dev->sdev->bus;
        u32 crystalfreq, tmp, ref;
        unsigned int i;
        const struct b2062_freqdata *fd = NULL;
@@ -697,7 +697,7 @@ static void lpphy_radio_init(struct b43_wldev *dev)
                lpphy_sync_stx(dev);
                b43_phy_write(dev, B43_PHY_OFDM(0xF0), 0x5F80);
                b43_phy_write(dev, B43_PHY_OFDM(0xF1), 0);
-               if (dev->sdev->bus->chip_id == 0x4325) {
+               if (dev->dev->chip_id == 0x4325) {
                        // TODO SSB PMU recalibration
                }
        }
@@ -1289,7 +1289,7 @@ finish:
 
 static void lpphy_rev2plus_rc_calib(struct b43_wldev *dev)
 {
-       struct ssb_bus *bus = dev->sdev->bus;
+       struct ssb_bus *bus = dev->dev->sdev->bus;
        u32 crystal_freq = bus->chipco.pmu.crystalfreq * 1000;
        u8 tmp = b43_radio_read(dev, B2063_RX_BB_SP8) & 0xFF;
        int i;
@@ -1840,7 +1840,6 @@ static void lpphy_papd_cal(struct b43_wldev *dev, struct lpphy_tx_gains gains,
 static void lpphy_papd_cal_txpwr(struct b43_wldev *dev)
 {
        struct b43_phy_lp *lpphy = dev->phy.lp;
-       struct ssb_bus *bus = dev->sdev->bus;
        struct lpphy_tx_gains gains, oldgains;
        int old_txpctl, old_afe_ovr, old_rf, old_bbmult;
 
@@ -1854,7 +1853,7 @@ static void lpphy_papd_cal_txpwr(struct b43_wldev *dev)
 
        lpphy_set_tx_power_control(dev, B43_LPPHY_TXPCTL_OFF);
 
-       if (bus->chip_id == 0x4325 && bus->chip_rev == 0)
+       if (dev->dev->chip_id == 0x4325 && dev->dev->chip_rev == 0)
                lpphy_papd_cal(dev, gains, 0, 1, 30);
        else
                lpphy_papd_cal(dev, gains, 0, 1, 65);
@@ -1870,7 +1869,6 @@ static int lpphy_rx_iq_cal(struct b43_wldev *dev, bool noise, bool tx,
                            bool rx, bool pa, struct lpphy_tx_gains *gains)
 {
        struct b43_phy_lp *lpphy = dev->phy.lp;
-       struct ssb_bus *bus = dev->sdev->bus;
        const struct lpphy_rx_iq_comp *iqcomp = NULL;
        struct lpphy_tx_gains nogains, oldgains;
        u16 tmp;
@@ -1879,7 +1877,7 @@ static int lpphy_rx_iq_cal(struct b43_wldev *dev, bool noise, bool tx,
        memset(&nogains, 0, sizeof(nogains));
        memset(&oldgains, 0, sizeof(oldgains));
 
-       if (bus->chip_id == 0x5354) {
+       if (dev->dev->chip_id == 0x5354) {
                for (i = 0; i < ARRAY_SIZE(lpphy_5354_iq_table); i++) {
                        if (lpphy_5354_iq_table[i].chan == lpphy->channel) {
                                iqcomp = &lpphy_5354_iq_table[i];
@@ -2408,11 +2406,9 @@ static const struct b206x_channel b2063_chantbl[] = {
 
 static void lpphy_b2062_reset_pll_bias(struct b43_wldev *dev)
 {
-       struct ssb_bus *bus = dev->sdev->bus;
-
        b43_radio_write(dev, B2062_S_RFPLL_CTL2, 0xFF);
        udelay(20);
-       if (bus->chip_id == 0x5354) {
+       if (dev->dev->chip_id == 0x5354) {
                b43_radio_write(dev, B2062_N_COMM1, 4);
                b43_radio_write(dev, B2062_S_RFPLL_CTL2, 4);
        } else {
@@ -2432,7 +2428,7 @@ static int lpphy_b2062_tune(struct b43_wldev *dev,
                            unsigned int channel)
 {
        struct b43_phy_lp *lpphy = dev->phy.lp;
-       struct ssb_bus *bus = dev->sdev->bus;
+       struct ssb_bus *bus = dev->dev->sdev->bus;
        const struct b206x_channel *chandata = NULL;
        u32 crystal_freq = bus->chipco.pmu.crystalfreq * 1000;
        u32 tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8, tmp9;
@@ -2522,7 +2518,7 @@ static void lpphy_b2063_vco_calib(struct b43_wldev *dev)
 static int lpphy_b2063_tune(struct b43_wldev *dev,
                            unsigned int channel)
 {
-       struct ssb_bus *bus = dev->sdev->bus;
+       struct ssb_bus *bus = dev->dev->sdev->bus;
 
        static const struct b206x_channel *chandata = NULL;
        u32 crystal_freq = bus->chipco.pmu.crystalfreq * 1000;
@@ -2670,6 +2666,11 @@ static int b43_lpphy_op_init(struct b43_wldev *dev)
 {
        int err;
 
+       if (dev->dev->bus_type != B43_BUS_SSB) {
+               b43err(dev->wl, "LP-PHY is supported only on SSB!\n");
+               return -EOPNOTSUPP;
+       }
+
        lpphy_read_band_sprom(dev); //FIXME should this be in prepare_structs?
        lpphy_baseband_init(dev);
        lpphy_radio_init(dev);
index 05960ddde24ee4fef9eb12801522eb95ea3e4825..ad14f3b428c5882ad0de963396ffdcaa7d001744 100644 (file)
@@ -299,7 +299,7 @@ static void b43_nphy_tx_power_ctrl(struct b43_wldev *dev, bool enable)
 static void b43_nphy_tx_power_fix(struct b43_wldev *dev)
 {
        struct b43_phy_n *nphy = dev->phy.n;
-       struct ssb_sprom *sprom = &(dev->sdev->bus->sprom);
+       struct ssb_sprom *sprom = dev->dev->bus_sprom;
 
        u8 txpi[2], bbmult, i;
        u16 tmp, radio_gain, dac_gain;
@@ -423,16 +423,15 @@ static void b43_radio_init2055_pre(struct b43_wldev *dev)
 static void b43_radio_init2055_post(struct b43_wldev *dev)
 {
        struct b43_phy_n *nphy = dev->phy.n;
-       struct ssb_sprom *sprom = &(dev->sdev->bus->sprom);
-       struct ssb_boardinfo *binfo = &(dev->sdev->bus->boardinfo);
+       struct ssb_sprom *sprom = dev->dev->bus_sprom;
        int i;
        u16 val;
        bool workaround = false;
 
        if (sprom->revision < 4)
-               workaround = (binfo->vendor != PCI_VENDOR_ID_BROADCOM &&
-                               binfo->type == 0x46D &&
-                               binfo->rev >= 0x41);
+               workaround = (dev->dev->board_vendor != PCI_VENDOR_ID_BROADCOM
+                             && dev->dev->board_type == 0x46D
+                             && dev->dev->board_rev >= 0x41);
        else
                workaround =
                        !(sprom->boardflags2_lo & B43_BFL2_RXBB_INT_REG_DIS);
@@ -983,7 +982,7 @@ static u16 b43_nphy_classifier(struct b43_wldev *dev, u16 mask, u16 val)
 {
        u16 tmp;
 
-       if (dev->sdev->id.revision == 16)
+       if (dev->dev->core_rev == 16)
                b43_mac_suspend(dev);
 
        tmp = b43_phy_read(dev, B43_NPHY_CLASSCTL);
@@ -993,7 +992,7 @@ static u16 b43_nphy_classifier(struct b43_wldev *dev, u16 mask, u16 val)
        tmp |= (val & mask);
        b43_phy_maskset(dev, B43_NPHY_CLASSCTL, 0xFFF8, tmp);
 
-       if (dev->sdev->id.revision == 16)
+       if (dev->dev->core_rev == 16)
                b43_mac_enable(dev);
 
        return tmp;
@@ -1168,7 +1167,7 @@ static void b43_nphy_adjust_lna_gain_table(struct b43_wldev *dev)
 static void b43_nphy_gain_ctrl_workarounds(struct b43_wldev *dev)
 {
        struct b43_phy_n *nphy = dev->phy.n;
-       struct ssb_sprom *sprom = &(dev->sdev->bus->sprom);
+       struct ssb_sprom *sprom = dev->dev->bus_sprom;
 
        /* PHY rev 0, 1, 2 */
        u8 i, j;
@@ -1373,7 +1372,7 @@ static void b43_nphy_gain_ctrl_workarounds(struct b43_wldev *dev)
 /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/Workarounds */
 static void b43_nphy_workarounds(struct b43_wldev *dev)
 {
-       struct ssb_bus *bus = dev->sdev->bus;
+       struct ssb_sprom *sprom = dev->dev->bus_sprom;
        struct b43_phy *phy = &dev->phy;
        struct b43_phy_n *nphy = phy->n;
 
@@ -1443,9 +1442,9 @@ static void b43_nphy_workarounds(struct b43_wldev *dev)
 
                /* N PHY WAR TX Chain Update with hw_phytxchain as argument */
 
-               if ((bus->sprom.boardflags2_lo & B43_BFL2_APLL_WAR &&
+               if ((sprom->boardflags2_lo & B43_BFL2_APLL_WAR &&
                    b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) ||
-                   (bus->sprom.boardflags2_lo & B43_BFL2_GPLL_WAR &&
+                   (sprom->boardflags2_lo & B43_BFL2_GPLL_WAR &&
                    b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ))
                        tmp32 = 0x00088888;
                else
@@ -1503,8 +1502,8 @@ static void b43_nphy_workarounds(struct b43_wldev *dev)
                b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_LO2, 0x2D8);
                b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_UP2, 0x301);
 
-               if (bus->sprom.boardflags2_lo & 0x100 &&
-                   bus->boardinfo.type == 0x8B) {
+               if (sprom->boardflags2_lo & 0x100 &&
+                   dev->dev->board_type == 0x8B) {
                        delays1[0] = 0x1;
                        delays1[5] = 0x14;
                }
@@ -3586,7 +3585,7 @@ static void b43_nphy_set_rx_core_state(struct b43_wldev *dev, u8 mask)
  */
 int b43_phy_initn(struct b43_wldev *dev)
 {
-       struct ssb_bus *bus = dev->sdev->bus;
+       struct ssb_sprom *sprom = dev->dev->bus_sprom;
        struct b43_phy *phy = &dev->phy;
        struct b43_phy_n *nphy = phy->n;
        u8 tx_pwr_state;
@@ -3599,7 +3598,7 @@ int b43_phy_initn(struct b43_wldev *dev)
        bool do_cal = false;
 
        if ((dev->phy.rev >= 3) &&
-          (bus->sprom.boardflags_lo & B43_BFL_EXTLNA) &&
+          (sprom->boardflags_lo & B43_BFL_EXTLNA) &&
           (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)) {
                chipco_set32(&dev->sdev->bus->chipco, SSB_CHIPCO_CHIPCTL, 0x40);
        }
@@ -3639,9 +3638,9 @@ int b43_phy_initn(struct b43_wldev *dev)
        b43_phy_write(dev, B43_NPHY_AFESEQ_TX2RX_PUD_20M, 0x20);
        b43_phy_write(dev, B43_NPHY_AFESEQ_TX2RX_PUD_40M, 0x20);
 
-       if (bus->sprom.boardflags2_lo & 0x100 ||
-           (bus->boardinfo.vendor == PCI_VENDOR_ID_APPLE &&
-            bus->boardinfo.type == 0x8B))
+       if (sprom->boardflags2_lo & 0x100 ||
+           (dev->dev->board_vendor == PCI_VENDOR_ID_APPLE &&
+            dev->dev->board_type == 0x8B))
                b43_phy_write(dev, B43_NPHY_TXREALFD, 0xA0);
        else
                b43_phy_write(dev, B43_NPHY_TXREALFD, 0xB8);
index 72ab94df7569e79696e475470a33978c3c49c834..44da620d9cc28a9cb3f87aaf286b57d17278c88f 100644 (file)
@@ -111,7 +111,7 @@ static u16 index_to_pioqueue_base(struct b43_wldev *dev,
                B43_MMIO_PIO11_BASE5,
        };
 
-       if (dev->sdev->id.revision >= 11) {
+       if (dev->dev->core_rev >= 11) {
                B43_WARN_ON(index >= ARRAY_SIZE(bases_rev11));
                return bases_rev11[index];
        }
@@ -121,14 +121,14 @@ static u16 index_to_pioqueue_base(struct b43_wldev *dev,
 
 static u16 pio_txqueue_offset(struct b43_wldev *dev)
 {
-       if (dev->sdev->id.revision >= 11)
+       if (dev->dev->core_rev >= 11)
                return 0x18;
        return 0;
 }
 
 static u16 pio_rxqueue_offset(struct b43_wldev *dev)
 {
-       if (dev->sdev->id.revision >= 11)
+       if (dev->dev->core_rev >= 11)
                return 0x38;
        return 8;
 }
@@ -144,7 +144,7 @@ static struct b43_pio_txqueue *b43_setup_pioqueue_tx(struct b43_wldev *dev,
        if (!q)
                return NULL;
        q->dev = dev;
-       q->rev = dev->sdev->id.revision;
+       q->rev = dev->dev->core_rev;
        q->mmio_base = index_to_pioqueue_base(dev, index) +
                       pio_txqueue_offset(dev);
        q->index = index;
@@ -178,7 +178,7 @@ static struct b43_pio_rxqueue *b43_setup_pioqueue_rx(struct b43_wldev *dev,
        if (!q)
                return NULL;
        q->dev = dev;
-       q->rev = dev->sdev->id.revision;
+       q->rev = dev->dev->core_rev;
        q->mmio_base = index_to_pioqueue_base(dev, index) +
                       pio_rxqueue_offset(dev);
 
index a617efe38289d1157ccccc78fca85dda73b52e5a..59c3afe047af6a1052ea19d3668544769b894194 100644 (file)
@@ -37,17 +37,16 @@ void b43_rfkill_poll(struct ieee80211_hw *hw)
 {
        struct b43_wl *wl = hw_to_b43_wl(hw);
        struct b43_wldev *dev = wl->current_dev;
-       struct ssb_bus *bus = dev->sdev->bus;
        bool enabled;
        bool brought_up = false;
 
        mutex_lock(&wl->mutex);
        if (unlikely(b43_status(dev) < B43_STAT_INITIALIZED)) {
-               if (ssb_bus_powerup(bus, 0)) {
+               if (b43_bus_powerup(dev, 0)) {
                        mutex_unlock(&wl->mutex);
                        return;
                }
-               ssb_device_enable(dev->sdev, 0);
+               b43_device_enable(dev, 0);
                brought_up = true;
        }
 
@@ -63,8 +62,8 @@ void b43_rfkill_poll(struct ieee80211_hw *hw)
        }
 
        if (brought_up) {
-               ssb_device_disable(dev->sdev, 0);
-               ssb_bus_may_powerdown(bus);
+               b43_device_disable(dev, 0);
+               b43_bus_may_powerdown(dev);
        }
 
        mutex_unlock(&wl->mutex);
index 808e25b79703a0151cab0bd46317523768ca160b..e6c733d37c94d29e127fb4dfa89fdd65273f5f92 100644 (file)
@@ -66,7 +66,7 @@ static void b43_sdio_interrupt_dispatcher(struct sdio_func *func)
 int b43_sdio_request_irq(struct b43_wldev *dev,
                         void (*handler)(struct b43_wldev *dev))
 {
-       struct ssb_bus *bus = dev->sdev->bus;
+       struct ssb_bus *bus = dev->dev->sdev->bus;
        struct sdio_func *func = bus->host_sdio;
        struct b43_sdio *sdio = sdio_get_drvdata(func);
        int err;
@@ -82,7 +82,7 @@ int b43_sdio_request_irq(struct b43_wldev *dev,
 
 void b43_sdio_free_irq(struct b43_wldev *dev)
 {
-       struct ssb_bus *bus = dev->sdev->bus;
+       struct ssb_bus *bus = dev->dev->sdev->bus;
        struct sdio_func *func = bus->host_sdio;
        struct b43_sdio *sdio = sdio_get_drvdata(func);
 
index 57af619725c3e12c3716cae0e0fd7369ae8bcd8a..f1ae4e05a32cf3b77b356dbf2ea97b56b6e72c68 100644 (file)
@@ -140,7 +140,7 @@ static DEVICE_ATTR(interference, 0644,
 
 int b43_sysfs_register(struct b43_wldev *wldev)
 {
-       struct device *dev = wldev->sdev->dev;
+       struct device *dev = wldev->dev->dev;
 
        B43_WARN_ON(b43_status(wldev) != B43_STAT_INITIALIZED);
 
@@ -149,7 +149,7 @@ int b43_sysfs_register(struct b43_wldev *wldev)
 
 void b43_sysfs_unregister(struct b43_wldev *wldev)
 {
-       struct device *dev = wldev->sdev->dev;
+       struct device *dev = wldev->dev->dev;
 
        device_remove_file(dev, &dev_attr_interference);
 }
index 59df3c64af6339e69684a3f048622abac960472f..6748c5a196e9c6b4ac152d0949dd171891c32f4b 100644 (file)
@@ -2304,7 +2304,6 @@ void lpphy_rev0_1_table_init(struct b43_wldev *dev)
 
 void lpphy_rev2plus_table_init(struct b43_wldev *dev)
 {
-       struct ssb_bus *bus = dev->sdev->bus;
        int i;
 
        B43_WARN_ON(dev->phy.rev < 2);
@@ -2341,7 +2340,7 @@ void lpphy_rev2plus_table_init(struct b43_wldev *dev)
        b43_lptab_write_bulk(dev, B43_LPTAB32(10, 0),
                ARRAY_SIZE(lpphy_papd_mult_table), lpphy_papd_mult_table);
 
-       if ((bus->chip_id == 0x4325) && (bus->chip_rev == 0)) {
+       if ((dev->dev->chip_id == 0x4325) && (dev->dev->chip_rev == 0)) {
                b43_lptab_write_bulk(dev, B43_LPTAB32(13, 0),
                        ARRAY_SIZE(lpphy_a0_gain_idx_table), lpphy_a0_gain_idx_table);
                b43_lptab_write_bulk(dev, B43_LPTAB16(14, 0),
@@ -2416,12 +2415,12 @@ void lpphy_write_gain_table_bulk(struct b43_wldev *dev, int offset, int count,
 
 void lpphy_init_tx_gain_table(struct b43_wldev *dev)
 {
-       struct ssb_bus *bus = dev->sdev->bus;
+       struct ssb_sprom *sprom = dev->dev->bus_sprom;
 
        switch (dev->phy.rev) {
        case 0:
-               if ((bus->sprom.boardflags_hi & B43_BFH_NOPA) ||
-                   (bus->sprom.boardflags_lo & B43_BFL_HGPA))
+               if ((sprom->boardflags_hi & B43_BFH_NOPA) ||
+                   (sprom->boardflags_lo & B43_BFL_HGPA))
                        lpphy_write_gain_table_bulk(dev, 0, 128,
                                        lpphy_rev0_nopa_tx_gain_table);
                else if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)
@@ -2432,8 +2431,8 @@ void lpphy_init_tx_gain_table(struct b43_wldev *dev)
                                        lpphy_rev0_5ghz_tx_gain_table);
                break;
        case 1:
-               if ((bus->sprom.boardflags_hi & B43_BFH_NOPA) ||
-                   (bus->sprom.boardflags_lo & B43_BFL_HGPA))
+               if ((sprom->boardflags_hi & B43_BFH_NOPA) ||
+                   (sprom->boardflags_lo & B43_BFL_HGPA))
                        lpphy_write_gain_table_bulk(dev, 0, 128,
                                        lpphy_rev1_nopa_tx_gain_table);
                else if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)
@@ -2444,7 +2443,7 @@ void lpphy_init_tx_gain_table(struct b43_wldev *dev)
                                        lpphy_rev1_5ghz_tx_gain_table);
                break;
        default:
-               if (bus->sprom.boardflags_hi & B43_BFH_NOPA)
+               if (sprom->boardflags_hi & B43_BFH_NOPA)
                        lpphy_write_gain_table_bulk(dev, 0, 128,
                                        lpphy_rev2_nopa_tx_gain_table);
                else if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)
index 8f4db448ec3308a1e6f2ccad03a1277f59e6f610..5d00d0eaf2e7aee1d58bf83c4ad7669876e37397 100644 (file)
@@ -458,17 +458,15 @@ static void b43_wa_rssi_adc(struct b43_wldev *dev)
 
 static void b43_wa_boards_a(struct b43_wldev *dev)
 {
-       struct ssb_bus *bus = dev->sdev->bus;
-
-       if (bus->boardinfo.vendor == SSB_BOARDVENDOR_BCM &&
-           bus->boardinfo.type == SSB_BOARD_BU4306 &&
-           bus->boardinfo.rev < 0x30) {
+       if (dev->dev->board_vendor == SSB_BOARDVENDOR_BCM &&
+           dev->dev->board_type == SSB_BOARD_BU4306 &&
+           dev->dev->board_rev < 0x30) {
                b43_phy_write(dev, 0x0010, 0xE000);
                b43_phy_write(dev, 0x0013, 0x0140);
                b43_phy_write(dev, 0x0014, 0x0280);
        } else {
-               if (bus->boardinfo.type == SSB_BOARD_MP4318 &&
-                   bus->boardinfo.rev < 0x20) {
+               if (dev->dev->board_type == SSB_BOARD_MP4318 &&
+                   dev->dev->board_rev < 0x20) {
                        b43_phy_write(dev, 0x0013, 0x0210);
                        b43_phy_write(dev, 0x0014, 0x0840);
                } else {
@@ -486,19 +484,19 @@ static void b43_wa_boards_a(struct b43_wldev *dev)
 
 static void b43_wa_boards_g(struct b43_wldev *dev)
 {
-       struct ssb_bus *bus = dev->sdev->bus;
+       struct ssb_sprom *sprom = dev->dev->bus_sprom;
        struct b43_phy *phy = &dev->phy;
 
-       if (bus->boardinfo.vendor != SSB_BOARDVENDOR_BCM ||
-           bus->boardinfo.type != SSB_BOARD_BU4306 ||
-           bus->boardinfo.rev != 0x17) {
+       if (dev->dev->board_vendor != SSB_BOARDVENDOR_BCM ||
+           dev->dev->board_type != SSB_BOARD_BU4306 ||
+           dev->dev->board_rev != 0x17) {
                if (phy->rev < 2) {
                        b43_ofdmtab_write16(dev, B43_OFDMTAB_GAINX_R1, 1, 0x0002);
                        b43_ofdmtab_write16(dev, B43_OFDMTAB_GAINX_R1, 2, 0x0001);
                } else {
                        b43_ofdmtab_write16(dev, B43_OFDMTAB_GAINX, 1, 0x0002);
                        b43_ofdmtab_write16(dev, B43_OFDMTAB_GAINX, 2, 0x0001);
-                       if ((bus->sprom.boardflags_lo & B43_BFL_EXTLNA) &&
+                       if ((sprom->boardflags_lo & B43_BFL_EXTLNA) &&
                            (phy->rev >= 7)) {
                                b43_phy_mask(dev, B43_PHY_EXTG(0x11), 0xF7FF);
                                b43_ofdmtab_write16(dev, B43_OFDMTAB_GAINX, 0x0020, 0x0001);
@@ -510,7 +508,7 @@ static void b43_wa_boards_g(struct b43_wldev *dev)
                        }
                }
        }
-       if (bus->sprom.boardflags_lo & B43_BFL_FEM) {
+       if (sprom->boardflags_lo & B43_BFL_FEM) {
                b43_phy_write(dev, B43_PHY_GTABCTL, 0x3120);
                b43_phy_write(dev, B43_PHY_GTABDATA, 0xC480);
        }
index c8f99aebe01f6565a798ef67952bb7cc9c4722c7..488b898418a3afe649af7586e31644a758a2757a 100644 (file)
@@ -547,7 +547,7 @@ static s8 b43_rssi_postprocess(struct b43_wldev *dev,
                        else
                                tmp -= 3;
                } else {
-                       if (dev->sdev->bus->sprom.
+                       if (dev->dev->bus_sprom->
                            boardflags_lo & B43_BFL_RSSI) {
                                if (in_rssi > 63)
                                        in_rssi = 63;
index e03e01d0bc355bd5a72d282b62dd39526f0cbdad..c33934ad6cd2fbb80b3e1c60ba7bc24a60e305bc 100644 (file)
@@ -817,14 +817,13 @@ static void dmacontroller_cleanup(struct b43legacy_dmaring *ring)
 
 static void free_all_descbuffers(struct b43legacy_dmaring *ring)
 {
-       struct b43legacy_dmadesc_generic *desc;
        struct b43legacy_dmadesc_meta *meta;
        int i;
 
        if (!ring->used_slots)
                return;
        for (i = 0; i < ring->nr_slots; i++) {
-               desc = ring->ops->idx2desc(ring, i, &meta);
+               ring->ops->idx2desc(ring, i, &meta);
 
                if (!meta->skb) {
                        B43legacy_WARN_ON(!ring->tx);
@@ -1371,10 +1370,8 @@ int b43legacy_dma_tx(struct b43legacy_wldev *dev,
                     struct sk_buff *skb)
 {
        struct b43legacy_dmaring *ring;
-       struct ieee80211_hdr *hdr;
        int err = 0;
        unsigned long flags;
-       struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
 
        ring = priority_to_txring(dev, skb_get_queue_mapping(skb));
        spin_lock_irqsave(&ring->lock, flags);
@@ -1401,8 +1398,6 @@ int b43legacy_dma_tx(struct b43legacy_wldev *dev,
 
        /* dma_tx_fragment might reallocate the skb, so invalidate pointers pointing
         * into the skb data or cb now. */
-       hdr = NULL;
-       info = NULL;
        err = dma_tx_fragment(ring, &skb);
        if (unlikely(err == -ENOKEY)) {
                /* Drop this packet, as we don't have the encryption key
@@ -1435,7 +1430,6 @@ void b43legacy_dma_handle_txstatus(struct b43legacy_wldev *dev,
 {
        const struct b43legacy_dma_ops *ops;
        struct b43legacy_dmaring *ring;
-       struct b43legacy_dmadesc_generic *desc;
        struct b43legacy_dmadesc_meta *meta;
        int retry_limit;
        int slot;
@@ -1450,7 +1444,7 @@ void b43legacy_dma_handle_txstatus(struct b43legacy_wldev *dev,
        ops = ring->ops;
        while (1) {
                B43legacy_WARN_ON(!(slot >= 0 && slot < ring->nr_slots));
-               desc = ops->idx2desc(ring, slot, &meta);
+               ops->idx2desc(ring, slot, &meta);
 
                if (meta->skb)
                        unmap_descbuffer(ring, meta->dmaaddr,
index 60107b8e4c93688919ff21c2dcf9a5cfce0fb41a..d6db6c17da4f77544350d3de09af5cd5ed459ef9 100644 (file)
@@ -1564,10 +1564,10 @@ static int b43legacy_request_firmware(struct b43legacy_wldev *dev)
        struct b43legacy_firmware *fw = &dev->fw;
        const u8 rev = dev->dev->id.revision;
        const char *filename;
-       u32 tmshigh;
        int err;
 
-       tmshigh = ssb_read32(dev->dev, SSB_TMSHIGH);
+       /* do dummy read */
+       ssb_read32(dev->dev, SSB_TMSHIGH);
        if (!fw->ucode) {
                if (rev == 2)
                        filename = "ucode2";
@@ -2634,11 +2634,9 @@ static int b43legacy_op_dev_config(struct ieee80211_hw *hw,
        unsigned long flags;
        unsigned int new_phymode = 0xFFFF;
        int antenna_tx;
-       int antenna_rx;
        int err = 0;
 
        antenna_tx = B43legacy_ANTENNA_DEFAULT;
-       antenna_rx = B43legacy_ANTENNA_DEFAULT;
 
        mutex_lock(&wl->mutex);
        dev = wl->current_dev;
@@ -2775,14 +2773,12 @@ static void b43legacy_op_bss_info_changed(struct ieee80211_hw *hw,
 {
        struct b43legacy_wl *wl = hw_to_b43legacy_wl(hw);
        struct b43legacy_wldev *dev;
-       struct b43legacy_phy *phy;
        unsigned long flags;
 
        mutex_lock(&wl->mutex);
        B43legacy_WARN_ON(wl->vif != vif);
 
        dev = wl->current_dev;
-       phy = &dev->phy;
 
        /* Disable IRQs while reconfiguring the device.
         * This makes it possible to drop the spinlock throughout
index 3a95541708a6f2e244890c0e73da940534986185..6c174f38ca3c0e166f60e4df412e22e1dc63c906 100644 (file)
@@ -321,11 +321,9 @@ static int generate_txhdr_fw3(struct b43legacy_wldev *dev,
                struct ieee80211_hdr *hdr;
                int rts_rate;
                int rts_rate_fb;
-               int rts_rate_ofdm;
                int rts_rate_fb_ofdm;
 
                rts_rate = ieee80211_get_rts_cts_rate(dev->wl->hw, info)->hw_value;
-               rts_rate_ofdm = b43legacy_is_ofdm_rate(rts_rate);
                rts_rate_fb = b43legacy_calc_fallback_rate(rts_rate);
                rts_rate_fb_ofdm = b43legacy_is_ofdm_rate(rts_rate_fb);
                if (rts_rate_fb_ofdm)
index 24d149909ba346e4e02fb38e3db262cb5a5ba5e2..9b65153bdd018800a4d43a4d8184486bb7afbb3d 100644 (file)
@@ -2275,6 +2275,9 @@ iwl4965_rs_get_rate(void *priv_r, struct ieee80211_sta *sta, void *priv_sta,
        if (rate_control_send_low(sta, priv_sta, txrc))
                return;
 
+       if (!lq_sta)
+               return;
+
        rate_idx  = lq_sta->last_txrate_idx;
 
        if (lq_sta->last_rate_n_flags & RATE_MCS_HT_MSK) {
index f9db25bb35c338f0b7f503e192293e78937d60f6..3a022bcf615c612ae9b292913bf2aec718024f23 100644 (file)
@@ -496,7 +496,7 @@ static s32 iwl4965_get_tx_atten_grp(u16 channel)
            channel <= CALIB_IWL_TX_ATTEN_GR4_LCH)
                return CALIB_CH_GROUP_4;
 
-       return -1;
+       return -EINVAL;
 }
 
 static u32 iwl4965_get_sub_band(const struct iwl_priv *priv, u32 channel)
@@ -915,7 +915,7 @@ static int iwl4965_fill_txpower_tbl(struct iwl_priv *priv, u8 band, u16 channel,
        if (txatten_grp < 0) {
                IWL_ERR(priv, "Can't find txatten group for channel %d.\n",
                          channel);
-               return -EINVAL;
+               return txatten_grp;
        }
 
        IWL_DEBUG_TXPOWER(priv, "channel %d belongs to txatten group %d\n",
@@ -1185,8 +1185,6 @@ static int iwl4965_send_rxon_assoc(struct iwl_priv *priv,
 
        ret = iwl_legacy_send_cmd_pdu_async(priv, REPLY_RXON_ASSOC,
                                     sizeof(rxon_assoc), &rxon_assoc, NULL);
-       if (ret)
-               return ret;
 
        return ret;
 }
@@ -1237,7 +1235,7 @@ static int iwl4965_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *c
 
                memcpy(active_rxon, &ctx->staging, sizeof(*active_rxon));
                iwl_legacy_print_rx_config_cmd(priv, ctx);
-               return 0;
+               goto set_tx_power;
        }
 
        /* If we are currently associated and the new config requires
@@ -1317,6 +1315,7 @@ static int iwl4965_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *c
 
        iwl4965_init_sensitivity(priv);
 
+set_tx_power:
        /* If we issue a new RXON command which required a tune then we must
         * send a new TXPOWER command or we won't be able to Tx any frames */
        ret = iwl_legacy_set_tx_power(priv, priv->tx_power_next, true);
index cb346d1a9ffa6e5f581b5b9c9c0a52f6ffafed3a..5bf3f49b74abc73d196342538bb4c067523cd829 100644 (file)
@@ -316,7 +316,6 @@ static void iwl_legacy_init_band_reference(const struct iwl_priv *priv,
                break;
        default:
                BUG();
-               return;
        }
 }
 
index 61d4a11f566b4f9e9864f1109369eade4634c50a..7aa240e6ba1c57e13f5ec2c3979c0ef89b24c198 100644 (file)
@@ -174,7 +174,6 @@ static struct iwl_lib_ops iwl1000_lib = {
        .rx_handler_setup = iwlagn_rx_handler_setup,
        .setup_deferred_work = iwlagn_setup_deferred_work,
        .is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr,
-       .send_tx_power = iwlagn_send_tx_power,
        .update_chain_flags = iwl_update_chain_flags,
        .apm_ops = {
                .init = iwl_apm_init,
@@ -223,6 +222,7 @@ static struct iwl_base_params iwl1000_base_params = {
 static struct iwl_ht_params iwl1000_ht_params = {
        .ht_greenfield_support = true,
        .use_rts_for_aggregation = true, /* use rts/cts protection */
+       .smps_mode = IEEE80211_SMPS_STATIC,
 };
 
 #define IWL_DEVICE_1000                                                \
index 86feec86d13009c9b6266cd7bf102b8f3195af94..5484ab712da80c7145f1d5faf172c84635321306 100644 (file)
@@ -177,88 +177,13 @@ static int iwl2000_hw_set_hw_params(struct iwl_priv *priv)
        return 0;
 }
 
-static int iwl2030_hw_channel_switch(struct iwl_priv *priv,
-                                    struct ieee80211_channel_switch *ch_switch)
-{
-       /*
-        * MULTI-FIXME
-        * See iwl_mac_channel_switch.
-        */
-       struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
-       struct iwl6000_channel_switch_cmd cmd;
-       const struct iwl_channel_info *ch_info;
-       u32 switch_time_in_usec, ucode_switch_time;
-       u16 ch;
-       u32 tsf_low;
-       u8 switch_count;
-       u16 beacon_interval = le16_to_cpu(ctx->timing.beacon_interval);
-       struct ieee80211_vif *vif = ctx->vif;
-       struct iwl_host_cmd hcmd = {
-               .id = REPLY_CHANNEL_SWITCH,
-               .len = { sizeof(cmd), },
-               .flags = CMD_SYNC,
-               .data = { &cmd, },
-       };
-
-       cmd.band = priv->band == IEEE80211_BAND_2GHZ;
-       ch = ch_switch->channel->hw_value;
-       IWL_DEBUG_11H(priv, "channel switch from %u to %u\n",
-               ctx->active.channel, ch);
-       cmd.channel = cpu_to_le16(ch);
-       cmd.rxon_flags = ctx->staging.flags;
-       cmd.rxon_filter_flags = ctx->staging.filter_flags;
-       switch_count = ch_switch->count;
-       tsf_low = ch_switch->timestamp & 0x0ffffffff;
-       /*
-        * calculate the ucode channel switch time
-        * adding TSF as one of the factor for when to switch
-        */
-       if ((priv->ucode_beacon_time > tsf_low) && beacon_interval) {
-               if (switch_count > ((priv->ucode_beacon_time - tsf_low) /
-                   beacon_interval)) {
-                       switch_count -= (priv->ucode_beacon_time -
-                               tsf_low) / beacon_interval;
-               } else
-                       switch_count = 0;
-       }
-       if (switch_count <= 1)
-               cmd.switch_time = cpu_to_le32(priv->ucode_beacon_time);
-       else {
-               switch_time_in_usec =
-                       vif->bss_conf.beacon_int * switch_count * TIME_UNIT;
-               ucode_switch_time = iwl_usecs_to_beacons(priv,
-                                               switch_time_in_usec,
-                                               beacon_interval);
-               cmd.switch_time = iwl_add_beacon_time(priv,
-                                               priv->ucode_beacon_time,
-                                               ucode_switch_time,
-                                               beacon_interval);
-       }
-       IWL_DEBUG_11H(priv, "uCode time for the switch is 0x%x\n",
-                     cmd.switch_time);
-       ch_info = iwl_get_channel_info(priv, priv->band, ch);
-       if (ch_info)
-               cmd.expect_beacon = is_channel_radar(ch_info);
-       else {
-               IWL_ERR(priv, "invalid channel switch from %u to %u\n",
-                       ctx->active.channel, ch);
-               return -EFAULT;
-       }
-       priv->switch_rxon.channel = cmd.channel;
-       priv->switch_rxon.switch_in_progress = true;
-
-       return iwl_send_cmd_sync(priv, &hcmd);
-}
-
 static struct iwl_lib_ops iwl2000_lib = {
        .set_hw_params = iwl2000_hw_set_hw_params,
        .rx_handler_setup = iwlagn_rx_handler_setup,
        .setup_deferred_work = iwlagn_bt_setup_deferred_work,
        .cancel_deferred_work = iwlagn_bt_cancel_deferred_work,
        .is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr,
-       .send_tx_power = iwlagn_send_tx_power,
        .update_chain_flags = iwl_update_chain_flags,
-       .set_channel_switch = iwl2030_hw_channel_switch,
        .apm_ops = {
                .init = iwl_apm_init,
                .config = iwl2000_nic_config,
index a70b8cfafda195a3b92e1f46d2a7e617c3faba0f..4353a658de25db60822d48638f40189913befa6a 100644 (file)
@@ -331,8 +331,6 @@ static int iwl5000_hw_channel_switch(struct iwl_priv *priv,
                        ctx->active.channel, ch);
                return -EFAULT;
        }
-       priv->switch_rxon.channel = cmd.channel;
-       priv->switch_rxon.switch_in_progress = true;
 
        return iwl_send_cmd_sync(priv, &hcmd);
 }
@@ -342,7 +340,6 @@ static struct iwl_lib_ops iwl5000_lib = {
        .rx_handler_setup = iwlagn_rx_handler_setup,
        .setup_deferred_work = iwlagn_setup_deferred_work,
        .is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr,
-       .send_tx_power = iwlagn_send_tx_power,
        .update_chain_flags = iwl_update_chain_flags,
        .set_channel_switch = iwl5000_hw_channel_switch,
        .apm_ops = {
@@ -373,7 +370,6 @@ static struct iwl_lib_ops iwl5150_lib = {
        .rx_handler_setup = iwlagn_rx_handler_setup,
        .setup_deferred_work = iwlagn_setup_deferred_work,
        .is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr,
-       .send_tx_power = iwlagn_send_tx_power,
        .update_chain_flags = iwl_update_chain_flags,
        .set_channel_switch = iwl5000_hw_channel_switch,
        .apm_ops = {
@@ -425,7 +421,6 @@ static struct iwl_base_params iwl5000_base_params = {
 };
 static struct iwl_ht_params iwl5000_ht_params = {
        .ht_greenfield_support = true,
-       .use_rts_for_aggregation = true, /* use rts/cts protection */
 };
 
 #define IWL_DEVICE_5000                                                \
index fda6fe08cf91c10b875b9f738ca66d143fd2e2f4..6e5ce44784906e30b13ba318a71e8b1056cea569 100644 (file)
@@ -270,8 +270,6 @@ static int iwl6000_hw_channel_switch(struct iwl_priv *priv,
                        ctx->active.channel, ch);
                return -EFAULT;
        }
-       priv->switch_rxon.channel = cmd.channel;
-       priv->switch_rxon.switch_in_progress = true;
 
        return iwl_send_cmd_sync(priv, &hcmd);
 }
@@ -281,7 +279,6 @@ static struct iwl_lib_ops iwl6000_lib = {
        .rx_handler_setup = iwlagn_rx_handler_setup,
        .setup_deferred_work = iwlagn_setup_deferred_work,
        .is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr,
-       .send_tx_power = iwlagn_send_tx_power,
        .update_chain_flags = iwl_update_chain_flags,
        .set_channel_switch = iwl6000_hw_channel_switch,
        .apm_ops = {
@@ -314,7 +311,6 @@ static struct iwl_lib_ops iwl6030_lib = {
        .setup_deferred_work = iwlagn_bt_setup_deferred_work,
        .cancel_deferred_work = iwlagn_bt_cancel_deferred_work,
        .is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr,
-       .send_tx_power = iwlagn_send_tx_power,
        .update_chain_flags = iwl_update_chain_flags,
        .set_channel_switch = iwl6000_hw_channel_switch,
        .apm_ops = {
index b12c72d63ccb94fd0e2628667ed8b1bbb3b2d5fd..23eee0ca5b357760db96115412265a2610c2d78f 100644 (file)
@@ -163,17 +163,9 @@ static void iwlagn_tx_cmd_protection(struct iwl_priv *priv,
                                     __le16 fc, __le32 *tx_flags)
 {
        if (info->control.rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS ||
-           info->control.rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT) {
+           info->control.rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT ||
+           info->flags & IEEE80211_TX_CTL_AMPDU)
                *tx_flags |= TX_CMD_FLG_PROT_REQUIRE_MSK;
-               return;
-       }
-
-       if (priv->cfg->ht_params &&
-           priv->cfg->ht_params->use_rts_for_aggregation &&
-           info->flags & IEEE80211_TX_CTL_AMPDU) {
-               *tx_flags |= TX_CMD_FLG_PROT_REQUIRE_MSK;
-               return;
-       }
 }
 
 /* Calc max signal level (dBm) among 3 possible receivers */
@@ -310,7 +302,6 @@ static int iwlagn_set_pan_params(struct iwl_priv *priv)
 }
 
 struct iwl_hcmd_ops iwlagn_hcmd = {
-       .commit_rxon = iwlagn_commit_rxon,
        .set_rxon_chain = iwlagn_set_rxon_chain,
        .set_tx_ant = iwlagn_send_tx_ant_config,
        .send_bt_config = iwl_send_bt_config,
@@ -318,7 +309,6 @@ struct iwl_hcmd_ops iwlagn_hcmd = {
 };
 
 struct iwl_hcmd_ops iwlagn_bt_hcmd = {
-       .commit_rxon = iwlagn_commit_rxon,
        .set_rxon_chain = iwlagn_set_rxon_chain,
        .set_tx_ant = iwlagn_send_tx_ant_config,
        .send_bt_config = iwlagn_send_advance_bt_config,
@@ -332,5 +322,4 @@ struct iwl_hcmd_utils_ops iwlagn_hcmd_utils = {
        .tx_cmd_protection = iwlagn_tx_cmd_protection,
        .calc_rssi = iwlagn_calc_rssi,
        .request_scan = iwlagn_request_scan,
-       .post_scan = iwlagn_post_scan,
 };
index f803fb62f8bc0abee7a41d3d09ec3bdd35895cbe..677f73c4c1e3af52457a8c8650191d162f19c125 100644 (file)
@@ -408,9 +408,9 @@ static void iwlagn_rx_reply_tx(struct iwl_priv *priv,
        unsigned long flags;
 
        if ((index >= txq->q.n_bd) || (iwl_queue_used(&txq->q, index) == 0)) {
-               IWL_ERR(priv, "Read index for DMA queue txq_id (%d) index %d "
-                         "is out of range [0-%d] %d %d\n", txq_id,
-                         index, txq->q.n_bd, txq->q.write_ptr,
+               IWL_ERR(priv, "%s: Read index for DMA queue txq_id (%d) "
+                         "index %d is out of range [0-%d] %d %d\n", __func__,
+                         txq_id, index, txq->q.n_bd, txq->q.write_ptr,
                          txq->q.read_ptr);
                return;
        }
@@ -1797,6 +1797,7 @@ static void iwlagn_bt_traffic_change_work(struct work_struct *work)
                priv->cfg->ops->lib->update_chain_flags(priv);
 
        if (smps_request != -1) {
+               priv->current_ht_config.smps = smps_request;
                for_each_context(priv, ctx) {
                        if (ctx->vif && ctx->vif->type == NL80211_IFTYPE_STATION)
                                ieee80211_request_smps(ctx->vif, smps_request);
index 592b0cfcf717a7a9f76af9515ae77481dfda47bb..85e082830c1ebd80d464e360dc57eae32e52f912 100644 (file)
@@ -426,7 +426,7 @@ static int rs_tl_turn_on_agg_for_tid(struct iwl_priv *priv,
                        ieee80211_stop_tx_ba_session(sta, tid);
                }
        } else {
-               IWL_ERR(priv, "Aggregation not enabled for tid %d "
+               IWL_DEBUG_HT(priv, "Aggregation not enabled for tid %d "
                        "because load = %u\n", tid, load);
        }
        return ret;
index a95ad84c537752c7c2c9491cc29eb8531c841b38..a7c66c4e5f2a2953e3d98dbc0c6af0a9f8aa3e49 100644 (file)
@@ -81,6 +81,21 @@ static int iwlagn_disable_pan(struct iwl_priv *priv,
        return ret;
 }
 
+static int iwlagn_disconn_pan(struct iwl_priv *priv,
+                             struct iwl_rxon_context *ctx,
+                             struct iwl_rxon_cmd *send)
+{
+       __le32 old_filter = send->filter_flags;
+       int ret;
+
+       send->filter_flags &= ~RXON_FILTER_ASSOC_MSK;
+       ret = iwl_send_cmd_pdu(priv, ctx->rxon_cmd, sizeof(*send), send);
+
+       send->filter_flags = old_filter;
+
+       return ret;
+}
+
 static void iwlagn_update_qos(struct iwl_priv *priv,
                              struct iwl_rxon_context *ctx)
 {
@@ -163,9 +178,6 @@ static int iwlagn_send_rxon_assoc(struct iwl_priv *priv,
 
        ret = iwl_send_cmd_pdu_async(priv, ctx->rxon_assoc_cmd,
                                     sizeof(rxon_assoc), &rxon_assoc, NULL);
-       if (ret)
-               return ret;
-
        return ret;
 }
 
@@ -175,10 +187,21 @@ static int iwlagn_rxon_disconn(struct iwl_priv *priv,
        int ret;
        struct iwl_rxon_cmd *active = (void *)&ctx->active;
 
-       if (ctx->ctxid == IWL_RXON_CTX_BSS)
+       if (ctx->ctxid == IWL_RXON_CTX_BSS) {
                ret = iwlagn_disable_bss(priv, ctx, &ctx->staging);
-       else
+       } else {
                ret = iwlagn_disable_pan(priv, ctx, &ctx->staging);
+               if (ret)
+                       return ret;
+               if (ctx->vif) {
+                       ret = iwl_send_rxon_timing(priv, ctx);
+                       if (ret) {
+                               IWL_ERR(priv, "Failed to send timing (%d)!\n", ret);
+                               return ret;
+                       }
+                       ret = iwlagn_disconn_pan(priv, ctx, &ctx->staging);
+               }
+       }
        if (ret)
                return ret;
 
@@ -205,10 +228,12 @@ static int iwlagn_rxon_connect(struct iwl_priv *priv,
        struct iwl_rxon_cmd *active = (void *)&ctx->active;
 
        /* RXON timing must be before associated RXON */
-       ret = iwl_send_rxon_timing(priv, ctx);
-       if (ret) {
-               IWL_ERR(priv, "Failed to send timing (%d)!\n", ret);
-               return ret;
+       if (ctx->ctxid == IWL_RXON_CTX_BSS) {
+               ret = iwl_send_rxon_timing(priv, ctx);
+               if (ret) {
+                       IWL_ERR(priv, "Failed to send timing (%d)!\n", ret);
+                       return ret;
+               }
        }
        /* QoS info may be cleared by previous un-assoc RXON */
        iwlagn_update_qos(priv, ctx);
@@ -263,6 +288,12 @@ static int iwlagn_rxon_connect(struct iwl_priv *priv,
                IWL_ERR(priv, "Error sending TX power (%d)\n", ret);
                return ret;
        }
+
+       if ((ctx->vif && ctx->vif->type == NL80211_IFTYPE_STATION) &&
+           priv->cfg->ht_params->smps_mode)
+               ieee80211_request_smps(ctx->vif,
+                                      priv->cfg->ht_params->smps_mode);
+
        return 0;
 }
 
@@ -325,6 +356,14 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
                        return 0;
        }
 
+       /*
+        * force CTS-to-self frames protection if RTS-CTS is not preferred
+        * one aggregation protection method
+        */
+       if (!(priv->cfg->ht_params &&
+             priv->cfg->ht_params->use_rts_for_aggregation))
+               ctx->staging.flags |= RXON_FLG_SELF_CTS_EN;
+
        if ((ctx->vif && ctx->vif->bss_conf.use_short_slot) ||
            !(ctx->staging.flags & RXON_FLG_BAND_24G_MSK))
                ctx->staging.flags |= RXON_FLG_SHORT_SLOT_MSK;
@@ -342,10 +381,10 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
         * receive commit_rxon request
         * abort any previous channel switch if still in process
         */
-       if (priv->switch_rxon.switch_in_progress &&
-           (priv->switch_rxon.channel != ctx->staging.channel)) {
+       if (test_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status) &&
+           (priv->switch_channel != ctx->staging.channel)) {
                IWL_DEBUG_11H(priv, "abort channel switch on %d\n",
-                     le16_to_cpu(priv->switch_rxon.channel));
+                             le16_to_cpu(priv->switch_channel));
                iwl_chswitch_done(priv, false);
        }
 
@@ -362,13 +401,16 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
                }
 
                memcpy(active, &ctx->staging, sizeof(*active));
-               return 0;
-       }
+               /*
+                * We do not commit tx power settings while channel changing,
+                * do it now if after settings changed.
+                */
+               iwl_set_tx_power(priv, priv->tx_power_next, false);
 
-       if (priv->cfg->ops->hcmd->set_pan_params) {
-               ret = priv->cfg->ops->hcmd->set_pan_params(priv);
-               if (ret)
-                       return ret;
+               /* make sure we are in the right PS state */
+               iwl_power_update_mode(priv, true);
+
+               return 0;
        }
 
        iwl_set_rxon_hwcrypto(priv, ctx, !iwlagn_mod_params.sw_crypto);
@@ -392,6 +434,12 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
        if (ret)
                return ret;
 
+       if (priv->cfg->ops->hcmd->set_pan_params) {
+               ret = priv->cfg->ops->hcmd->set_pan_params(priv);
+               if (ret)
+                       return ret;
+       }
+
        if (new_assoc)
                return iwlagn_rxon_connect(priv, ctx);
 
@@ -756,6 +804,13 @@ void iwlagn_post_scan(struct iwl_priv *priv)
 {
        struct iwl_rxon_context *ctx;
 
+       /*
+        * We do not commit power settings while scan is pending,
+        * do it now if the settings changed.
+        */
+       iwl_power_set_mode(priv, &priv->power_data.sleep_cmd_next, false);
+       iwl_set_tx_power(priv, priv->tx_power_next, false);
+
        /*
         * Since setting the RXON may have been deferred while
         * performing the scan, fire one off if needed
index 4974cd7837cbecb92a40f6d757eaa42a75235024..8bd48f61a9f5d9f90e38f656dbcbe113d81bf90c 100644 (file)
@@ -1033,8 +1033,8 @@ int iwlagn_tx_agg_start(struct iwl_priv *priv, struct ieee80211_vif *vif,
        if (unlikely(tx_fifo < 0))
                return tx_fifo;
 
-       IWL_WARN(priv, "%s on ra = %pM tid = %d\n",
-                       __func__, sta->addr, tid);
+       IWL_DEBUG_HT(priv, "TX AGG request on ra = %pM tid = %d\n",
+                    sta->addr, tid);
 
        sta_id = iwl_sta_id(sta);
        if (sta_id == IWL_INVALID_STATION) {
@@ -1236,9 +1236,9 @@ int iwlagn_tx_queue_reclaim(struct iwl_priv *priv, int txq_id, int index)
        struct ieee80211_hdr *hdr;
 
        if ((index >= q->n_bd) || (iwl_queue_used(q, index) == 0)) {
-               IWL_ERR(priv, "Read index for DMA queue txq id (%d), index %d, "
-                         "is out of range [0-%d] %d %d.\n", txq_id,
-                         index, q->n_bd, q->write_ptr, q->read_ptr);
+               IWL_ERR(priv, "%s: Read index for DMA queue txq id (%d), "
+                         "index %d is out of range [0-%d] %d %d.\n", __func__,
+                         txq_id, index, q->n_bd, q->write_ptr, q->read_ptr);
                return 0;
        }
 
index a662adcb2adbba26ce06045d48e7977390999447..099c2795ec0b16125afe7c8919182c6a75177c3e 100644 (file)
@@ -97,7 +97,7 @@ void iwl_update_chain_flags(struct iwl_priv *priv)
                for_each_context(priv, ctx) {
                        priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx);
                        if (ctx->active.rx_chain != ctx->staging.rx_chain)
-                               iwlcore_commit_rxon(priv, ctx);
+                               iwlagn_commit_rxon(priv, ctx);
                }
        }
 }
@@ -274,7 +274,7 @@ static void iwl_bg_bt_full_concurrency(struct work_struct *work)
        for_each_context(priv, ctx) {
                if (priv->cfg->ops->hcmd->set_rxon_chain)
                        priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx);
-               iwlcore_commit_rxon(priv, ctx);
+               iwlagn_commit_rxon(priv, ctx);
        }
 
        priv->cfg->ops->hcmd->send_bt_config(priv);
@@ -2056,7 +2056,7 @@ int iwl_alive_start(struct iwl_priv *priv)
        set_bit(STATUS_READY, &priv->status);
 
        /* Configure the adapter for unassociated operation */
-       ret = iwlcore_commit_rxon(priv, ctx);
+       ret = iwlagn_commit_rxon(priv, ctx);
        if (ret)
                return ret;
 
@@ -2420,6 +2420,77 @@ unlock:
  *
  *****************************************************************************/
 
+static const struct ieee80211_iface_limit iwlagn_sta_ap_limits[] = {
+       {
+               .max = 1,
+               .types = BIT(NL80211_IFTYPE_STATION),
+       },
+       {
+               .max = 1,
+               .types = BIT(NL80211_IFTYPE_AP),
+       },
+};
+
+static const struct ieee80211_iface_limit iwlagn_2sta_limits[] = {
+       {
+               .max = 2,
+               .types = BIT(NL80211_IFTYPE_STATION),
+       },
+};
+
+static const struct ieee80211_iface_limit iwlagn_p2p_sta_go_limits[] = {
+       {
+               .max = 1,
+               .types = BIT(NL80211_IFTYPE_STATION),
+       },
+       {
+               .max = 1,
+               .types = BIT(NL80211_IFTYPE_P2P_GO) |
+                        BIT(NL80211_IFTYPE_AP),
+       },
+};
+
+static const struct ieee80211_iface_limit iwlagn_p2p_2sta_limits[] = {
+       {
+               .max = 2,
+               .types = BIT(NL80211_IFTYPE_STATION),
+       },
+       {
+               .max = 1,
+               .types = BIT(NL80211_IFTYPE_P2P_CLIENT),
+       },
+};
+
+static const struct ieee80211_iface_combination
+iwlagn_iface_combinations_dualmode[] = {
+       { .num_different_channels = 1,
+         .max_interfaces = 2,
+         .beacon_int_infra_match = true,
+         .limits = iwlagn_sta_ap_limits,
+         .n_limits = ARRAY_SIZE(iwlagn_sta_ap_limits),
+       },
+       { .num_different_channels = 1,
+         .max_interfaces = 2,
+         .limits = iwlagn_2sta_limits,
+         .n_limits = ARRAY_SIZE(iwlagn_2sta_limits),
+       },
+};
+
+static const struct ieee80211_iface_combination
+iwlagn_iface_combinations_p2p[] = {
+       { .num_different_channels = 1,
+         .max_interfaces = 2,
+         .beacon_int_infra_match = true,
+         .limits = iwlagn_p2p_sta_go_limits,
+         .n_limits = ARRAY_SIZE(iwlagn_p2p_sta_go_limits),
+       },
+       { .num_different_channels = 1,
+         .max_interfaces = 2,
+         .limits = iwlagn_p2p_2sta_limits,
+         .n_limits = ARRAY_SIZE(iwlagn_p2p_2sta_limits),
+       },
+};
+
 /*
  * Not a mac80211 entry point function, but it fits in with all the
  * other mac80211 functions grouped here.
@@ -2460,6 +2531,18 @@ static int iwl_mac_setup_register(struct iwl_priv *priv,
                hw->wiphy->interface_modes |= ctx->exclusive_interface_modes;
        }
 
+       BUILD_BUG_ON(NUM_IWL_RXON_CTX != 2);
+
+       if (hw->wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_CLIENT)) {
+               hw->wiphy->iface_combinations = iwlagn_iface_combinations_p2p;
+               hw->wiphy->n_iface_combinations =
+                       ARRAY_SIZE(iwlagn_iface_combinations_p2p);
+       } else if (hw->wiphy->interface_modes & BIT(NL80211_IFTYPE_AP)) {
+               hw->wiphy->iface_combinations = iwlagn_iface_combinations_dualmode;
+               hw->wiphy->n_iface_combinations =
+                       ARRAY_SIZE(iwlagn_iface_combinations_dualmode);
+       }
+
        hw->wiphy->max_remain_on_channel_duration = 1000;
 
        hw->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY |
@@ -2711,12 +2794,9 @@ static int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw,
                        ret = 0;
                if (priv->cfg->ht_params &&
                    priv->cfg->ht_params->use_rts_for_aggregation) {
-                       struct iwl_station_priv *sta_priv =
-                               (void *) sta->drv_priv;
                        /*
                         * switch off RTS/CTS if it was previously enabled
                         */
-
                        sta_priv->lq_sta.lq.general_params.flags &=
                                ~LINK_QUAL_FLAGS_SET_STA_TLC_RTS_MSK;
                        iwl_send_lq_cmd(priv, iwl_rxon_ctx_from_vif(vif),
@@ -2764,6 +2844,9 @@ static int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw,
 
                iwl_send_lq_cmd(priv, iwl_rxon_ctx_from_vif(vif),
                                &sta_priv->lq_sta.lq, CMD_ASYNC, false);
+
+               IWL_INFO(priv, "Tx aggregation enabled on ra = %pM tid = %d\n",
+                        sta->addr, tid);
                ret = 0;
                break;
        }
@@ -2833,7 +2916,6 @@ static void iwlagn_mac_channel_switch(struct ieee80211_hw *hw,
         */
        struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
        u16 ch;
-       unsigned long flags = 0;
 
        IWL_DEBUG_MAC80211(priv, "enter\n");
 
@@ -2843,73 +2925,73 @@ static void iwlagn_mac_channel_switch(struct ieee80211_hw *hw,
                goto out;
 
        if (test_bit(STATUS_EXIT_PENDING, &priv->status) ||
-           test_bit(STATUS_SCANNING, &priv->status))
+           test_bit(STATUS_SCANNING, &priv->status) ||
+           test_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status))
                goto out;
 
        if (!iwl_is_associated_ctx(ctx))
                goto out;
 
-       /* channel switch in progress */
-       if (priv->switch_rxon.switch_in_progress == true)
+       if (!priv->cfg->ops->lib->set_channel_switch)
                goto out;
 
-       if (priv->cfg->ops->lib->set_channel_switch) {
+       ch = channel->hw_value;
+       if (le16_to_cpu(ctx->active.channel) == ch)
+               goto out;
 
-               ch = channel->hw_value;
-               if (le16_to_cpu(ctx->active.channel) != ch) {
-                       ch_info = iwl_get_channel_info(priv,
-                                                      channel->band,
-                                                      ch);
-                       if (!is_channel_valid(ch_info)) {
-                               IWL_DEBUG_MAC80211(priv, "invalid channel\n");
-                               goto out;
-                       }
-                       spin_lock_irqsave(&priv->lock, flags);
-
-                       priv->current_ht_config.smps = conf->smps_mode;
-
-                       /* Configure HT40 channels */
-                       ctx->ht.enabled = conf_is_ht(conf);
-                       if (ctx->ht.enabled) {
-                               if (conf_is_ht40_minus(conf)) {
-                                       ctx->ht.extension_chan_offset =
-                                               IEEE80211_HT_PARAM_CHA_SEC_BELOW;
-                                       ctx->ht.is_40mhz = true;
-                               } else if (conf_is_ht40_plus(conf)) {
-                                       ctx->ht.extension_chan_offset =
-                                               IEEE80211_HT_PARAM_CHA_SEC_ABOVE;
-                                       ctx->ht.is_40mhz = true;
-                               } else {
-                                       ctx->ht.extension_chan_offset =
-                                               IEEE80211_HT_PARAM_CHA_SEC_NONE;
-                                       ctx->ht.is_40mhz = false;
-                               }
-                       } else
-                               ctx->ht.is_40mhz = false;
+       ch_info = iwl_get_channel_info(priv, channel->band, ch);
+       if (!is_channel_valid(ch_info)) {
+               IWL_DEBUG_MAC80211(priv, "invalid channel\n");
+               goto out;
+       }
 
-                       if ((le16_to_cpu(ctx->staging.channel) != ch))
-                               ctx->staging.flags = 0;
+       spin_lock_irq(&priv->lock);
 
-                       iwl_set_rxon_channel(priv, channel, ctx);
-                       iwl_set_rxon_ht(priv, ht_conf);
-                       iwl_set_flags_for_band(priv, ctx, channel->band,
-                                              ctx->vif);
-                       spin_unlock_irqrestore(&priv->lock, flags);
+       priv->current_ht_config.smps = conf->smps_mode;
 
-                       iwl_set_rate(priv);
-                       /*
-                        * at this point, staging_rxon has the
-                        * configuration for channel switch
-                        */
-                       if (priv->cfg->ops->lib->set_channel_switch(priv,
-                                                                   ch_switch))
-                               priv->switch_rxon.switch_in_progress = false;
+       /* Configure HT40 channels */
+       ctx->ht.enabled = conf_is_ht(conf);
+       if (ctx->ht.enabled) {
+               if (conf_is_ht40_minus(conf)) {
+                       ctx->ht.extension_chan_offset =
+                               IEEE80211_HT_PARAM_CHA_SEC_BELOW;
+                       ctx->ht.is_40mhz = true;
+               } else if (conf_is_ht40_plus(conf)) {
+                       ctx->ht.extension_chan_offset =
+                               IEEE80211_HT_PARAM_CHA_SEC_ABOVE;
+                       ctx->ht.is_40mhz = true;
+               } else {
+                       ctx->ht.extension_chan_offset =
+                               IEEE80211_HT_PARAM_CHA_SEC_NONE;
+                       ctx->ht.is_40mhz = false;
                }
+       } else
+               ctx->ht.is_40mhz = false;
+
+       if ((le16_to_cpu(ctx->staging.channel) != ch))
+               ctx->staging.flags = 0;
+
+       iwl_set_rxon_channel(priv, channel, ctx);
+       iwl_set_rxon_ht(priv, ht_conf);
+       iwl_set_flags_for_band(priv, ctx, channel->band, ctx->vif);
+
+       spin_unlock_irq(&priv->lock);
+
+       iwl_set_rate(priv);
+       /*
+        * at this point, staging_rxon has the
+        * configuration for channel switch
+        */
+       set_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status);
+       priv->switch_channel = cpu_to_le16(ch);
+       if (priv->cfg->ops->lib->set_channel_switch(priv, ch_switch)) {
+               clear_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status);
+               priv->switch_channel = 0;
+               ieee80211_chswitch_done(ctx->vif, false);
        }
+
 out:
        mutex_unlock(&priv->mutex);
-       if (!priv->switch_rxon.switch_in_progress)
-               ieee80211_chswitch_done(ctx->vif, false);
        IWL_DEBUG_MAC80211(priv, "leave\n");
 }
 
@@ -3018,7 +3100,7 @@ static void iwlagn_disable_roc(struct iwl_priv *priv)
 
        priv->_agn.hw_roc_channel = NULL;
 
-       iwlcore_commit_rxon(priv, ctx);
+       iwlagn_commit_rxon(priv, ctx);
 
        ctx->is_active = false;
 }
@@ -3061,7 +3143,7 @@ static int iwl_mac_remain_on_channel(struct ieee80211_hw *hw,
        priv->_agn.hw_roc_channel = channel;
        priv->_agn.hw_roc_chantype = channel_type;
        priv->_agn.hw_roc_duration = DIV_ROUND_UP(duration * 1000, 1024);
-       iwlcore_commit_rxon(priv, &priv->contexts[IWL_RXON_CTX_PAN]);
+       iwlagn_commit_rxon(priv, &priv->contexts[IWL_RXON_CTX_PAN]);
        queue_delayed_work(priv->workqueue, &priv->_agn.hw_roc_work,
                           msecs_to_jiffies(duration + 20));
 
@@ -3618,8 +3700,8 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
        destroy_workqueue(priv->workqueue);
        priv->workqueue = NULL;
        free_irq(priv->pci_dev->irq, priv);
-       iwl_free_isr_ict(priv);
  out_disable_msi:
+       iwl_free_isr_ict(priv);
        pci_disable_msi(priv->pci_dev);
        iwl_uninit_drv(priv);
  out_free_eeprom:
index 4653deada05b48b1383f1cda6b33c7477a1717d3..5416b12cd9311de7ad853eedbe2435f5269e3dd9 100644 (file)
@@ -843,12 +843,8 @@ void iwl_chswitch_done(struct iwl_priv *priv, bool is_success)
        if (test_bit(STATUS_EXIT_PENDING, &priv->status))
                return;
 
-       if (priv->switch_rxon.switch_in_progress) {
+       if (test_and_clear_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status))
                ieee80211_chswitch_done(ctx->vif, is_success);
-               mutex_lock(&priv->mutex);
-               priv->switch_rxon.switch_in_progress = false;
-               mutex_unlock(&priv->mutex);
-       }
 }
 
 #ifdef CONFIG_IWLWIFI_DEBUG
@@ -1131,9 +1127,6 @@ int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force)
        if (priv->tx_power_user_lmt == tx_power && !force)
                return 0;
 
-       if (!priv->cfg->ops->lib->send_tx_power)
-               return -EOPNOTSUPP;
-
        if (tx_power < IWLAGN_TX_POWER_TARGET_POWER_MIN) {
                IWL_WARN(priv,
                         "Requested user TXPOWER %d below lower limit %d.\n",
@@ -1167,7 +1160,7 @@ int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force)
        prev_tx_power = priv->tx_power_user_lmt;
        priv->tx_power_user_lmt = tx_power;
 
-       ret = priv->cfg->ops->lib->send_tx_power(priv);
+       ret = iwlagn_send_tx_power(priv);
 
        /* if fail to set tx_power, restore the orig. tx power */
        if (ret) {
@@ -1282,7 +1275,7 @@ static int iwl_set_mode(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
        if (priv->cfg->ops->hcmd->set_rxon_chain)
                priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx);
 
-       return iwlcore_commit_rxon(priv, ctx);
+       return iwlagn_commit_rxon(priv, ctx);
 }
 
 static int iwl_setup_interface(struct iwl_priv *priv,
index 3bb76f6ea41017448c5cc5ce99851c967d66dafe..05ea88aa76e32126ff3d7902e333007168f9ec7f 100644 (file)
@@ -90,7 +90,6 @@ struct iwl_cmd;
 #define IWL_CMD(x) case x: return #x
 
 struct iwl_hcmd_ops {
-       int (*commit_rxon)(struct iwl_priv *priv, struct iwl_rxon_context *ctx);
        void (*set_rxon_chain)(struct iwl_priv *priv,
                               struct iwl_rxon_context *ctx);
        int (*set_tx_ant)(struct iwl_priv *priv, u8 valid_tx_ant);
@@ -112,7 +111,6 @@ struct iwl_hcmd_utils_ops {
        int  (*calc_rssi)(struct iwl_priv *priv,
                          struct iwl_rx_phy_res *rx_resp);
        int (*request_scan)(struct iwl_priv *priv, struct ieee80211_vif *vif);
-       void (*post_scan)(struct iwl_priv *priv);
 };
 
 struct iwl_apm_ops {
@@ -141,7 +139,6 @@ struct iwl_lib_ops {
        struct iwl_apm_ops apm_ops;
 
        /* power */
-       int (*send_tx_power) (struct iwl_priv *priv);
        void (*update_chain_flags)(struct iwl_priv *priv);
 
        /* eeprom operations (as defined in iwl-eeprom.h) */
@@ -225,7 +222,7 @@ struct iwl_base_params {
  * @ampdu_factor: Maximum A-MPDU length factor
  * @ampdu_density: Minimum A-MPDU spacing
  * @bt_sco_disable: uCode should not response to BT in SCO/ESCO mode
-*/
+ */
 struct iwl_bt_params {
        bool advanced_bt_coexist;
        u8 bt_init_traffic_load;
@@ -238,10 +235,11 @@ struct iwl_bt_params {
 };
 /*
  * @use_rts_for_aggregation: use rts/cts protection for HT traffic
-*/
+ */
 struct iwl_ht_params {
        const bool ht_greenfield_support; /* if used set to true */
        bool use_rts_for_aggregation;
+       enum ieee80211_smps_mode smps_mode;
 };
 
 /**
@@ -560,6 +558,7 @@ void iwlcore_free_geos(struct iwl_priv *priv);
 #define STATUS_POWER_PMI       16
 #define STATUS_FW_ERROR                17
 #define STATUS_DEVICE_ENABLED  18
+#define STATUS_CHANNEL_SWITCH_PENDING 19
 
 
 static inline int iwl_is_ready(struct iwl_priv *priv)
@@ -612,11 +611,7 @@ void iwl_apm_stop(struct iwl_priv *priv);
 int iwl_apm_init(struct iwl_priv *priv);
 
 int iwl_send_rxon_timing(struct iwl_priv *priv, struct iwl_rxon_context *ctx);
-static inline int iwlcore_commit_rxon(struct iwl_priv *priv,
-                                     struct iwl_rxon_context *ctx)
-{
-       return priv->cfg->ops->hcmd->commit_rxon(priv, ctx);
-}
+
 static inline const struct ieee80211_supported_band *iwl_get_hw_mode(
                        struct iwl_priv *priv, enum ieee80211_band band)
 {
index 1f4797d9848d6e7242857f29a06fb4cb880dd4c7..7ad98d868954ef8da0678fbaa7c911154e31ff07 100644 (file)
@@ -982,17 +982,6 @@ struct traffic_stats {
 #endif
 };
 
-/*
- * iwl_switch_rxon: "channel switch" structure
- *
- * @ switch_in_progress: channel switch in progress
- * @ channel: new channel
- */
-struct iwl_switch_rxon {
-       bool switch_in_progress;
-       __le16 channel;
-};
-
 /*
  * schedule the timer to wake up every UCODE_TRACE_PERIOD milliseconds
  * to perform continuous uCode event logging operation if enabled
@@ -1288,7 +1277,7 @@ struct iwl_priv {
 
        struct iwl_rxon_context contexts[NUM_IWL_RXON_CTX];
 
-       struct iwl_switch_rxon switch_rxon;
+       __le16 switch_channel;
 
        struct {
                u32 error_event_table;
index 0053e9ea9021a433b98025701fcc1e9d703ea1f3..b774517aa9fa11dbe95c2f666ab88df0b915b1d9 100644 (file)
@@ -250,19 +250,19 @@ static void iwl_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
        struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
        struct iwl_rxon_cmd *rxon = (void *)&ctx->active;
 
-       if (priv->switch_rxon.switch_in_progress) {
-               if (!le32_to_cpu(csa->status) &&
-                   (csa->channel == priv->switch_rxon.channel)) {
-                       rxon->channel = csa->channel;
-                       ctx->staging.channel = csa->channel;
-                       IWL_DEBUG_11H(priv, "CSA notif: channel %d\n",
-                             le16_to_cpu(csa->channel));
-                       iwl_chswitch_done(priv, true);
-               } else {
-                       IWL_ERR(priv, "CSA notif (fail) : channel %d\n",
+       if (!test_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status))
+               return;
+
+       if (!le32_to_cpu(csa->status) && csa->channel == priv->switch_channel) {
+               rxon->channel = csa->channel;
+               ctx->staging.channel = csa->channel;
+               IWL_DEBUG_11H(priv, "CSA notif: channel %d\n",
                              le16_to_cpu(csa->channel));
-                       iwl_chswitch_done(priv, false);
-               }
+               iwl_chswitch_done(priv, true);
+       } else {
+               IWL_ERR(priv, "CSA notif (fail) : channel %d\n",
+                       le16_to_cpu(csa->channel));
+               iwl_chswitch_done(priv, false);
        }
 }
 
index d60d630cb93af7d8eadb7c8be243a562444a5693..438eecd87335b0d3ff1695a1f2d387e0983598e7 100644 (file)
@@ -36,6 +36,7 @@
 #include "iwl-sta.h"
 #include "iwl-io.h"
 #include "iwl-helpers.h"
+#include "iwl-agn.h"
 
 /* For active scan, listen ACTIVE_DWELL_TIME (msec) on each channel after
  * sending probe req.  This should be set long enough to hear probe responses
@@ -600,14 +601,7 @@ out_settings:
        if (!iwl_is_ready_rf(priv))
                goto out;
 
-       /*
-        * We do not commit power settings while scan is pending,
-        * do it now if the settings changed.
-        */
-       iwl_power_set_mode(priv, &priv->power_data.sleep_cmd_next, false);
-       iwl_set_tx_power(priv, priv->tx_power_next, false);
-
-       priv->cfg->ops->utils->post_scan(priv);
+       iwlagn_post_scan(priv);
 
 out:
        mutex_unlock(&priv->mutex);
index 686e176b5ebdeb80c992860b49e2e64150892ca0..1084fe0e8a867e94f8d23b73cbfe6c91d5d9afac 100644 (file)
@@ -753,9 +753,9 @@ static void iwl_hcmd_queue_reclaim(struct iwl_priv *priv, int txq_id, int idx)
        int nfreed = 0;
 
        if ((idx >= q->n_bd) || (iwl_queue_used(q, idx) == 0)) {
-               IWL_ERR(priv, "Read index for DMA queue txq id (%d), index %d, "
-                         "is out of range [0-%d] %d %d.\n", txq_id,
-                         idx, q->n_bd, q->write_ptr, q->read_ptr);
+               IWL_ERR(priv, "%s: Read index for DMA queue txq id (%d), "
+                         "index %d is out of range [0-%d] %d %d.\n", __func__,
+                         txq_id, idx, q->n_bd, q->write_ptr, q->read_ptr);
                return;
        }
 
index a7b5cb0c2753845a581543e2ccca7963993592b0..224e9853c480605400a129fdda30b8298ca2d2bf 100644 (file)
@@ -907,7 +907,7 @@ static void if_sdio_interrupt(struct sdio_func *func)
        card = sdio_get_drvdata(func);
 
        cause = sdio_readb(card->func, IF_SDIO_H_INT_STATUS, &ret);
-       if (ret)
+       if (ret || !cause)
                goto out;
 
        lbs_deb_sdio("interrupt: 0x%X\n", (unsigned)cause);
@@ -1008,10 +1008,6 @@ static int if_sdio_probe(struct sdio_func *func,
        if (ret)
                goto release;
 
-       ret = sdio_claim_irq(func, if_sdio_interrupt);
-       if (ret)
-               goto disable;
-
        /* For 1-bit transfers to the 8686 model, we need to enable the
         * interrupt flag in the CCCR register. Set the MMC_QUIRK_LENIENT_FN0
         * bit to allow access to non-vendor registers. */
@@ -1082,6 +1078,21 @@ static int if_sdio_probe(struct sdio_func *func,
        else
                card->rx_unit = 0;
 
+       /*
+        * Set up the interrupt handler late.
+        *
+        * If we set it up earlier, the (buggy) hardware generates a spurious
+        * interrupt, even before the interrupt has been enabled, with
+        * CCCR_INTx = 0.
+        *
+        * We register the interrupt handler late so that we can handle any
+        * spurious interrupts, and also to avoid generation of that known
+        * spurious interrupt in the first place.
+        */
+       ret = sdio_claim_irq(func, if_sdio_interrupt);
+       if (ret)
+               goto disable;
+
        /*
         * Enable interrupts now that everything is set up
         */
index 9d4a40ee16c4f5987bd1d08d766c87b7b35332e5..7e1fa967127739664a7b8c741cba5fb035617563 100644 (file)
@@ -1,6 +1,7 @@
 /*
  * mac80211_hwsim - software simulator of 802.11 radio(s) for mac80211
  * Copyright (c) 2008, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2011, Javier Lopez <jlopex@gmail.com>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
 #include <linux/rtnetlink.h>
 #include <linux/etherdevice.h>
 #include <linux/debugfs.h>
+#include <net/genetlink.h>
+#include "mac80211_hwsim.h"
+
+#define WARN_QUEUE 100
+#define MAX_QUEUE 200
 
 MODULE_AUTHOR("Jouni Malinen");
 MODULE_DESCRIPTION("Software simulator of 802.11 radio(s) for mac80211");
 MODULE_LICENSE("GPL");
 
+int wmediumd_pid;
 static int radios = 2;
 module_param(radios, int, 0444);
 MODULE_PARM_DESC(radios, "Number of simulated radios");
@@ -302,6 +309,7 @@ struct mac80211_hwsim_data {
        struct dentry *debugfs;
        struct dentry *debugfs_ps;
 
+       struct sk_buff_head pending;    /* packets pending */
        /*
         * Only radios in the same group can communicate together (the
         * channel has to match too). Each bit represents a group. A
@@ -322,6 +330,32 @@ struct hwsim_radiotap_hdr {
        __le16 rt_chbitmask;
 } __packed;
 
+/* MAC80211_HWSIM netlinf family */
+static struct genl_family hwsim_genl_family = {
+       .id = GENL_ID_GENERATE,
+       .hdrsize = 0,
+       .name = "MAC80211_HWSIM",
+       .version = 1,
+       .maxattr = HWSIM_ATTR_MAX,
+};
+
+/* MAC80211_HWSIM netlink policy */
+
+static struct nla_policy hwsim_genl_policy[HWSIM_ATTR_MAX + 1] = {
+       [HWSIM_ATTR_ADDR_RECEIVER] = { .type = NLA_UNSPEC,
+                                      .len = 6*sizeof(u8) },
+       [HWSIM_ATTR_ADDR_TRANSMITTER] = { .type = NLA_UNSPEC,
+                                         .len = 6*sizeof(u8) },
+       [HWSIM_ATTR_FRAME] = { .type = NLA_BINARY,
+                              .len = IEEE80211_MAX_DATA_LEN },
+       [HWSIM_ATTR_FLAGS] = { .type = NLA_U32 },
+       [HWSIM_ATTR_RX_RATE] = { .type = NLA_U32 },
+       [HWSIM_ATTR_SIGNAL] = { .type = NLA_U32 },
+       [HWSIM_ATTR_TX_INFO] = { .type = NLA_UNSPEC,
+                                .len = IEEE80211_TX_MAX_RATES*sizeof(
+                                       struct hwsim_tx_rate)},
+       [HWSIM_ATTR_COOKIE] = { .type = NLA_U64 },
+};
 
 static netdev_tx_t hwsim_mon_xmit(struct sk_buff *skb,
                                        struct net_device *dev)
@@ -478,9 +512,89 @@ static bool mac80211_hwsim_addr_match(struct mac80211_hwsim_data *data,
        return md.ret;
 }
 
+static void mac80211_hwsim_tx_frame_nl(struct ieee80211_hw *hw,
+                                      struct sk_buff *my_skb,
+                                      int dst_pid)
+{
+       struct sk_buff *skb;
+       struct mac80211_hwsim_data *data = hw->priv;
+       struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) my_skb->data;
+       struct ieee80211_tx_info *info = IEEE80211_SKB_CB(my_skb);
+       void *msg_head;
+       unsigned int hwsim_flags = 0;
+       int i;
+       struct hwsim_tx_rate tx_attempts[IEEE80211_TX_MAX_RATES];
+
+       if (data->idle) {
+               wiphy_debug(hw->wiphy, "Trying to TX when idle - reject\n");
+               dev_kfree_skb(my_skb);
+               return;
+       }
+
+       if (data->ps != PS_DISABLED)
+               hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_PM);
+       /* If the queue contains MAX_QUEUE skb's drop some */
+       if (skb_queue_len(&data->pending) >= MAX_QUEUE) {
+               /* Droping until WARN_QUEUE level */
+               while (skb_queue_len(&data->pending) >= WARN_QUEUE)
+                       skb_dequeue(&data->pending);
+       }
+
+       skb = genlmsg_new(NLMSG_GOODSIZE, GFP_ATOMIC);
+       if (skb == NULL)
+               goto nla_put_failure;
+
+       msg_head = genlmsg_put(skb, 0, 0, &hwsim_genl_family, 0,
+                              HWSIM_CMD_FRAME);
+       if (msg_head == NULL) {
+               printk(KERN_DEBUG "mac80211_hwsim: problem with msg_head\n");
+               goto nla_put_failure;
+       }
+
+       NLA_PUT(skb, HWSIM_ATTR_ADDR_TRANSMITTER,
+                    sizeof(struct mac_address), data->addresses[1].addr);
 
-static bool mac80211_hwsim_tx_frame(struct ieee80211_hw *hw,
-                                   struct sk_buff *skb)
+       /* We get the skb->data */
+       NLA_PUT(skb, HWSIM_ATTR_FRAME, my_skb->len, my_skb->data);
+
+       /* We get the flags for this transmission, and we translate them to
+          wmediumd flags  */
+
+       if (info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS)
+               hwsim_flags |= HWSIM_TX_CTL_REQ_TX_STATUS;
+
+       if (info->flags & IEEE80211_TX_CTL_NO_ACK)
+               hwsim_flags |= HWSIM_TX_CTL_NO_ACK;
+
+       NLA_PUT_U32(skb, HWSIM_ATTR_FLAGS, hwsim_flags);
+
+       /* We get the tx control (rate and retries) info*/
+
+       for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) {
+               tx_attempts[i].idx = info->status.rates[i].idx;
+               tx_attempts[i].count = info->status.rates[i].count;
+       }
+
+       NLA_PUT(skb, HWSIM_ATTR_TX_INFO,
+                    sizeof(struct hwsim_tx_rate)*IEEE80211_TX_MAX_RATES,
+                    tx_attempts);
+
+       /* We create a cookie to identify this skb */
+       NLA_PUT_U64(skb, HWSIM_ATTR_COOKIE, (unsigned long) my_skb);
+
+       genlmsg_end(skb, msg_head);
+       genlmsg_unicast(&init_net, skb, dst_pid);
+
+       /* Enqueue the packet */
+       skb_queue_tail(&data->pending, my_skb);
+       return;
+
+nla_put_failure:
+       printk(KERN_DEBUG "mac80211_hwsim: error occured in %s\n", __func__);
+}
+
+static bool mac80211_hwsim_tx_frame_no_nl(struct ieee80211_hw *hw,
+                                         struct sk_buff *skb)
 {
        struct mac80211_hwsim_data *data = hw->priv, *data2;
        bool ack = false;
@@ -540,11 +654,11 @@ static bool mac80211_hwsim_tx_frame(struct ieee80211_hw *hw,
        return ack;
 }
 
-
 static void mac80211_hwsim_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
 {
        bool ack;
        struct ieee80211_tx_info *txi;
+       int _pid;
 
        mac80211_hwsim_monitor_rx(hw, skb);
 
@@ -554,7 +668,15 @@ static void mac80211_hwsim_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
                return;
        }
 
-       ack = mac80211_hwsim_tx_frame(hw, skb);
+       /* wmediumd mode check */
+       _pid = wmediumd_pid;
+
+       if (_pid)
+               return mac80211_hwsim_tx_frame_nl(hw, skb, _pid);
+
+       /* NO wmediumd detected, perfect medium simulation */
+       ack = mac80211_hwsim_tx_frame_no_nl(hw, skb);
+
        if (ack && skb->len >= 16) {
                struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
                mac80211_hwsim_monitor_ack(hw, hdr->addr2);
@@ -635,6 +757,7 @@ static void mac80211_hwsim_beacon_tx(void *arg, u8 *mac,
        struct ieee80211_hw *hw = arg;
        struct sk_buff *skb;
        struct ieee80211_tx_info *info;
+       int _pid;
 
        hwsim_check_magic(vif);
 
@@ -649,7 +772,14 @@ static void mac80211_hwsim_beacon_tx(void *arg, u8 *mac,
        info = IEEE80211_SKB_CB(skb);
 
        mac80211_hwsim_monitor_rx(hw, skb);
-       mac80211_hwsim_tx_frame(hw, skb);
+
+       /* wmediumd mode check */
+       _pid = wmediumd_pid;
+
+       if (_pid)
+               return mac80211_hwsim_tx_frame_nl(hw, skb, _pid);
+
+       mac80211_hwsim_tx_frame_no_nl(hw, skb);
        dev_kfree_skb(skb);
 }
 
@@ -966,12 +1096,7 @@ static int mac80211_hwsim_ampdu_action(struct ieee80211_hw *hw,
 
 static void mac80211_hwsim_flush(struct ieee80211_hw *hw, bool drop)
 {
-       /*
-        * In this special case, there's nothing we need to
-        * do because hwsim does transmission synchronously.
-        * In the future, when it does transmissions via
-        * userspace, we may need to do something.
-        */
+       /* Not implemented, queues only on kernel side */
 }
 
 struct hw_scan_done {
@@ -1119,6 +1244,7 @@ static void hwsim_send_ps_poll(void *dat, u8 *mac, struct ieee80211_vif *vif)
        struct hwsim_vif_priv *vp = (void *)vif->drv_priv;
        struct sk_buff *skb;
        struct ieee80211_pspoll *pspoll;
+       int _pid;
 
        if (!vp->assoc)
                return;
@@ -1137,8 +1263,15 @@ static void hwsim_send_ps_poll(void *dat, u8 *mac, struct ieee80211_vif *vif)
        pspoll->aid = cpu_to_le16(0xc000 | vp->aid);
        memcpy(pspoll->bssid, vp->bssid, ETH_ALEN);
        memcpy(pspoll->ta, mac, ETH_ALEN);
-       if (!mac80211_hwsim_tx_frame(data->hw, skb))
-               printk(KERN_DEBUG "%s: PS-Poll frame not ack'ed\n", __func__);
+
+       /* wmediumd mode check */
+       _pid = wmediumd_pid;
+
+       if (_pid)
+               return mac80211_hwsim_tx_frame_nl(data->hw, skb, _pid);
+
+       if (!mac80211_hwsim_tx_frame_no_nl(data->hw, skb))
+               printk(KERN_DEBUG "%s: PS-poll frame not ack'ed\n", __func__);
        dev_kfree_skb(skb);
 }
 
@@ -1149,6 +1282,7 @@ static void hwsim_send_nullfunc(struct mac80211_hwsim_data *data, u8 *mac,
        struct hwsim_vif_priv *vp = (void *)vif->drv_priv;
        struct sk_buff *skb;
        struct ieee80211_hdr *hdr;
+       int _pid;
 
        if (!vp->assoc)
                return;
@@ -1168,7 +1302,14 @@ static void hwsim_send_nullfunc(struct mac80211_hwsim_data *data, u8 *mac,
        memcpy(hdr->addr1, vp->bssid, ETH_ALEN);
        memcpy(hdr->addr2, mac, ETH_ALEN);
        memcpy(hdr->addr3, vp->bssid, ETH_ALEN);
-       if (!mac80211_hwsim_tx_frame(data->hw, skb))
+
+       /* wmediumd mode check */
+       _pid = wmediumd_pid;
+
+       if (_pid)
+               return mac80211_hwsim_tx_frame_nl(data->hw, skb, _pid);
+
+       if (!mac80211_hwsim_tx_frame_no_nl(data->hw, skb))
                printk(KERN_DEBUG "%s: nullfunc frame not ack'ed\n", __func__);
        dev_kfree_skb(skb);
 }
@@ -1248,6 +1389,273 @@ DEFINE_SIMPLE_ATTRIBUTE(hwsim_fops_group,
                        hwsim_fops_group_read, hwsim_fops_group_write,
                        "%llx\n");
 
+struct mac80211_hwsim_data *get_hwsim_data_ref_from_addr(
+                            struct mac_address *addr)
+{
+       struct mac80211_hwsim_data *data;
+       bool _found = false;
+
+       spin_lock_bh(&hwsim_radio_lock);
+       list_for_each_entry(data, &hwsim_radios, list) {
+               if (memcmp(data->addresses[1].addr, addr,
+                         sizeof(struct mac_address)) == 0) {
+                       _found = true;
+                       break;
+               }
+       }
+       spin_unlock_bh(&hwsim_radio_lock);
+
+       if (!_found)
+               return NULL;
+
+       return data;
+}
+
+static int hwsim_tx_info_frame_received_nl(struct sk_buff *skb_2,
+                                          struct genl_info *info)
+{
+
+       struct ieee80211_hdr *hdr;
+       struct mac80211_hwsim_data *data2;
+       struct ieee80211_tx_info *txi;
+       struct hwsim_tx_rate *tx_attempts;
+       struct sk_buff __user *ret_skb;
+       struct sk_buff *skb, *tmp;
+       struct mac_address *src;
+       unsigned int hwsim_flags;
+
+       int i;
+       bool found = false;
+
+       if (!info->attrs[HWSIM_ATTR_ADDR_TRANSMITTER] ||
+          !info->attrs[HWSIM_ATTR_FLAGS] ||
+          !info->attrs[HWSIM_ATTR_COOKIE] ||
+          !info->attrs[HWSIM_ATTR_TX_INFO])
+               goto out;
+
+       src = (struct mac_address *)nla_data(
+                                  info->attrs[HWSIM_ATTR_ADDR_TRANSMITTER]);
+       hwsim_flags = nla_get_u32(info->attrs[HWSIM_ATTR_FLAGS]);
+
+       ret_skb = (struct sk_buff __user *)
+                 (unsigned long) nla_get_u64(info->attrs[HWSIM_ATTR_COOKIE]);
+
+       data2 = get_hwsim_data_ref_from_addr(src);
+
+       if (data2 == NULL)
+               goto out;
+
+       /* look for the skb matching the cookie passed back from user */
+       skb_queue_walk_safe(&data2->pending, skb, tmp) {
+               if (skb == ret_skb) {
+                       skb_unlink(skb, &data2->pending);
+                       found = true;
+                       break;
+               }
+       }
+
+       /* not found */
+       if (!found)
+               goto out;
+
+       /* Tx info received because the frame was broadcasted on user space,
+        so we get all the necessary info: tx attempts and skb control buff */
+
+       tx_attempts = (struct hwsim_tx_rate *)nla_data(
+                      info->attrs[HWSIM_ATTR_TX_INFO]);
+
+       /* now send back TX status */
+       txi = IEEE80211_SKB_CB(skb);
+
+       if (txi->control.vif)
+               hwsim_check_magic(txi->control.vif);
+       if (txi->control.sta)
+               hwsim_check_sta_magic(txi->control.sta);
+
+       ieee80211_tx_info_clear_status(txi);
+
+       for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) {
+               txi->status.rates[i].idx = tx_attempts[i].idx;
+               txi->status.rates[i].count = tx_attempts[i].count;
+               /*txi->status.rates[i].flags = 0;*/
+       }
+
+       txi->status.ack_signal = nla_get_u32(info->attrs[HWSIM_ATTR_SIGNAL]);
+
+       if (!(hwsim_flags & HWSIM_TX_CTL_NO_ACK) &&
+          (hwsim_flags & HWSIM_TX_STAT_ACK)) {
+               if (skb->len >= 16) {
+                       hdr = (struct ieee80211_hdr *) skb->data;
+                       mac80211_hwsim_monitor_ack(data2->hw, hdr->addr2);
+               }
+       }
+       ieee80211_tx_status_irqsafe(data2->hw, skb);
+       return 0;
+out:
+       return -EINVAL;
+
+}
+
+static int hwsim_cloned_frame_received_nl(struct sk_buff *skb_2,
+                                         struct genl_info *info)
+{
+
+       struct mac80211_hwsim_data  *data2;
+       struct ieee80211_rx_status rx_status;
+       struct mac_address *dst;
+       int frame_data_len;
+       char *frame_data;
+       struct sk_buff *skb = NULL;
+
+       if (!info->attrs[HWSIM_ATTR_ADDR_RECEIVER] ||
+          !info->attrs[HWSIM_ATTR_FRAME] ||
+          !info->attrs[HWSIM_ATTR_RX_RATE] ||
+          !info->attrs[HWSIM_ATTR_SIGNAL])
+               goto out;
+
+       dst = (struct mac_address *)nla_data(
+                                  info->attrs[HWSIM_ATTR_ADDR_RECEIVER]);
+
+       frame_data_len = nla_len(info->attrs[HWSIM_ATTR_FRAME]);
+       frame_data = (char *)nla_data(info->attrs[HWSIM_ATTR_FRAME]);
+
+       /* Allocate new skb here */
+       skb = alloc_skb(frame_data_len, GFP_KERNEL);
+       if (skb == NULL)
+               goto err;
+
+       if (frame_data_len <= IEEE80211_MAX_DATA_LEN) {
+               /* Copy the data */
+               memcpy(skb_put(skb, frame_data_len), frame_data,
+                      frame_data_len);
+       } else
+               goto err;
+
+       data2 = get_hwsim_data_ref_from_addr(dst);
+
+       if (data2 == NULL)
+               goto out;
+
+       /* check if radio is configured properly */
+
+       if (data2->idle || !data2->started || !data2->channel)
+               goto out;
+
+       /*A frame is received from user space*/
+       memset(&rx_status, 0, sizeof(rx_status));
+       rx_status.freq = data2->channel->center_freq;
+       rx_status.band = data2->channel->band;
+       rx_status.rate_idx = nla_get_u32(info->attrs[HWSIM_ATTR_RX_RATE]);
+       rx_status.signal = nla_get_u32(info->attrs[HWSIM_ATTR_SIGNAL]);
+
+       memcpy(IEEE80211_SKB_RXCB(skb), &rx_status, sizeof(rx_status));
+       ieee80211_rx_irqsafe(data2->hw, skb);
+
+       return 0;
+err:
+       printk(KERN_DEBUG "mac80211_hwsim: error occured in %s\n", __func__);
+       goto out;
+out:
+       dev_kfree_skb(skb);
+       return -EINVAL;
+}
+
+static int hwsim_register_received_nl(struct sk_buff *skb_2,
+                                     struct genl_info *info)
+{
+       if (info == NULL)
+               goto out;
+
+       wmediumd_pid = info->snd_pid;
+
+       printk(KERN_DEBUG "mac80211_hwsim: received a REGISTER, "
+       "switching to wmediumd mode with pid %d\n", info->snd_pid);
+
+       return 0;
+out:
+       printk(KERN_DEBUG "mac80211_hwsim: error occured in %s\n", __func__);
+       return -EINVAL;
+}
+
+/* Generic Netlink operations array */
+static struct genl_ops hwsim_ops[] = {
+       {
+               .cmd = HWSIM_CMD_REGISTER,
+               .policy = hwsim_genl_policy,
+               .doit = hwsim_register_received_nl,
+               .flags = GENL_ADMIN_PERM,
+       },
+       {
+               .cmd = HWSIM_CMD_FRAME,
+               .policy = hwsim_genl_policy,
+               .doit = hwsim_cloned_frame_received_nl,
+       },
+       {
+               .cmd = HWSIM_CMD_TX_INFO_FRAME,
+               .policy = hwsim_genl_policy,
+               .doit = hwsim_tx_info_frame_received_nl,
+       },
+};
+
+static int mac80211_hwsim_netlink_notify(struct notifier_block *nb,
+                                        unsigned long state,
+                                        void *_notify)
+{
+       struct netlink_notify *notify = _notify;
+
+       if (state != NETLINK_URELEASE)
+               return NOTIFY_DONE;
+
+       if (notify->pid == wmediumd_pid) {
+               printk(KERN_INFO "mac80211_hwsim: wmediumd released netlink"
+                      " socket, switching to perfect channel medium\n");
+               wmediumd_pid = 0;
+       }
+       return NOTIFY_DONE;
+
+}
+
+static struct notifier_block hwsim_netlink_notifier = {
+       .notifier_call = mac80211_hwsim_netlink_notify,
+};
+
+static int hwsim_init_netlink(void)
+{
+       int rc;
+       printk(KERN_INFO "mac80211_hwsim: initializing netlink\n");
+
+       wmediumd_pid = 0;
+
+       rc = genl_register_family_with_ops(&hwsim_genl_family,
+               hwsim_ops, ARRAY_SIZE(hwsim_ops));
+       if (rc)
+               goto failure;
+
+       rc = netlink_register_notifier(&hwsim_netlink_notifier);
+       if (rc)
+               goto failure;
+
+       return 0;
+
+failure:
+       printk(KERN_DEBUG "mac80211_hwsim: error occured in %s\n", __func__);
+       return -EINVAL;
+}
+
+static void hwsim_exit_netlink(void)
+{
+       int ret;
+
+       printk(KERN_INFO "mac80211_hwsim: closing netlink\n");
+       /* unregister the notifier */
+       netlink_unregister_notifier(&hwsim_netlink_notifier);
+       /* unregister the family */
+       ret = genl_unregister_family(&hwsim_genl_family);
+       if (ret)
+               printk(KERN_DEBUG "mac80211_hwsim: "
+                      "unregister family %i\n", ret);
+}
+
 static int __init init_mac80211_hwsim(void)
 {
        int i, err = 0;
@@ -1298,6 +1706,7 @@ static int __init init_mac80211_hwsim(void)
                        goto failed_drvdata;
                }
                data->dev->driver = &mac80211_hwsim_driver;
+               skb_queue_head_init(&data->pending);
 
                SET_IEEE80211_DEV(hw, data->dev);
                addr[3] = i >> 8;
@@ -1379,6 +1788,10 @@ static int __init init_mac80211_hwsim(void)
                data->group = 1;
                mutex_init(&data->mutex);
 
+               /* Enable frame retransmissions for lossy channels */
+               hw->max_rates = 4;
+               hw->max_rate_tries = 11;
+
                /* Work to be done prior to ieee80211_register_hw() */
                switch (regtest) {
                case HWSIM_REGTEST_DISABLED:
@@ -1515,12 +1928,29 @@ static int __init init_mac80211_hwsim(void)
        if (hwsim_mon == NULL)
                goto failed;
 
-       err = register_netdev(hwsim_mon);
+       rtnl_lock();
+
+       err = dev_alloc_name(hwsim_mon, hwsim_mon->name);
        if (err < 0)
                goto failed_mon;
 
+
+       err = register_netdevice(hwsim_mon);
+       if (err < 0)
+               goto failed_mon;
+
+       rtnl_unlock();
+
+       err = hwsim_init_netlink();
+       if (err < 0)
+               goto failed_nl;
+
        return 0;
 
+failed_nl:
+       printk(KERN_DEBUG "mac_80211_hwsim: failed initializing netlink\n");
+       return err;
+
 failed_mon:
        rtnl_unlock();
        free_netdev(hwsim_mon);
@@ -1541,6 +1971,8 @@ static void __exit exit_mac80211_hwsim(void)
 {
        printk(KERN_DEBUG "mac80211_hwsim: unregister radios\n");
 
+       hwsim_exit_netlink();
+
        mac80211_hwsim_free();
        unregister_netdev(hwsim_mon);
 }
diff --git a/drivers/net/wireless/mac80211_hwsim.h b/drivers/net/wireless/mac80211_hwsim.h
new file mode 100644 (file)
index 0000000..afaad5a
--- /dev/null
@@ -0,0 +1,133 @@
+/*
+ * mac80211_hwsim - software simulator of 802.11 radio(s) for mac80211
+ * Copyright (c) 2008, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2011, Javier Lopez <jlopex@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __MAC80211_HWSIM_H
+#define __MAC80211_HWSIM_H
+
+/**
+ * enum hwsim_tx_control_flags - flags to describe transmission info/status
+ *
+ * These flags are used to give the wmediumd extra information in order to
+ * modify its behavior for each frame
+ *
+ * @HWSIM_TX_CTL_REQ_TX_STATUS: require TX status callback for this frame.
+ * @HWSIM_TX_CTL_NO_ACK: tell the wmediumd not to wait for an ack
+ * @HWSIM_TX_STAT_ACK: Frame was acknowledged
+ *
+ */
+enum hwsim_tx_control_flags {
+       HWSIM_TX_CTL_REQ_TX_STATUS              = BIT(0),
+       HWSIM_TX_CTL_NO_ACK                     = BIT(1),
+       HWSIM_TX_STAT_ACK                       = BIT(2),
+};
+
+/**
+ * DOC: Frame transmission/registration support
+ *
+ * Frame transmission and registration support exists to allow userspace
+ * entities such as wmediumd to receive and process all broadcasted
+ * frames from a mac80211_hwsim radio device.
+ *
+ * This allow user space applications to decide if the frame should be
+ * dropped or not and implement a wireless medium simulator at user space.
+ *
+ * Registration is done by sending a register message to the driver and
+ * will be automatically unregistered if the user application doesn't
+ * responds to sent frames.
+ * Once registered the user application has to take responsibility of
+ * broadcasting the frames to all listening mac80211_hwsim radio
+ * interfaces.
+ *
+ * For more technical details, see the corresponding command descriptions
+ * below.
+ */
+
+/**
+ * enum hwsim_commands - supported hwsim commands
+ *
+ * @HWSIM_CMD_UNSPEC: unspecified command to catch errors
+ *
+ * @HWSIM_CMD_REGISTER: request to register and received all broadcasted
+ *     frames by any mac80211_hwsim radio device.
+ * @HWSIM_CMD_FRAME: send/receive a broadcasted frame from/to kernel/user
+ * space, uses:
+ *     %HWSIM_ATTR_ADDR_TRANSMITTER, %HWSIM_ATTR_ADDR_RECEIVER,
+ *     %HWSIM_ATTR_FRAME, %HWSIM_ATTR_FLAGS, %HWSIM_ATTR_RX_RATE,
+ *     %HWSIM_ATTR_SIGNAL, %HWSIM_ATTR_COOKIE
+ * @HWSIM_CMD_TX_INFO_FRAME: Transmission info report from user space to
+ * kernel, uses:
+ *     %HWSIM_ATTR_ADDR_TRANSMITTER, %HWSIM_ATTR_FLAGS,
+ *     %HWSIM_ATTR_TX_INFO, %HWSIM_ATTR_SIGNAL, %HWSIM_ATTR_COOKIE
+ * @__HWSIM_CMD_MAX: enum limit
+ */
+enum {
+       HWSIM_CMD_UNSPEC,
+       HWSIM_CMD_REGISTER,
+       HWSIM_CMD_FRAME,
+       HWSIM_CMD_TX_INFO_FRAME,
+       __HWSIM_CMD_MAX,
+};
+#define HWSIM_CMD_MAX (_HWSIM_CMD_MAX - 1)
+
+/**
+ * enum hwsim_attrs - hwsim netlink attributes
+ *
+ * @HWSIM_ATTR_UNSPEC: unspecified attribute to catch errors
+ *
+ * @HWSIM_ATTR_ADDR_RECEIVER: MAC address of the radio device that
+ *     the frame is broadcasted to
+ * @HWSIM_ATTR_ADDR_TRANSMITTER: MAC address of the radio device that
+ *     the frame was broadcasted from
+ * @HWSIM_ATTR_FRAME: Data array
+ * @HWSIM_ATTR_FLAGS: mac80211 transmission flags, used to process
+       properly the frame at user space
+ * @HWSIM_ATTR_RX_RATE: estimated rx rate index for this frame at user
+       space
+ * @HWSIM_ATTR_SIGNAL: estimated RX signal for this frame at user
+       space
+ * @HWSIM_ATTR_TX_INFO: ieee80211_tx_rate array
+ * @HWSIM_ATTR_COOKIE: sk_buff cookie to identify the frame
+ * @__HWSIM_ATTR_MAX: enum limit
+ */
+
+
+enum {
+       HWSIM_ATTR_UNSPEC,
+       HWSIM_ATTR_ADDR_RECEIVER,
+       HWSIM_ATTR_ADDR_TRANSMITTER,
+       HWSIM_ATTR_FRAME,
+       HWSIM_ATTR_FLAGS,
+       HWSIM_ATTR_RX_RATE,
+       HWSIM_ATTR_SIGNAL,
+       HWSIM_ATTR_TX_INFO,
+       HWSIM_ATTR_COOKIE,
+       __HWSIM_ATTR_MAX,
+};
+#define HWSIM_ATTR_MAX (__HWSIM_ATTR_MAX - 1)
+
+/**
+ * struct hwsim_tx_rate - rate selection/status
+ *
+ * @idx: rate index to attempt to send with
+ * @count: number of tries in this rate before going to the next rate
+ *
+ * A value of -1 for @idx indicates an invalid rate and, if used
+ * in an array of retry rates, that no more rates should be tried.
+ *
+ * When used for transmit status reporting, the driver should
+ * always report the rate and number of retries used.
+ *
+ */
+struct hwsim_tx_rate {
+       s8 idx;
+       u8 count;
+} __packed;
+
+#endif /* __MAC80211_HWSIM_H */
index f807447e4d993cf1fae0befdd13e57b4aa25f764..1a453a605b3f31e5d10bff47bed8176d280360a2 100644 (file)
@@ -164,12 +164,13 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv,
        struct mwifiex_tx_param tx_param;
        struct txpd *ptx_pd = NULL;
 
-       if (skb_queue_empty(&pra_list->skb_head)) {
+       skb_src = skb_peek(&pra_list->skb_head);
+       if (!skb_src) {
                spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock,
                                       ra_list_flags);
                return 0;
        }
-       skb_src = skb_peek(&pra_list->skb_head);
+
        tx_info_src = MWIFIEX_SKB_TXCB(skb_src);
        skb_aggr = dev_alloc_skb(adapter->tx_buf_size);
        if (!skb_aggr) {
@@ -184,17 +185,15 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv,
        tx_info_aggr->bss_index = tx_info_src->bss_index;
        skb_aggr->priority = skb_src->priority;
 
-       while (skb_src && ((skb_headroom(skb_aggr) + skb_src->len
-                                       + LLC_SNAP_LEN)
-                               <= adapter->tx_buf_size)) {
+       do {
+               /* Check if AMSDU can accommodate this MSDU */
+               if (skb_tailroom(skb_aggr) < (skb_src->len + LLC_SNAP_LEN))
+                       break;
 
-               if (!skb_queue_empty(&pra_list->skb_head))
-                       skb_src = skb_dequeue(&pra_list->skb_head);
-               else
-                       skb_src = NULL;
+               skb_src = skb_dequeue(&pra_list->skb_head);
 
-               if (skb_src)
-                       pra_list->total_pkts_size -= skb_src->len;
+               pra_list->total_pkts_size -= skb_src->len;
+               pra_list->total_pkts--;
 
                atomic_dec(&priv->wmm.tx_pkts_queued);
 
@@ -212,11 +211,15 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv,
                        return -1;
                }
 
-               if (!skb_queue_empty(&pra_list->skb_head))
-                       skb_src = skb_peek(&pra_list->skb_head);
-               else
-                       skb_src = NULL;
-       }
+               if (skb_tailroom(skb_aggr) < pad) {
+                       pad = 0;
+                       break;
+               }
+               skb_put(skb_aggr, pad);
+
+               skb_src = skb_peek(&pra_list->skb_head);
+
+       } while (skb_src);
 
        spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, ra_list_flags);
 
@@ -230,11 +233,19 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv,
 
        skb_push(skb_aggr, headroom);
 
-       tx_param.next_pkt_len = ((pra_list->total_pkts_size) ?
-                                (((pra_list->total_pkts_size) >
-                                  adapter->tx_buf_size) ? adapter->
-                                 tx_buf_size : pra_list->total_pkts_size +
-                                 LLC_SNAP_LEN + sizeof(struct txpd)) : 0);
+       /*
+        * Padding per MSDU will affect the length of next
+        * packet and hence the exact length of next packet
+        * is uncertain here.
+        *
+        * Also, aggregation of transmission buffer, while
+        * downloading the data to the card, wont gain much
+        * on the AMSDU packets as the AMSDU packets utilizes
+        * the transmission buffer space to the maximum
+        * (adapter->tx_buf_size).
+        */
+       tx_param.next_pkt_len = 0;
+
        ret = adapter->if_ops.host_to_card(adapter, MWIFIEX_TYPE_DATA,
                                             skb_aggr->data,
                                             skb_aggr->len, &tx_param);
@@ -258,6 +269,7 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv,
                skb_queue_tail(&pra_list->skb_head, skb_aggr);
 
                pra_list->total_pkts_size += skb_aggr->len;
+               pra_list->total_pkts++;
 
                atomic_inc(&priv->wmm.tx_pkts_queued);
 
index f0582259c93531640ce474a8344b3bc54d0eee49..4f43443036f46a3608cba97adf7ebb7d623c2844 100644 (file)
@@ -35,8 +35,6 @@ static struct mwifiex_bss_attr mwifiex_bss_sta[] = {
 
 static int drv_mode = DRV_MODE_STA;
 
-static char fw_name[32] = DEFAULT_FW_NAME;
-
 /* Supported drv_mode table */
 static struct mwifiex_drv_mode mwifiex_drv_mode_tbl[] = {
        {
@@ -384,20 +382,8 @@ static int mwifiex_init_hw_fw(struct mwifiex_adapter *adapter)
 
        memset(&fw, 0, sizeof(struct mwifiex_fw_image));
 
-       switch (adapter->revision_id) {
-       case SD8787_W0:
-       case SD8787_W1:
-               strcpy(fw_name, SD8787_W1_FW_NAME);
-               break;
-       case SD8787_A0:
-       case SD8787_A1:
-               strcpy(fw_name, SD8787_AX_FW_NAME);
-               break;
-       default:
-               break;
-       }
-
-       err = request_firmware(&adapter->firmware, fw_name, adapter->dev);
+       err = request_firmware(&adapter->firmware, adapter->fw_name,
+                              adapter->dev);
        if (err < 0) {
                dev_err(adapter->dev, "request_firmware() returned"
                                " error code %#x\n", err);
index 8316b3cd92cdf421975c96ffd9955cc62ae49483..57b183af72d796f7f38df47cb936d414147dc5e8 100644 (file)
@@ -48,15 +48,6 @@ enum {
 
 #define DRV_MODE_STA       0x1
 
-#define SD8787_W0   0x30
-#define SD8787_W1   0x31
-#define SD8787_A0   0x40
-#define SD8787_A1   0x41
-
-#define DEFAULT_FW_NAME "mrvl/sd8787_uapsta.bin"
-#define SD8787_W1_FW_NAME "mrvl/sd8787_uapsta_w1.bin"
-#define SD8787_AX_FW_NAME "mrvl/sd8787_uapsta.bin"
-
 struct mwifiex_drv_mode {
        u16 drv_mode;
        u16 intf_num;
@@ -190,6 +181,7 @@ struct mwifiex_ra_list_tbl {
        struct sk_buff_head skb_head;
        u8 ra[ETH_ALEN];
        u32 total_pkts_size;
+       u32 total_pkts;
        u32 is_11n_enabled;
 };
 
@@ -576,10 +568,10 @@ struct mwifiex_adapter {
        u8 priv_num;
        struct mwifiex_drv_mode *drv_mode;
        const struct firmware *firmware;
+       char fw_name[32];
        struct device *dev;
        bool surprise_removed;
        u32 fw_release_number;
-       u32 revision_id;
        u16 init_wait_q_woken;
        wait_queue_head_t init_wait_q;
        void *card;
index d425dbd91d19e80785c49c7a024f5b3a2c6cfcbb..4327b6d099c891b39ac4633a98a2a9f19a3febe0 100644 (file)
@@ -1531,6 +1531,7 @@ static int mwifiex_register_dev(struct mwifiex_adapter *adapter)
        sdio_set_drvdata(func, card);
 
        adapter->dev = &func->dev;
+       strcpy(adapter->fw_name, SD8787_DEFAULT_FW_NAME);
 
        return 0;
 
@@ -1552,7 +1553,6 @@ disable_func:
  *        the first interrupt got from bootloader
  *      - Disable host interrupt mask register
  *      - Get SDIO port
- *      - Get revision ID
  *      - Initialize SDIO variables in card
  *      - Allocate MP registers
  *      - Allocate MPA Tx and Rx buffers
@@ -1576,10 +1576,6 @@ static int mwifiex_init_sdio(struct mwifiex_adapter *adapter)
        /* Get SDIO ioport */
        mwifiex_init_sdio_ioport(adapter);
 
-       /* Get revision ID */
-#define REV_ID_REG     0x5c
-       mwifiex_read_reg(adapter, REV_ID_REG, &adapter->revision_id);
-
        /* Initialize SDIO variables in card */
        card->mp_rd_bitmap = 0;
        card->mp_wr_bitmap = 0;
@@ -1751,4 +1747,4 @@ MODULE_AUTHOR("Marvell International Ltd.");
 MODULE_DESCRIPTION("Marvell WiFi-Ex SDIO Driver version " SDIO_VERSION);
 MODULE_VERSION(SDIO_VERSION);
 MODULE_LICENSE("GPL v2");
-MODULE_FIRMWARE("sd8787.bin");
+MODULE_FIRMWARE("mrvl/sd8787_uapsta.bin");
index 4e97e90aa3994cacc80cadbd034caa581549011e..c925376fcaaeee8d2fad78e975f80dafae331608 100644 (file)
@@ -28,6 +28,8 @@
 
 #include "main.h"
 
+#define SD8787_DEFAULT_FW_NAME "mrvl/sd8787_uapsta.bin"
+
 #define BLOCK_MODE     1
 #define BYTE_MODE      0
 
index 91634daec306c093928a7718c176d734b7bf07aa..67b2d0b78c71f2a9899851aea28036b16b084b55 100644 (file)
@@ -121,6 +121,7 @@ mwifiex_wmm_allocate_ralist_node(struct mwifiex_adapter *adapter, u8 *ra)
        memcpy(ra_list->ra, ra, ETH_ALEN);
 
        ra_list->total_pkts_size = 0;
+       ra_list->total_pkts = 0;
 
        dev_dbg(adapter->dev, "info: allocated ra_list %p\n", ra_list);
 
@@ -645,6 +646,7 @@ mwifiex_wmm_add_buf_txqueue(struct mwifiex_adapter *adapter,
        skb_queue_tail(&ra_list->skb_head, skb);
 
        ra_list->total_pkts_size += skb->len;
+       ra_list->total_pkts++;
 
        atomic_inc(&priv->wmm.tx_pkts_queued);
 
@@ -970,28 +972,6 @@ mwifiex_wmm_get_highest_priolist_ptr(struct mwifiex_adapter *adapter,
        return NULL;
 }
 
-/*
- * This function gets the number of packets in the Tx queue of a
- * particular RA list.
- */
-static int
-mwifiex_num_pkts_in_txq(struct mwifiex_private *priv,
-                       struct mwifiex_ra_list_tbl *ptr, int max_buf_size)
-{
-       int count = 0, total_size = 0;
-       struct sk_buff *skb, *tmp;
-
-       skb_queue_walk_safe(&ptr->skb_head, skb, tmp) {
-               total_size += skb->len;
-               if (total_size < max_buf_size)
-                       ++count;
-               else
-                       break;
-       }
-
-       return count;
-}
-
 /*
  * This function sends a single packet to firmware for transmission.
  */
@@ -1019,6 +999,7 @@ mwifiex_send_single_packet(struct mwifiex_private *priv,
        dev_dbg(adapter->dev, "data: dequeuing the packet %p %p\n", ptr, skb);
 
        ptr->total_pkts_size -= skb->len;
+       ptr->total_pkts--;
 
        if (!skb_queue_empty(&ptr->skb_head))
                skb_next = skb_peek(&ptr->skb_head);
@@ -1044,6 +1025,7 @@ mwifiex_send_single_packet(struct mwifiex_private *priv,
                skb_queue_tail(&ptr->skb_head, skb);
 
                ptr->total_pkts_size += skb->len;
+               ptr->total_pkts++;
                tx_info->flags |= MWIFIEX_BUF_FLAG_REQUEUED_PKT;
                spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock,
                                       ra_list_flags);
@@ -1231,9 +1213,9 @@ mwifiex_dequeue_tx_packet(struct mwifiex_adapter *adapter)
                }
 /* Minimum number of AMSDU */
 #define MIN_NUM_AMSDU 2
+
                if (mwifiex_is_amsdu_allowed(priv, tid) &&
-                   (mwifiex_num_pkts_in_txq(priv, ptr, adapter->tx_buf_size) >=
-                    MIN_NUM_AMSDU))
+                               (ptr->total_pkts >= MIN_NUM_AMSDU))
                        mwifiex_11n_aggregate_pkt(priv, ptr, INTF_HEADER_LEN,
                                                  ptr_index, flags);
                        /* ra_list_spinlock has been freed in
index b2f8b8fd4d2dc911dbb4f590430f8caa60dc70ab..a0a7854facc08e17a40f04f5eccd0a09a3c68c63 100644 (file)
@@ -83,14 +83,12 @@ config RT2800PCI_RT33XX
 config RT2800PCI_RT35XX
        bool "rt2800pci - Include support for rt35xx devices (EXPERIMENTAL)"
        depends on EXPERIMENTAL
-       default n
+       default y
        ---help---
          This adds support for rt35xx wireless chipset family to the
          rt2800pci driver.
          Supported chips: RT3060, RT3062, RT3562, RT3592
 
-         Support for these devices is non-functional at the moment and is
-         intended for testers and developers.
 
 config RT2800PCI_RT53XX
        bool "rt2800pci - Include support for rt53xx devices (EXPERIMENTAL)"
@@ -154,15 +152,12 @@ config RT2800USB_RT33XX
 config RT2800USB_RT35XX
        bool "rt2800usb - Include support for rt35xx devices (EXPERIMENTAL)"
        depends on EXPERIMENTAL
-       default n
+       default y
        ---help---
          This adds support for rt35xx wireless chipset family to the
          rt2800usb driver.
          Supported chips: RT3572
 
-         Support for these devices is non-functional at the moment and is
-         intended for testers and developers.
-
 config RT2800USB_RT53XX
        bool "rt2800usb - Include support for rt53xx devices (EXPERIMENTAL)"
        depends on EXPERIMENTAL
index f67bc9b31b28544091b5140ad86eee5ff8fe166f..c69a7d71f4cad3cf2b6f1a90b19d1512f6d849e7 100644 (file)
@@ -1740,6 +1740,7 @@ struct mac_iveiv_entry {
 /*
  * BBP 3: RX Antenna
  */
+#define BBP3_RX_ADC                            FIELD8(0x03)
 #define BBP3_RX_ANTENNA                        FIELD8(0x18)
 #define BBP3_HT40_MINUS                        FIELD8(0x20)
 
@@ -1783,22 +1784,34 @@ struct mac_iveiv_entry {
 #define RFCSR1_TX0_PD                  FIELD8(0x08)
 #define RFCSR1_RX1_PD                  FIELD8(0x10)
 #define RFCSR1_TX1_PD                  FIELD8(0x20)
+#define RFCSR1_RX2_PD                  FIELD8(0x40)
+#define RFCSR1_TX2_PD                  FIELD8(0x80)
 
 /*
  * RFCSR 2:
  */
 #define RFCSR2_RESCAL_EN               FIELD8(0x80)
 
+/*
+ * FRCSR 5:
+ */
+#define RFCSR5_R1                      FIELD8(0x0c)
+
 /*
  * RFCSR 6:
  */
 #define RFCSR6_R1                      FIELD8(0x03)
 #define RFCSR6_R2                      FIELD8(0x40)
+#define RFCSR6_TXDIV           FIELD8(0x0c)
 
 /*
  * RFCSR 7:
  */
 #define RFCSR7_RF_TUNING               FIELD8(0x01)
+#define RFCSR7_R02                             FIELD8(0x07)
+#define RFCSR7_R3                              FIELD8(0x08)
+#define RFCSR7_R45                             FIELD8(0x30)
+#define RFCSR7_R67                             FIELD8(0xc0)
 
 /*
  * RFCSR 11:
@@ -1809,11 +1822,13 @@ struct mac_iveiv_entry {
  * RFCSR 12:
  */
 #define RFCSR12_TX_POWER               FIELD8(0x1f)
+#define RFCSR12_DR0                            FIELD8(0xe0)
 
 /*
  * RFCSR 13:
  */
 #define RFCSR13_TX_POWER               FIELD8(0x1f)
+#define RFCSR13_DR0                            FIELD8(0xe0)
 
 /*
  * RFCSR 15:
@@ -2256,6 +2271,7 @@ struct mac_iveiv_entry {
 #define MCU_ANT_SELECT                 0X73
 #define MCU_BBP_SIGNAL                 0x80
 #define MCU_POWER_SAVE                 0x83
+#define MCU_BAND_SELECT                0x91
 
 /*
  * MCU mailbox tokens
index 8f92dfcb08df936f565df9746ef7577d6b686765..84ab7d1acb6a5a71c7f307a978b2a0036a3e27fb 100644 (file)
@@ -401,7 +401,8 @@ int rt2800_load_firmware(struct rt2x00_dev *rt2x00dev,
                return -EBUSY;
 
        if (rt2x00_is_pci(rt2x00dev)) {
-               if (rt2x00_rt(rt2x00dev, RT5390)) {
+               if (rt2x00_rt(rt2x00dev, RT3572) ||
+                   rt2x00_rt(rt2x00dev, RT5390)) {
                        rt2800_register_read(rt2x00dev, AUX_CTRL, &reg);
                        rt2x00_set_field32(&reg, AUX_CTRL_FORCE_PCIE_CLK, 1);
                        rt2x00_set_field32(&reg, AUX_CTRL_WAKE_PCIE_EN, 1);
@@ -600,49 +601,6 @@ void rt2800_process_rxwi(struct queue_entry *entry,
 }
 EXPORT_SYMBOL_GPL(rt2800_process_rxwi);
 
-static bool rt2800_txdone_entry_check(struct queue_entry *entry, u32 reg)
-{
-       __le32 *txwi;
-       u32 word;
-       int wcid, ack, pid;
-       int tx_wcid, tx_ack, tx_pid;
-
-       wcid    = rt2x00_get_field32(reg, TX_STA_FIFO_WCID);
-       ack     = rt2x00_get_field32(reg, TX_STA_FIFO_TX_ACK_REQUIRED);
-       pid     = rt2x00_get_field32(reg, TX_STA_FIFO_PID_TYPE);
-
-       /*
-        * This frames has returned with an IO error,
-        * so the status report is not intended for this
-        * frame.
-        */
-       if (test_bit(ENTRY_DATA_IO_FAILED, &entry->flags)) {
-               rt2x00lib_txdone_noinfo(entry, TXDONE_FAILURE);
-               return false;
-       }
-
-       /*
-        * Validate if this TX status report is intended for
-        * this entry by comparing the WCID/ACK/PID fields.
-        */
-       txwi = rt2800_drv_get_txwi(entry);
-
-       rt2x00_desc_read(txwi, 1, &word);
-       tx_wcid = rt2x00_get_field32(word, TXWI_W1_WIRELESS_CLI_ID);
-       tx_ack  = rt2x00_get_field32(word, TXWI_W1_ACK);
-       tx_pid  = rt2x00_get_field32(word, TXWI_W1_PACKETID);
-
-       if ((wcid != tx_wcid) || (ack != tx_ack) || (pid != tx_pid)) {
-               WARNING(entry->queue->rt2x00dev,
-                       "TX status report missed for queue %d entry %d\n",
-               entry->queue->qid, entry->entry_idx);
-               rt2x00lib_txdone_noinfo(entry, TXDONE_UNKNOWN);
-               return false;
-       }
-
-       return true;
-}
-
 void rt2800_txdone_entry(struct queue_entry *entry, u32 status)
 {
        struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
@@ -725,45 +683,6 @@ void rt2800_txdone_entry(struct queue_entry *entry, u32 status)
 }
 EXPORT_SYMBOL_GPL(rt2800_txdone_entry);
 
-void rt2800_txdone(struct rt2x00_dev *rt2x00dev)
-{
-       struct data_queue *queue;
-       struct queue_entry *entry;
-       u32 reg;
-       u8 qid;
-
-       while (kfifo_get(&rt2x00dev->txstatus_fifo, &reg)) {
-
-               /* TX_STA_FIFO_PID_QUEUE is a 2-bit field, thus
-                * qid is guaranteed to be one of the TX QIDs
-                */
-               qid = rt2x00_get_field32(reg, TX_STA_FIFO_PID_QUEUE);
-               queue = rt2x00queue_get_tx_queue(rt2x00dev, qid);
-               if (unlikely(!queue)) {
-                       WARNING(rt2x00dev, "Got TX status for an unavailable "
-                                          "queue %u, dropping\n", qid);
-                       continue;
-               }
-
-               /*
-                * Inside each queue, we process each entry in a chronological
-                * order. We first check that the queue is not empty.
-                */
-               entry = NULL;
-               while (!rt2x00queue_empty(queue)) {
-                       entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE);
-                       if (rt2800_txdone_entry_check(entry, reg))
-                               break;
-               }
-
-               if (!entry || rt2x00queue_empty(queue))
-                       break;
-
-               rt2800_txdone_entry(entry, reg);
-       }
-}
-EXPORT_SYMBOL_GPL(rt2800_txdone);
-
 void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc)
 {
        struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
@@ -1433,6 +1352,40 @@ void rt2800_config_erp(struct rt2x00_dev *rt2x00dev, struct rt2x00lib_erp *erp,
 }
 EXPORT_SYMBOL_GPL(rt2800_config_erp);
 
+static void rt2800_config_3572bt_ant(struct rt2x00_dev *rt2x00dev)
+{
+       u32 reg;
+       u16 eeprom;
+       u8 led_ctrl, led_g_mode, led_r_mode;
+
+       rt2800_register_read(rt2x00dev, GPIO_SWITCH, &reg);
+       if (rt2x00dev->curr_band == IEEE80211_BAND_5GHZ) {
+               rt2x00_set_field32(&reg, GPIO_SWITCH_0, 1);
+               rt2x00_set_field32(&reg, GPIO_SWITCH_1, 1);
+       } else {
+               rt2x00_set_field32(&reg, GPIO_SWITCH_0, 0);
+               rt2x00_set_field32(&reg, GPIO_SWITCH_1, 0);
+       }
+       rt2800_register_write(rt2x00dev, GPIO_SWITCH, reg);
+
+       rt2800_register_read(rt2x00dev, LED_CFG, &reg);
+       led_g_mode = rt2x00_get_field32(reg, LED_CFG_LED_POLAR) ? 3 : 0;
+       led_r_mode = rt2x00_get_field32(reg, LED_CFG_LED_POLAR) ? 0 : 3;
+       if (led_g_mode != rt2x00_get_field32(reg, LED_CFG_G_LED_MODE) ||
+           led_r_mode != rt2x00_get_field32(reg, LED_CFG_R_LED_MODE)) {
+               rt2x00_eeprom_read(rt2x00dev, EEPROM_FREQ, &eeprom);
+               led_ctrl = rt2x00_get_field16(eeprom, EEPROM_FREQ_LED_MODE);
+               if (led_ctrl == 0 || led_ctrl > 0x40) {
+                       rt2x00_set_field32(&reg, LED_CFG_G_LED_MODE, led_g_mode);
+                       rt2x00_set_field32(&reg, LED_CFG_R_LED_MODE, led_r_mode);
+                       rt2800_register_write(rt2x00dev, LED_CFG, reg);
+               } else {
+                       rt2800_mcu_request(rt2x00dev, MCU_BAND_SELECT, 0xff,
+                                          (led_g_mode << 2) | led_r_mode, 1);
+               }
+       }
+}
+
 static void rt2800_set_ant_diversity(struct rt2x00_dev *rt2x00dev,
                                     enum antenna ant)
 {
@@ -1463,6 +1416,10 @@ void rt2800_config_ant(struct rt2x00_dev *rt2x00dev, struct antenna_setup *ant)
        rt2800_bbp_read(rt2x00dev, 1, &r1);
        rt2800_bbp_read(rt2x00dev, 3, &r3);
 
+       if (rt2x00_rt(rt2x00dev, RT3572) &&
+           test_bit(CAPABILITY_BT_COEXIST, &rt2x00dev->cap_flags))
+               rt2800_config_3572bt_ant(rt2x00dev);
+
        /*
         * Configure the TX antenna.
         */
@@ -1471,7 +1428,11 @@ void rt2800_config_ant(struct rt2x00_dev *rt2x00dev, struct antenna_setup *ant)
                rt2x00_set_field8(&r1, BBP1_TX_ANTENNA, 0);
                break;
        case 2:
-               rt2x00_set_field8(&r1, BBP1_TX_ANTENNA, 2);
+               if (rt2x00_rt(rt2x00dev, RT3572) &&
+                   test_bit(CAPABILITY_BT_COEXIST, &rt2x00dev->cap_flags))
+                       rt2x00_set_field8(&r1, BBP1_TX_ANTENNA, 1);
+               else
+                       rt2x00_set_field8(&r1, BBP1_TX_ANTENNA, 2);
                break;
        case 3:
                rt2x00_set_field8(&r1, BBP1_TX_ANTENNA, 0);
@@ -1496,7 +1457,15 @@ void rt2800_config_ant(struct rt2x00_dev *rt2x00dev, struct antenna_setup *ant)
                rt2x00_set_field8(&r3, BBP3_RX_ANTENNA, 0);
                break;
        case 2:
-               rt2x00_set_field8(&r3, BBP3_RX_ANTENNA, 1);
+               if (rt2x00_rt(rt2x00dev, RT3572) &&
+                   test_bit(CAPABILITY_BT_COEXIST, &rt2x00dev->cap_flags)) {
+                       rt2x00_set_field8(&r3, BBP3_RX_ADC, 1);
+                       rt2x00_set_field8(&r3, BBP3_RX_ANTENNA,
+                               rt2x00dev->curr_band == IEEE80211_BAND_5GHZ);
+                       rt2800_set_ant_diversity(rt2x00dev, ANTENNA_B);
+               } else {
+                       rt2x00_set_field8(&r3, BBP3_RX_ANTENNA, 1);
+               }
                break;
        case 3:
                rt2x00_set_field8(&r3, BBP3_RX_ANTENNA, 2);
@@ -1630,6 +1599,161 @@ static void rt2800_config_channel_rf3xxx(struct rt2x00_dev *rt2x00dev,
        rt2800_rfcsr_write(rt2x00dev, 7, rfcsr);
 }
 
+static void rt2800_config_channel_rf3052(struct rt2x00_dev *rt2x00dev,
+                                        struct ieee80211_conf *conf,
+                                        struct rf_channel *rf,
+                                        struct channel_info *info)
+{
+       u8 rfcsr;
+       u32 reg;
+
+       if (rf->channel <= 14) {
+               rt2800_bbp_write(rt2x00dev, 25, 0x15);
+               rt2800_bbp_write(rt2x00dev, 26, 0x85);
+       } else {
+               rt2800_bbp_write(rt2x00dev, 25, 0x09);
+               rt2800_bbp_write(rt2x00dev, 26, 0xff);
+       }
+
+       rt2800_rfcsr_write(rt2x00dev, 2, rf->rf1);
+       rt2800_rfcsr_write(rt2x00dev, 3, rf->rf3);
+
+       rt2800_rfcsr_read(rt2x00dev, 6, &rfcsr);
+       rt2x00_set_field8(&rfcsr, RFCSR6_R1, rf->rf2);
+       if (rf->channel <= 14)
+               rt2x00_set_field8(&rfcsr, RFCSR6_TXDIV, 2);
+       else
+               rt2x00_set_field8(&rfcsr, RFCSR6_TXDIV, 1);
+       rt2800_rfcsr_write(rt2x00dev, 6, rfcsr);
+
+       rt2800_rfcsr_read(rt2x00dev, 5, &rfcsr);
+       if (rf->channel <= 14)
+               rt2x00_set_field8(&rfcsr, RFCSR5_R1, 1);
+       else
+               rt2x00_set_field8(&rfcsr, RFCSR5_R1, 2);
+       rt2800_rfcsr_write(rt2x00dev, 5, rfcsr);
+
+       rt2800_rfcsr_read(rt2x00dev, 12, &rfcsr);
+       if (rf->channel <= 14) {
+               rt2x00_set_field8(&rfcsr, RFCSR12_DR0, 3);
+               rt2x00_set_field8(&rfcsr, RFCSR12_TX_POWER,
+                               (info->default_power1 & 0x3) |
+                               ((info->default_power1 & 0xC) << 1));
+       } else {
+               rt2x00_set_field8(&rfcsr, RFCSR12_DR0, 7);
+               rt2x00_set_field8(&rfcsr, RFCSR12_TX_POWER,
+                               (info->default_power1 & 0x3) |
+                               ((info->default_power1 & 0xC) << 1));
+       }
+       rt2800_rfcsr_write(rt2x00dev, 12, rfcsr);
+
+       rt2800_rfcsr_read(rt2x00dev, 13, &rfcsr);
+       if (rf->channel <= 14) {
+               rt2x00_set_field8(&rfcsr, RFCSR13_DR0, 3);
+               rt2x00_set_field8(&rfcsr, RFCSR13_TX_POWER,
+                               (info->default_power2 & 0x3) |
+                               ((info->default_power2 & 0xC) << 1));
+       } else {
+               rt2x00_set_field8(&rfcsr, RFCSR13_DR0, 7);
+               rt2x00_set_field8(&rfcsr, RFCSR13_TX_POWER,
+                               (info->default_power2 & 0x3) |
+                               ((info->default_power2 & 0xC) << 1));
+       }
+       rt2800_rfcsr_write(rt2x00dev, 13, rfcsr);
+
+       rt2800_rfcsr_read(rt2x00dev, 1, &rfcsr);
+       rt2x00_set_field8(&rfcsr, RFCSR1_RF_BLOCK_EN, 1);
+       rt2x00_set_field8(&rfcsr, RFCSR1_RX0_PD, 0);
+       rt2x00_set_field8(&rfcsr, RFCSR1_TX0_PD, 0);
+       rt2x00_set_field8(&rfcsr, RFCSR1_RX1_PD, 0);
+       rt2x00_set_field8(&rfcsr, RFCSR1_TX1_PD, 0);
+       if (test_bit(CAPABILITY_BT_COEXIST, &rt2x00dev->cap_flags)) {
+               if (rf->channel <= 14) {
+                       rt2x00_set_field8(&rfcsr, RFCSR1_RX0_PD, 1);
+                       rt2x00_set_field8(&rfcsr, RFCSR1_TX0_PD, 1);
+               }
+               rt2x00_set_field8(&rfcsr, RFCSR1_RX2_PD, 1);
+               rt2x00_set_field8(&rfcsr, RFCSR1_TX2_PD, 1);
+       } else {
+               switch (rt2x00dev->default_ant.tx_chain_num) {
+               case 1:
+                       rt2x00_set_field8(&rfcsr, RFCSR1_TX1_PD, 1);
+               case 2:
+                       rt2x00_set_field8(&rfcsr, RFCSR1_TX2_PD, 1);
+                       break;
+               }
+
+               switch (rt2x00dev->default_ant.rx_chain_num) {
+               case 1:
+                       rt2x00_set_field8(&rfcsr, RFCSR1_RX1_PD, 1);
+               case 2:
+                       rt2x00_set_field8(&rfcsr, RFCSR1_RX2_PD, 1);
+                       break;
+               }
+       }
+       rt2800_rfcsr_write(rt2x00dev, 1, rfcsr);
+
+       rt2800_rfcsr_read(rt2x00dev, 23, &rfcsr);
+       rt2x00_set_field8(&rfcsr, RFCSR23_FREQ_OFFSET, rt2x00dev->freq_offset);
+       rt2800_rfcsr_write(rt2x00dev, 23, rfcsr);
+
+       rt2800_rfcsr_write(rt2x00dev, 24,
+                             rt2x00dev->calibration[conf_is_ht40(conf)]);
+       rt2800_rfcsr_write(rt2x00dev, 31,
+                             rt2x00dev->calibration[conf_is_ht40(conf)]);
+
+       if (rf->channel <= 14) {
+               rt2800_rfcsr_write(rt2x00dev, 7, 0xd8);
+               rt2800_rfcsr_write(rt2x00dev, 9, 0xc3);
+               rt2800_rfcsr_write(rt2x00dev, 10, 0xf1);
+               rt2800_rfcsr_write(rt2x00dev, 11, 0xb9);
+               rt2800_rfcsr_write(rt2x00dev, 15, 0x53);
+               rt2800_rfcsr_write(rt2x00dev, 16, 0x4c);
+               rt2800_rfcsr_write(rt2x00dev, 17, 0x23);
+               rt2800_rfcsr_write(rt2x00dev, 19, 0x93);
+               rt2800_rfcsr_write(rt2x00dev, 20, 0xb3);
+               rt2800_rfcsr_write(rt2x00dev, 25, 0x15);
+               rt2800_rfcsr_write(rt2x00dev, 26, 0x85);
+               rt2800_rfcsr_write(rt2x00dev, 27, 0x00);
+               rt2800_rfcsr_write(rt2x00dev, 29, 0x9b);
+       } else {
+               rt2800_rfcsr_write(rt2x00dev, 7, 0x14);
+               rt2800_rfcsr_write(rt2x00dev, 9, 0xc0);
+               rt2800_rfcsr_write(rt2x00dev, 10, 0xf1);
+               rt2800_rfcsr_write(rt2x00dev, 11, 0x00);
+               rt2800_rfcsr_write(rt2x00dev, 15, 0x43);
+               rt2800_rfcsr_write(rt2x00dev, 16, 0x7a);
+               rt2800_rfcsr_write(rt2x00dev, 17, 0x23);
+               if (rf->channel <= 64) {
+                       rt2800_rfcsr_write(rt2x00dev, 19, 0xb7);
+                       rt2800_rfcsr_write(rt2x00dev, 20, 0xf6);
+                       rt2800_rfcsr_write(rt2x00dev, 25, 0x3d);
+               } else if (rf->channel <= 128) {
+                       rt2800_rfcsr_write(rt2x00dev, 19, 0x74);
+                       rt2800_rfcsr_write(rt2x00dev, 20, 0xf4);
+                       rt2800_rfcsr_write(rt2x00dev, 25, 0x01);
+               } else {
+                       rt2800_rfcsr_write(rt2x00dev, 19, 0x72);
+                       rt2800_rfcsr_write(rt2x00dev, 20, 0xf3);
+                       rt2800_rfcsr_write(rt2x00dev, 25, 0x01);
+               }
+               rt2800_rfcsr_write(rt2x00dev, 26, 0x87);
+               rt2800_rfcsr_write(rt2x00dev, 27, 0x01);
+               rt2800_rfcsr_write(rt2x00dev, 29, 0x9f);
+       }
+
+       rt2800_register_read(rt2x00dev, GPIO_CTRL_CFG, &reg);
+       rt2x00_set_field32(&reg, GPIO_CTRL_CFG_GPIOD_BIT7, 0);
+       if (rf->channel <= 14)
+               rt2x00_set_field32(&reg, GPIO_CTRL_CFG_BIT7, 1);
+       else
+               rt2x00_set_field32(&reg, GPIO_CTRL_CFG_BIT7, 0);
+       rt2800_register_write(rt2x00dev, GPIO_CTRL_CFG, reg);
+
+       rt2800_rfcsr_read(rt2x00dev, 7, &rfcsr);
+       rt2x00_set_field8(&rfcsr, RFCSR7_RF_TUNING, 1);
+       rt2800_rfcsr_write(rt2x00dev, 7, rfcsr);
+}
 
 #define RT5390_POWER_BOUND     0x27
 #define RT5390_FREQ_OFFSET_BOUND       0x5f
@@ -1748,9 +1872,10 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
            rt2x00_rf(rt2x00dev, RF3020) ||
            rt2x00_rf(rt2x00dev, RF3021) ||
            rt2x00_rf(rt2x00dev, RF3022) ||
-           rt2x00_rf(rt2x00dev, RF3052) ||
            rt2x00_rf(rt2x00dev, RF3320))
                rt2800_config_channel_rf3xxx(rt2x00dev, conf, rf, info);
+       else if (rt2x00_rf(rt2x00dev, RF3052))
+               rt2800_config_channel_rf3052(rt2x00dev, conf, rf, info);
        else if (rt2x00_rf(rt2x00dev, RF5370) ||
                 rt2x00_rf(rt2x00dev, RF5390))
                rt2800_config_channel_rf53xx(rt2x00dev, conf, rf, info);
@@ -1777,7 +1902,10 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
                        }
                }
        } else {
-               rt2800_bbp_write(rt2x00dev, 82, 0xf2);
+               if (rt2x00_rt(rt2x00dev, RT3572))
+                       rt2800_bbp_write(rt2x00dev, 82, 0x94);
+               else
+                       rt2800_bbp_write(rt2x00dev, 82, 0xf2);
 
                if (test_bit(CAPABILITY_EXTERNAL_LNA_A, &rt2x00dev->cap_flags))
                        rt2800_bbp_write(rt2x00dev, 75, 0x46);
@@ -1791,12 +1919,17 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
        rt2x00_set_field32(&reg, TX_BAND_CFG_BG, rf->channel <= 14);
        rt2800_register_write(rt2x00dev, TX_BAND_CFG, reg);
 
+       if (rt2x00_rt(rt2x00dev, RT3572))
+               rt2800_rfcsr_write(rt2x00dev, 8, 0);
+
        tx_pin = 0;
 
        /* Turn on unused PA or LNA when not using 1T or 1R */
        if (rt2x00dev->default_ant.tx_chain_num == 2) {
-               rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_A1_EN, 1);
-               rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_G1_EN, 1);
+               rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_A1_EN,
+                                  rf->channel > 14);
+               rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_G1_EN,
+                                  rf->channel <= 14);
        }
 
        /* Turn on unused PA or LNA when not using 1T or 1R */
@@ -1809,11 +1942,18 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
        rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_G0_EN, 1);
        rt2x00_set_field32(&tx_pin, TX_PIN_CFG_RFTR_EN, 1);
        rt2x00_set_field32(&tx_pin, TX_PIN_CFG_TRSW_EN, 1);
-       rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_G0_EN, rf->channel <= 14);
+       if (test_bit(CAPABILITY_BT_COEXIST, &rt2x00dev->cap_flags))
+               rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_G0_EN, 1);
+       else
+               rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_G0_EN,
+                                  rf->channel <= 14);
        rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_A0_EN, rf->channel > 14);
 
        rt2800_register_write(rt2x00dev, TX_PIN_CFG, tx_pin);
 
+       if (rt2x00_rt(rt2x00dev, RT3572))
+               rt2800_rfcsr_write(rt2x00dev, 8, 0x80);
+
        rt2800_bbp_read(rt2x00dev, 4, &bbp);
        rt2x00_set_field8(&bbp, BBP4_BANDWIDTH, 2 * conf_is_ht40(conf));
        rt2800_bbp_write(rt2x00dev, 4, bbp);
@@ -2413,6 +2553,9 @@ static int rt2800_init_registers(struct rt2x00_dev *rt2x00dev)
                rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000400);
                rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00000000);
                rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x00000030);
+       } else if (rt2x00_rt(rt2x00dev, RT3572)) {
+               rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000400);
+               rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00080606);
        } else if (rt2x00_rt(rt2x00dev, RT5390)) {
                rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000404);
                rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00080606);
@@ -2799,6 +2942,7 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev)
        }
 
        if (rt2800_is_305x_soc(rt2x00dev) ||
+           rt2x00_rt(rt2x00dev, RT3572) ||
            rt2x00_rt(rt2x00dev, RT5390))
                rt2800_bbp_write(rt2x00dev, 31, 0x08);
 
@@ -2828,6 +2972,7 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev)
            rt2x00_rt(rt2x00dev, RT3071) ||
            rt2x00_rt(rt2x00dev, RT3090) ||
            rt2x00_rt(rt2x00dev, RT3390) ||
+           rt2x00_rt(rt2x00dev, RT3572) ||
            rt2x00_rt(rt2x00dev, RT5390)) {
                rt2800_bbp_write(rt2x00dev, 79, 0x13);
                rt2800_bbp_write(rt2x00dev, 80, 0x05);
@@ -2868,6 +3013,7 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev)
            rt2x00_rt_rev_gte(rt2x00dev, RT3071, REV_RT3071E) ||
            rt2x00_rt_rev_gte(rt2x00dev, RT3090, REV_RT3090E) ||
            rt2x00_rt_rev_gte(rt2x00dev, RT3390, REV_RT3390E) ||
+           rt2x00_rt(rt2x00dev, RT3572) ||
            rt2x00_rt(rt2x00dev, RT5390) ||
            rt2800_is_305x_soc(rt2x00dev))
                rt2800_bbp_write(rt2x00dev, 103, 0xc0);
@@ -2895,6 +3041,7 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev)
        if (rt2x00_rt(rt2x00dev, RT3071) ||
            rt2x00_rt(rt2x00dev, RT3090) ||
            rt2x00_rt(rt2x00dev, RT3390) ||
+           rt2x00_rt(rt2x00dev, RT3572) ||
            rt2x00_rt(rt2x00dev, RT5390)) {
                rt2800_bbp_read(rt2x00dev, 138, &value);
 
@@ -3031,6 +3178,7 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
            !rt2x00_rt(rt2x00dev, RT3071) &&
            !rt2x00_rt(rt2x00dev, RT3090) &&
            !rt2x00_rt(rt2x00dev, RT3390) &&
+           !rt2x00_rt(rt2x00dev, RT3572) &&
            !rt2x00_rt(rt2x00dev, RT5390) &&
            !rt2800_is_305x_soc(rt2x00dev))
                return 0;
@@ -3109,6 +3257,38 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
                rt2800_rfcsr_write(rt2x00dev, 29, 0x8f);
                rt2800_rfcsr_write(rt2x00dev, 30, 0x20);
                rt2800_rfcsr_write(rt2x00dev, 31, 0x0f);
+       } else if (rt2x00_rt(rt2x00dev, RT3572)) {
+               rt2800_rfcsr_write(rt2x00dev, 0, 0x70);
+               rt2800_rfcsr_write(rt2x00dev, 1, 0x81);
+               rt2800_rfcsr_write(rt2x00dev, 2, 0xf1);
+               rt2800_rfcsr_write(rt2x00dev, 3, 0x02);
+               rt2800_rfcsr_write(rt2x00dev, 4, 0x4c);
+               rt2800_rfcsr_write(rt2x00dev, 5, 0x05);
+               rt2800_rfcsr_write(rt2x00dev, 6, 0x4a);
+               rt2800_rfcsr_write(rt2x00dev, 7, 0xd8);
+               rt2800_rfcsr_write(rt2x00dev, 9, 0xc3);
+               rt2800_rfcsr_write(rt2x00dev, 10, 0xf1);
+               rt2800_rfcsr_write(rt2x00dev, 11, 0xb9);
+               rt2800_rfcsr_write(rt2x00dev, 12, 0x70);
+               rt2800_rfcsr_write(rt2x00dev, 13, 0x65);
+               rt2800_rfcsr_write(rt2x00dev, 14, 0xa0);
+               rt2800_rfcsr_write(rt2x00dev, 15, 0x53);
+               rt2800_rfcsr_write(rt2x00dev, 16, 0x4c);
+               rt2800_rfcsr_write(rt2x00dev, 17, 0x23);
+               rt2800_rfcsr_write(rt2x00dev, 18, 0xac);
+               rt2800_rfcsr_write(rt2x00dev, 19, 0x93);
+               rt2800_rfcsr_write(rt2x00dev, 20, 0xb3);
+               rt2800_rfcsr_write(rt2x00dev, 21, 0xd0);
+               rt2800_rfcsr_write(rt2x00dev, 22, 0x00);
+               rt2800_rfcsr_write(rt2x00dev, 23, 0x3c);
+               rt2800_rfcsr_write(rt2x00dev, 24, 0x16);
+               rt2800_rfcsr_write(rt2x00dev, 25, 0x15);
+               rt2800_rfcsr_write(rt2x00dev, 26, 0x85);
+               rt2800_rfcsr_write(rt2x00dev, 27, 0x00);
+               rt2800_rfcsr_write(rt2x00dev, 28, 0x00);
+               rt2800_rfcsr_write(rt2x00dev, 29, 0x9b);
+               rt2800_rfcsr_write(rt2x00dev, 30, 0x09);
+               rt2800_rfcsr_write(rt2x00dev, 31, 0x10);
        } else if (rt2800_is_305x_soc(rt2x00dev)) {
                rt2800_rfcsr_write(rt2x00dev, 0, 0x50);
                rt2800_rfcsr_write(rt2x00dev, 1, 0x01);
@@ -3258,6 +3438,19 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
                rt2800_register_read(rt2x00dev, GPIO_SWITCH, &reg);
                rt2x00_set_field32(&reg, GPIO_SWITCH_5, 0);
                rt2800_register_write(rt2x00dev, GPIO_SWITCH, reg);
+       } else if (rt2x00_rt(rt2x00dev, RT3572)) {
+               rt2800_rfcsr_read(rt2x00dev, 6, &rfcsr);
+               rt2x00_set_field8(&rfcsr, RFCSR6_R2, 1);
+               rt2800_rfcsr_write(rt2x00dev, 6, rfcsr);
+
+               rt2800_register_read(rt2x00dev, LDO_CFG0, &reg);
+               rt2x00_set_field32(&reg, LDO_CFG0_LDO_CORE_VLEVEL, 3);
+               rt2x00_set_field32(&reg, LDO_CFG0_BGSEL, 1);
+               rt2800_register_write(rt2x00dev, LDO_CFG0, reg);
+               msleep(1);
+               rt2800_register_read(rt2x00dev, LDO_CFG0, &reg);
+               rt2x00_set_field32(&reg, LDO_CFG0_BGSEL, 1);
+               rt2800_register_write(rt2x00dev, LDO_CFG0, reg);
        }
 
        /*
@@ -3270,7 +3463,8 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
                        rt2800_init_rx_filter(rt2x00dev, true, 0x27, 0x19);
        } else if (rt2x00_rt(rt2x00dev, RT3071) ||
                   rt2x00_rt(rt2x00dev, RT3090) ||
-                  rt2x00_rt(rt2x00dev, RT3390)) {
+                  rt2x00_rt(rt2x00dev, RT3390) ||
+                  rt2x00_rt(rt2x00dev, RT3572)) {
                rt2x00dev->calibration[0] =
                        rt2800_init_rx_filter(rt2x00dev, false, 0x07, 0x13);
                rt2x00dev->calibration[1] =
index f2d15941c71ac79f76ca5b506e57f8e500181c09..69deb3148ae77348fed373464868aefeee6327fc 100644 (file)
@@ -152,7 +152,6 @@ void rt2800_write_tx_data(struct queue_entry *entry,
                          struct txentry_desc *txdesc);
 void rt2800_process_rxwi(struct queue_entry *entry, struct rxdone_entry_desc *txdesc);
 
-void rt2800_txdone(struct rt2x00_dev *rt2x00dev);
 void rt2800_txdone_entry(struct queue_entry *entry, u32 status);
 
 void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc);
index 3ac0943b9789e66998dc9ef664da38c7a8d07e90..9ccc53733bae556a9ea4e7e4a47a64cf16ec6c10 100644 (file)
@@ -501,7 +501,9 @@ static int rt2800pci_init_registers(struct rt2x00_dev *rt2x00dev)
        rt2x00pci_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000e1f);
        rt2x00pci_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000e00);
 
-       if (rt2x00_rt(rt2x00dev, RT5390)) {
+       if (rt2x00_is_pcie(rt2x00dev) &&
+           (rt2x00_rt(rt2x00dev, RT3572) ||
+            rt2x00_rt(rt2x00dev, RT5390))) {
                rt2x00pci_register_read(rt2x00dev, AUX_CTRL, &reg);
                rt2x00_set_field32(&reg, AUX_CTRL_FORCE_PCIE_CLK, 1);
                rt2x00_set_field32(&reg, AUX_CTRL_WAKE_PCIE_EN, 1);
index ba82c972703aec773780bced0255f5d28075a673..6e9229830a2956d99527883523d363a89a551aa5 100644 (file)
@@ -457,6 +457,87 @@ static int rt2800usb_get_tx_data_len(struct queue_entry *entry)
 /*
  * TX control handlers
  */
+static bool rt2800usb_txdone_entry_check(struct queue_entry *entry, u32 reg)
+{
+       __le32 *txwi;
+       u32 word;
+       int wcid, ack, pid;
+       int tx_wcid, tx_ack, tx_pid;
+
+       wcid    = rt2x00_get_field32(reg, TX_STA_FIFO_WCID);
+       ack     = rt2x00_get_field32(reg, TX_STA_FIFO_TX_ACK_REQUIRED);
+       pid     = rt2x00_get_field32(reg, TX_STA_FIFO_PID_TYPE);
+
+       /*
+        * This frames has returned with an IO error,
+        * so the status report is not intended for this
+        * frame.
+        */
+       if (test_bit(ENTRY_DATA_IO_FAILED, &entry->flags)) {
+               rt2x00lib_txdone_noinfo(entry, TXDONE_FAILURE);
+               return false;
+       }
+
+       /*
+        * Validate if this TX status report is intended for
+        * this entry by comparing the WCID/ACK/PID fields.
+        */
+       txwi = rt2800usb_get_txwi(entry);
+
+       rt2x00_desc_read(txwi, 1, &word);
+       tx_wcid = rt2x00_get_field32(word, TXWI_W1_WIRELESS_CLI_ID);
+       tx_ack  = rt2x00_get_field32(word, TXWI_W1_ACK);
+       tx_pid  = rt2x00_get_field32(word, TXWI_W1_PACKETID);
+
+       if ((wcid != tx_wcid) || (ack != tx_ack) || (pid != tx_pid)) {
+               WARNING(entry->queue->rt2x00dev,
+                       "TX status report missed for queue %d entry %d\n",
+               entry->queue->qid, entry->entry_idx);
+               rt2x00lib_txdone_noinfo(entry, TXDONE_UNKNOWN);
+               return false;
+       }
+
+       return true;
+}
+
+static void rt2800usb_txdone(struct rt2x00_dev *rt2x00dev)
+{
+       struct data_queue *queue;
+       struct queue_entry *entry;
+       u32 reg;
+       u8 qid;
+
+       while (kfifo_get(&rt2x00dev->txstatus_fifo, &reg)) {
+
+               /* TX_STA_FIFO_PID_QUEUE is a 2-bit field, thus
+                * qid is guaranteed to be one of the TX QIDs
+                */
+               qid = rt2x00_get_field32(reg, TX_STA_FIFO_PID_QUEUE);
+               queue = rt2x00queue_get_tx_queue(rt2x00dev, qid);
+               if (unlikely(!queue)) {
+                       WARNING(rt2x00dev, "Got TX status for an unavailable "
+                                          "queue %u, dropping\n", qid);
+                       continue;
+               }
+
+               /*
+                * Inside each queue, we process each entry in a chronological
+                * order. We first check that the queue is not empty.
+                */
+               entry = NULL;
+               while (!rt2x00queue_empty(queue)) {
+                       entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE);
+                       if (rt2800usb_txdone_entry_check(entry, reg))
+                               break;
+               }
+
+               if (!entry || rt2x00queue_empty(queue))
+                       break;
+
+               rt2800_txdone_entry(entry, reg);
+       }
+}
+
 static void rt2800usb_work_txdone(struct work_struct *work)
 {
        struct rt2x00_dev *rt2x00dev =
@@ -464,7 +545,7 @@ static void rt2800usb_work_txdone(struct work_struct *work)
        struct data_queue *queue;
        struct queue_entry *entry;
 
-       rt2800_txdone(rt2x00dev);
+       rt2800usb_txdone(rt2x00dev);
 
        /*
         * Process any trailing TX status reports for IO failures,
index 555180d8f4aa7055aa77a417b75fa894898964a8..b704e5b183d0bc539e8bec6d08776774854d5479 100644 (file)
@@ -250,7 +250,8 @@ void rt2x00lib_config(struct rt2x00_dev *rt2x00dev,
        if (ieee80211_flags & IEEE80211_CONF_CHANGE_CHANNEL)
                rt2x00link_reset_tuner(rt2x00dev, false);
 
-       if (test_bit(REQUIRE_PS_AUTOWAKE, &rt2x00dev->cap_flags) &&
+       if (test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags) &&
+           test_bit(REQUIRE_PS_AUTOWAKE, &rt2x00dev->cap_flags) &&
            (ieee80211_flags & IEEE80211_CONF_CHANGE_PS) &&
            (conf->flags & IEEE80211_CONF_PS)) {
                beacon_diff = (long)jiffies - (long)rt2x00dev->last_beacon;
index c018d67aab8e40b7a5c719d04f14eb52a4853d9b..939821b4af2ff5b768913cc0809b05695801285c 100644 (file)
@@ -146,6 +146,9 @@ static void rt2x00lib_autowakeup(struct work_struct *work)
        struct rt2x00_dev *rt2x00dev =
            container_of(work, struct rt2x00_dev, autowakeup_work.work);
 
+       if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags))
+               return;
+
        if (rt2x00dev->ops->lib->set_device_state(rt2x00dev, STATE_AWAKE))
                ERROR(rt2x00dev, "Device failed to wakeup.\n");
        clear_bit(CONFIG_POWERSAVING, &rt2x00dev->flags);
@@ -1160,6 +1163,7 @@ void rt2x00lib_remove_dev(struct rt2x00_dev *rt2x00dev)
         * Stop all work.
         */
        cancel_work_sync(&rt2x00dev->intf_work);
+       cancel_delayed_work_sync(&rt2x00dev->autowakeup_work);
        if (rt2x00_is_usb(rt2x00dev)) {
                del_timer_sync(&rt2x00dev->txstatus_timer);
                cancel_work_sync(&rt2x00dev->rxdone_work);
index ab8c16f8bcafebec3faeecb412669792eab664a0..c7fc9def6bcf7f6933d7b767f352cc922a2c9070 100644 (file)
@@ -206,7 +206,6 @@ static void rt2x00queue_create_tx_descriptor_seq(struct queue_entry *entry,
        struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(entry->skb);
        struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)entry->skb->data;
        struct rt2x00_intf *intf = vif_to_intf(tx_info->control.vif);
-       unsigned long irqflags;
 
        if (!(tx_info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ))
                return;
@@ -227,14 +226,14 @@ static void rt2x00queue_create_tx_descriptor_seq(struct queue_entry *entry,
         * sequence counting per-frame, since those will override the
         * sequence counter given by mac80211.
         */
-       spin_lock_irqsave(&intf->seqlock, irqflags);
+       spin_lock(&intf->seqlock);
 
        if (test_bit(ENTRY_TXD_FIRST_FRAGMENT, &txdesc->flags))
                intf->seqno += 0x10;
        hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG);
        hdr->seq_ctrl |= cpu_to_le16(intf->seqno);
 
-       spin_unlock_irqrestore(&intf->seqlock, irqflags);
+       spin_unlock(&intf->seqlock);
 
 }
 
index ccb6da38fe22aff9938b4af119385756fa487210..fb5e43bd7c3c8076ccc0942998e2a0ea1d576fc0 100644 (file)
@@ -888,7 +888,6 @@ int rtl_tx_agg_stop(struct ieee80211_hw *hw,
 {
        struct rtl_priv *rtlpriv = rtl_priv(hw);
        struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
-       struct rtl_tid_data *tid_data;
        struct rtl_sta_info *sta_entry = NULL;
 
        if (sta == NULL)
@@ -906,7 +905,6 @@ int rtl_tx_agg_stop(struct ieee80211_hw *hw,
                return -EINVAL;
 
        sta_entry = (struct rtl_sta_info *)sta->drv_priv;
-       tid_data = &sta_entry->tids[tid];
        sta_entry->tids[tid].agg.agg_state = RTL_AGG_STOP;
 
        ieee80211_stop_tx_ba_cb_irqsafe(mac->vif, sta->addr, tid);
@@ -918,7 +916,6 @@ int rtl_tx_agg_oper(struct ieee80211_hw *hw,
                struct ieee80211_sta *sta, u16 tid)
 {
        struct rtl_priv *rtlpriv = rtl_priv(hw);
-       struct rtl_tid_data *tid_data;
        struct rtl_sta_info *sta_entry = NULL;
 
        if (sta == NULL)
@@ -936,7 +933,6 @@ int rtl_tx_agg_oper(struct ieee80211_hw *hw,
                return -EINVAL;
 
        sta_entry = (struct rtl_sta_info *)sta->drv_priv;
-       tid_data = &sta_entry->tids[tid];
        sta_entry->tids[tid].agg.agg_state = RTL_AGG_OPERATIONAL;
 
        return 0;
index 50de6f5d8a560baf0eee87995203a47f2611dd8b..0b562322f13890b58f71ec37197c401cadf66c3f 100644 (file)
@@ -925,7 +925,7 @@ static int efuse_pg_packet_write(struct ieee80211_hw *hw,
        struct rtl_priv *rtlpriv = rtl_priv(hw);
        struct pgpkt_struct target_pkt;
        u8 write_state = PG_STATE_HEADER;
-       int continual = true, dataempty = true, result = true;
+       int continual = true, result = true;
        u16 efuse_addr = 0;
        u8 efuse_data;
        u8 target_word_cnts = 0;
@@ -953,7 +953,6 @@ static int efuse_pg_packet_write(struct ieee80211_hw *hw,
               (EFUSE_MAX_SIZE - EFUSE_OOB_PROTECT_BYTES))) {
 
                if (write_state == PG_STATE_HEADER) {
-                       dataempty = true;
                        badworden = 0x0F;
                        RTPRINT(rtlpriv, FEEPROM, EFUSE_PG,
                                ("efuse PG_STATE_HEADER\n"));
@@ -1176,13 +1175,12 @@ static u16 efuse_get_current_size(struct ieee80211_hw *hw)
 {
        int continual = true;
        u16 efuse_addr = 0;
-       u8 hoffset, hworden;
+       u8 hworden;
        u8 efuse_data, word_cnts;
 
        while (continual && efuse_one_byte_read(hw, efuse_addr, &efuse_data)
               && (efuse_addr < EFUSE_MAX_SIZE)) {
                if (efuse_data != 0xFF) {
-                       hoffset = (efuse_data >> 4) & 0x0F;
                        hworden = efuse_data & 0x0F;
                        word_cnts = efuse_calculate_word_cnts(hworden);
                        efuse_addr = efuse_addr + (word_cnts * 2) + 1;
index 89100e7c553b782aa02b349075c488da54323e10..fc44005b0d53a6f2c866dd90b896bacf05ad5cda 100644 (file)
@@ -622,7 +622,7 @@ tx_status_ok:
        if (((rtlpriv->link_info.num_rx_inperiod +
                rtlpriv->link_info.num_tx_inperiod) > 8) ||
                (rtlpriv->link_info.num_rx_inperiod > 2)) {
-               rtl_lps_leave(hw);
+               tasklet_schedule(&rtlpriv->works.ips_leave_tasklet);
        }
 }
 
@@ -644,22 +644,23 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw)
                .noise = -98,
                .rate = 0,
        };
+       int index = rtlpci->rx_ring[rx_queue_idx].idx;
 
        /*RX NORMAL PKT */
        while (count--) {
                /*rx descriptor */
                struct rtl_rx_desc *pdesc = &rtlpci->rx_ring[rx_queue_idx].desc[
-                               rtlpci->rx_ring[rx_queue_idx].idx];
+                               index];
                /*rx pkt */
                struct sk_buff *skb = rtlpci->rx_ring[rx_queue_idx].rx_buf[
-                               rtlpci->rx_ring[rx_queue_idx].idx];
+                               index];
 
                own = (u8) rtlpriv->cfg->ops->get_desc((u8 *) pdesc,
                                                       false, HW_DESC_OWN);
 
                if (own) {
                        /*wait data to be filled by hardware */
-                       return;
+                       break;
                } else {
                        struct ieee80211_hdr *hdr;
                        __le16 fc;
@@ -700,7 +701,7 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw)
                                         rtlpci->rxbuffersize,
                                         PCI_DMA_FROMDEVICE);
 
-                       if (!stats.crc || !stats.hwerror) {
+                       if (!stats.crc && !stats.hwerror) {
                                memcpy(IEEE80211_SKB_RXCB(skb), &rx_status,
                                       sizeof(rx_status));
 
@@ -765,15 +766,12 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw)
                        if (((rtlpriv->link_info.num_rx_inperiod +
                                rtlpriv->link_info.num_tx_inperiod) > 8) ||
                                (rtlpriv->link_info.num_rx_inperiod > 2)) {
-                               rtl_lps_leave(hw);
+                               tasklet_schedule(&rtlpriv->works.ips_leave_tasklet);
                        }
 
                        skb = new_skb;
 
-                       rtlpci->rx_ring[rx_queue_idx].rx_buf[rtlpci->
-                                                            rx_ring
-                                                            [rx_queue_idx].
-                                                            idx] = skb;
+                       rtlpci->rx_ring[rx_queue_idx].rx_buf[index] = skb;
                        *((dma_addr_t *) skb->cb) =
                            pci_map_single(rtlpci->pdev, skb_tail_pointer(skb),
                                           rtlpci->rxbuffersize,
@@ -786,23 +784,22 @@ done:
                rtlpriv->cfg->ops->set_desc((u8 *) pdesc, false,
                                            HW_DESC_RXBUFF_ADDR,
                                            (u8 *)&bufferaddress);
-               rtlpriv->cfg->ops->set_desc((u8 *)pdesc, false, HW_DESC_RXOWN,
-                                           (u8 *)&tmp_one);
                rtlpriv->cfg->ops->set_desc((u8 *)pdesc, false,
                                            HW_DESC_RXPKT_LEN,
                                            (u8 *)&rtlpci->rxbuffersize);
 
-               if (rtlpci->rx_ring[rx_queue_idx].idx ==
-                   rtlpci->rxringcount - 1)
+               if (index == rtlpci->rxringcount - 1)
                        rtlpriv->cfg->ops->set_desc((u8 *)pdesc, false,
                                                    HW_DESC_RXERO,
                                                    (u8 *)&tmp_one);
 
-               rtlpci->rx_ring[rx_queue_idx].idx =
-                   (rtlpci->rx_ring[rx_queue_idx].idx + 1) %
-                   rtlpci->rxringcount;
+               rtlpriv->cfg->ops->set_desc((u8 *)pdesc, false, HW_DESC_RXOWN,
+                                           (u8 *)&tmp_one);
+
+               index = (index + 1) % rtlpci->rxringcount;
        }
 
+       rtlpci->rx_ring[rx_queue_idx].idx = index;
 }
 
 static irqreturn_t _rtl_pci_interrupt(int irq, void *dev_id)
@@ -940,6 +937,11 @@ static void _rtl_pci_irq_tasklet(struct ieee80211_hw *hw)
        _rtl_pci_tx_chk_waitq(hw);
 }
 
+static void _rtl_pci_ips_leave_tasklet(struct ieee80211_hw *hw)
+{
+       rtl_lps_leave(hw);
+}
+
 static void _rtl_pci_prepare_bcn_tasklet(struct ieee80211_hw *hw)
 {
        struct rtl_priv *rtlpriv = rtl_priv(hw);
@@ -1038,6 +1040,9 @@ static void _rtl_pci_init_struct(struct ieee80211_hw *hw,
        tasklet_init(&rtlpriv->works.irq_prepare_bcn_tasklet,
                     (void (*)(unsigned long))_rtl_pci_prepare_bcn_tasklet,
                     (unsigned long)hw);
+       tasklet_init(&rtlpriv->works.ips_leave_tasklet,
+                    (void (*)(unsigned long))_rtl_pci_ips_leave_tasklet,
+                    (unsigned long)hw);
 }
 
 static int _rtl_pci_init_tx_ring(struct ieee80211_hw *hw,
@@ -1507,6 +1512,7 @@ static void rtl_pci_deinit(struct ieee80211_hw *hw)
 
        synchronize_irq(rtlpci->pdev->irq);
        tasklet_kill(&rtlpriv->works.irq_tasklet);
+       tasklet_kill(&rtlpriv->works.ips_leave_tasklet);
 
        flush_workqueue(rtlpriv->works.rtl_wq);
        destroy_workqueue(rtlpriv->works.rtl_wq);
@@ -1581,6 +1587,7 @@ static void rtl_pci_stop(struct ieee80211_hw *hw)
        set_hal_stop(rtlhal);
 
        rtlpriv->cfg->ops->disable_interrupt(hw);
+       tasklet_kill(&rtlpriv->works.ips_leave_tasklet);
 
        spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flags);
        while (ppsc->rfchange_inprogress) {
index 39b0297ce925d6625291c91873d2948f42432a4c..d14c13d02177a7157cd73a271054e49c96e28a21 100644 (file)
@@ -68,6 +68,7 @@ bool rtl_ps_disable_nic(struct ieee80211_hw *hw)
 
        /*<2> Disable Interrupt */
        rtlpriv->cfg->ops->disable_interrupt(hw);
+       tasklet_kill(&rtlpriv->works.irq_tasklet);
 
        /*<3> Disable Adapter */
        rtlpriv->cfg->ops->hw_disable(hw);
@@ -82,10 +83,8 @@ bool rtl_ps_set_rf_state(struct ieee80211_hw *hw,
 {
        struct rtl_priv *rtlpriv = rtl_priv(hw);
        struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
-       enum rf_pwrstate rtstate;
        bool actionallowed = false;
        u16 rfwait_cnt = 0;
-       unsigned long flag;
 
        /*protect_or_not = true; */
 
@@ -98,10 +97,9 @@ bool rtl_ps_set_rf_state(struct ieee80211_hw *hw,
         *should wait to be executed.
         */
        while (true) {
-               spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flag);
+               spin_lock(&rtlpriv->locks.rf_ps_lock);
                if (ppsc->rfchange_inprogress) {
-                       spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock,
-                                              flag);
+                       spin_unlock(&rtlpriv->locks.rf_ps_lock);
 
                        RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
                                 ("RF Change in progress!"
@@ -122,15 +120,12 @@ bool rtl_ps_set_rf_state(struct ieee80211_hw *hw,
                        }
                } else {
                        ppsc->rfchange_inprogress = true;
-                       spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock,
-                                              flag);
+                       spin_unlock(&rtlpriv->locks.rf_ps_lock);
                        break;
                }
        }
 
 no_protect:
-       rtstate = ppsc->rfpwr_state;
-
        switch (state_toset) {
        case ERFON:
                ppsc->rfoff_reason &= (~changesource);
@@ -173,9 +168,9 @@ no_protect:
                rtlpriv->cfg->ops->set_rf_power_state(hw, state_toset);
 
        if (!protect_or_not) {
-               spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flag);
+               spin_lock(&rtlpriv->locks.rf_ps_lock);
                ppsc->rfchange_inprogress = false;
-               spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag);
+               spin_unlock(&rtlpriv->locks.rf_ps_lock);
        }
 
        return actionallowed;
@@ -289,12 +284,11 @@ void rtl_ips_nic_on(struct ieee80211_hw *hw)
        struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
        struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
        enum rf_pwrstate rtstate;
-       unsigned long flags;
 
        if (mac->opmode != NL80211_IFTYPE_STATION)
                return;
 
-       spin_lock_irqsave(&rtlpriv->locks.ips_lock, flags);
+       spin_lock(&rtlpriv->locks.ips_lock);
 
        if (ppsc->inactiveps) {
                rtstate = ppsc->rfpwr_state;
@@ -310,7 +304,7 @@ void rtl_ips_nic_on(struct ieee80211_hw *hw)
                }
        }
 
-       spin_unlock_irqrestore(&rtlpriv->locks.ips_lock, flags);
+       spin_unlock(&rtlpriv->locks.ips_lock);
 }
 
 /*for FW LPS*/
@@ -428,7 +422,6 @@ void rtl_lps_enter(struct ieee80211_hw *hw)
        struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
        struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
        struct rtl_priv *rtlpriv = rtl_priv(hw);
-       unsigned long flag;
 
        if (!ppsc->fwctrl_lps)
                return;
@@ -449,7 +442,7 @@ void rtl_lps_enter(struct ieee80211_hw *hw)
        if (mac->link_state != MAC80211_LINKED)
                return;
 
-       spin_lock_irqsave(&rtlpriv->locks.lps_lock, flag);
+       spin_lock(&rtlpriv->locks.lps_lock);
 
        /* Idle for a while if we connect to AP a while ago. */
        if (mac->cnt_after_linked >= 2) {
@@ -461,7 +454,7 @@ void rtl_lps_enter(struct ieee80211_hw *hw)
                }
        }
 
-       spin_unlock_irqrestore(&rtlpriv->locks.lps_lock, flag);
+       spin_unlock(&rtlpriv->locks.lps_lock);
 }
 
 /*Leave the leisure power save mode.*/
@@ -470,9 +463,8 @@ void rtl_lps_leave(struct ieee80211_hw *hw)
        struct rtl_priv *rtlpriv = rtl_priv(hw);
        struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
        struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
-       unsigned long flag;
 
-       spin_lock_irqsave(&rtlpriv->locks.lps_lock, flag);
+       spin_lock(&rtlpriv->locks.lps_lock);
 
        if (ppsc->fwctrl_lps) {
                if (ppsc->dot11_psmode != EACTIVE) {
@@ -493,7 +485,7 @@ void rtl_lps_leave(struct ieee80211_hw *hw)
                        rtl_lps_set_psmode(hw, EACTIVE);
                }
        }
-       spin_unlock_irqrestore(&rtlpriv->locks.lps_lock, flag);
+       spin_unlock(&rtlpriv->locks.lps_lock);
 }
 
 /* For sw LPS*/
@@ -582,7 +574,6 @@ void rtl_swlps_rf_awake(struct ieee80211_hw *hw)
        struct rtl_priv *rtlpriv = rtl_priv(hw);
        struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
        struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
-       unsigned long flag;
 
        if (!rtlpriv->psc.swctrl_lps)
                return;
@@ -595,9 +586,9 @@ void rtl_swlps_rf_awake(struct ieee80211_hw *hw)
                RT_CLEAR_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM);
        }
 
-       spin_lock_irqsave(&rtlpriv->locks.lps_lock, flag);
+       spin_lock(&rtlpriv->locks.lps_lock);
        rtl_ps_set_rf_state(hw, ERFON, RF_CHANGE_BY_PS, false);
-       spin_unlock_irqrestore(&rtlpriv->locks.lps_lock, flag);
+       spin_unlock(&rtlpriv->locks.lps_lock);
 }
 
 void rtl_swlps_rfon_wq_callback(void *data)
@@ -614,7 +605,6 @@ void rtl_swlps_rf_sleep(struct ieee80211_hw *hw)
        struct rtl_priv *rtlpriv = rtl_priv(hw);
        struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
        struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
-       unsigned long flag;
        u8 sleep_intv;
 
        if (!rtlpriv->psc.sw_ps_enabled)
@@ -631,16 +621,16 @@ void rtl_swlps_rf_sleep(struct ieee80211_hw *hw)
        if (rtlpriv->link_info.busytraffic)
                return;
 
-       spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flag);
+       spin_lock(&rtlpriv->locks.rf_ps_lock);
        if (rtlpriv->psc.rfchange_inprogress) {
-               spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag);
+               spin_unlock(&rtlpriv->locks.rf_ps_lock);
                return;
        }
-       spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag);
+       spin_unlock(&rtlpriv->locks.rf_ps_lock);
 
-       spin_lock_irqsave(&rtlpriv->locks.lps_lock, flag);
+       spin_lock(&rtlpriv->locks.lps_lock);
        rtl_ps_set_rf_state(hw, ERFSLEEP, RF_CHANGE_BY_PS, false);
-       spin_unlock_irqrestore(&rtlpriv->locks.lps_lock, flag);
+       spin_unlock(&rtlpriv->locks.lps_lock);
 
        if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM &&
                !RT_IN_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM)) {
index 8f6718f163e5a3d7c86ff5e87cc11264b96174fe..9fedb1f709191638ffd4a35bf96118d094456a92 100644 (file)
@@ -303,22 +303,6 @@ static void _rtl_reg_apply_world_flags(struct wiphy *wiphy,
        return;
 }
 
-static void _rtl_dump_channel_map(struct wiphy *wiphy)
-{
-       enum ieee80211_band band;
-       struct ieee80211_supported_band *sband;
-       struct ieee80211_channel *ch;
-       unsigned int i;
-
-       for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
-               if (!wiphy->bands[band])
-                       continue;
-               sband = wiphy->bands[band];
-               for (i = 0; i < sband->n_channels; i++)
-                       ch = &sband->channels[i];
-       }
-}
-
 static int _rtl_reg_notifier_apply(struct wiphy *wiphy,
                                   struct regulatory_request *request,
                                   struct rtl_regulatory *reg)
@@ -336,8 +320,6 @@ static int _rtl_reg_notifier_apply(struct wiphy *wiphy,
                break;
        }
 
-       _rtl_dump_channel_map(wiphy);
-
        return 0;
 }
 
index 50303e1adff109b6fc73676bf77b3c7632c565fa..f9f2370e9256ea6de048467256bffbd0e4aa2d19 100644 (file)
@@ -546,7 +546,6 @@ static bool _rtl92c_cmd_send_packet(struct ieee80211_hw *hw,
        struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
        struct rtl8192_tx_ring *ring;
        struct rtl_tx_desc *pdesc;
-       u8 own;
        unsigned long flags;
        struct sk_buff *pskb = NULL;
 
@@ -559,7 +558,6 @@ static bool _rtl92c_cmd_send_packet(struct ieee80211_hw *hw,
        spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags);
 
        pdesc = &ring->desc[0];
-       own = (u8) rtlpriv->cfg->ops->get_desc((u8 *) pdesc, true, HW_DESC_OWN);
 
        rtlpriv->cfg->ops->fill_tx_cmddesc(hw, (u8 *) pdesc, 1, 1, skb);
 
index d2cc81586a6a9c95a4b1660b0a377a024ac7fee9..3b11642d3f7dd9d44e038559d543bb5ba35ed6db 100644 (file)
@@ -1253,10 +1253,9 @@ static void _rtl92c_phy_iq_calibrate(struct ieee80211_hw *hw,
 
        const u32 retrycount = 2;
 
-       u32 bbvalue;
-
        if (t == 0) {
-               bbvalue = rtl_get_bbreg(hw, 0x800, MASKDWORD);
+               /* dummy read */
+               rtl_get_bbreg(hw, 0x800, MASKDWORD);
 
                _rtl92c_phy_save_adda_registers(hw, adda_reg,
                                                rtlphy->adda_backup, 16);
@@ -1762,8 +1761,7 @@ void rtl92c_phy_iq_calibrate(struct ieee80211_hw *hw, bool recovery)
        long result[4][8];
        u8 i, final_candidate;
        bool patha_ok, pathb_ok;
-       long reg_e94, reg_e9c, reg_ea4, reg_eac, reg_eb4, reg_ebc, reg_ec4,
-           reg_ecc, reg_tmp = 0;
+       long reg_e94, reg_e9c, reg_ea4, reg_eb4, reg_ebc, reg_ec4, reg_tmp = 0;
        bool is12simular, is13simular, is23simular;
        bool start_conttx = false, singletone = false;
        u32 iqk_bb_reg[10] = {
@@ -1841,21 +1839,17 @@ void rtl92c_phy_iq_calibrate(struct ieee80211_hw *hw, bool recovery)
                reg_e94 = result[i][0];
                reg_e9c = result[i][1];
                reg_ea4 = result[i][2];
-               reg_eac = result[i][3];
                reg_eb4 = result[i][4];
                reg_ebc = result[i][5];
                reg_ec4 = result[i][6];
-               reg_ecc = result[i][7];
        }
        if (final_candidate != 0xff) {
                rtlphy->reg_e94 = reg_e94 = result[final_candidate][0];
                rtlphy->reg_e9c = reg_e9c = result[final_candidate][1];
                reg_ea4 = result[final_candidate][2];
-               reg_eac = result[final_candidate][3];
                rtlphy->reg_eb4 = reg_eb4 = result[final_candidate][4];
                rtlphy->reg_ebc = reg_ebc = result[final_candidate][5];
                reg_ec4 = result[final_candidate][6];
-               reg_ecc = result[final_candidate][7];
                patha_ok = pathb_ok = true;
        } else {
                rtlphy->reg_e94 = rtlphy->reg_eb4 = 0x100;
index defb4370cf74f500c787a8cb93859eaa11271b2a..944f55e9d316724ab86e3727033b5e537655ff43 100644 (file)
@@ -763,11 +763,9 @@ static void _rtl92ce_hw_configure(struct ieee80211_hw *hw)
        struct rtl_priv *rtlpriv = rtl_priv(hw);
        struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
        u8 reg_bw_opmode;
-       u32 reg_ratr, reg_prsr;
+       u32 reg_prsr;
 
        reg_bw_opmode = BW_OPMODE_20MHZ;
-       reg_ratr = RATE_ALL_CCK | RATE_ALL_OFDM_AG |
-           RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS;
        reg_prsr = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
 
        rtl_write_byte(rtlpriv, REG_INIRTS_RATE_SEL, 0x8);
@@ -1196,6 +1194,7 @@ void rtl92ce_disable_interrupt(struct ieee80211_hw *hw)
        rtl_write_dword(rtlpriv, REG_HIMR, IMR8190_DISABLED);
        rtl_write_dword(rtlpriv, REG_HIMRE, IMR8190_DISABLED);
        rtlpci->irq_enabled = false;
+       synchronize_irq(rtlpci->pdev->irq);
 }
 
 static void _rtl92ce_poweroff_adapter(struct ieee80211_hw *hw)
@@ -1969,7 +1968,7 @@ bool rtl92ce_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 *valid)
        struct rtl_priv *rtlpriv = rtl_priv(hw);
        struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
        struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
-       enum rf_pwrstate e_rfpowerstate_toset, cur_rfstate;
+       enum rf_pwrstate e_rfpowerstate_toset;
        u8 u1tmp;
        bool actuallyset = false;
        unsigned long flag;
@@ -1989,8 +1988,6 @@ bool rtl92ce_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 *valid)
                spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag);
        }
 
-       cur_rfstate = ppsc->rfpwr_state;
-
        rtl_write_byte(rtlpriv, REG_MAC_PINMUX_CFG, rtl_read_byte(rtlpriv,
                       REG_MAC_PINMUX_CFG)&~(BIT(3)));
 
index abe0fcc753686fc9ac888bb3b64a176fcd530382..592a10ac59299ba0b243bdbf6ddfd676b4dfcf79 100644 (file)
@@ -46,13 +46,12 @@ u32 rtl92c_phy_query_rf_reg(struct ieee80211_hw *hw,
        struct rtl_priv *rtlpriv = rtl_priv(hw);
        u32 original_value, readback_value, bitshift;
        struct rtl_phy *rtlphy = &(rtlpriv->phy);
-       unsigned long flags;
 
        RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), "
                                               "rfpath(%#x), bitmask(%#x)\n",
                                               regaddr, rfpath, bitmask));
 
-       spin_lock_irqsave(&rtlpriv->locks.rf_lock, flags);
+       spin_lock(&rtlpriv->locks.rf_lock);
 
        if (rtlphy->rf_mode != RF_OP_BY_FW) {
                original_value = _rtl92c_phy_rf_serial_read(hw,
@@ -65,7 +64,7 @@ u32 rtl92c_phy_query_rf_reg(struct ieee80211_hw *hw,
        bitshift = _rtl92c_phy_calculate_bit_shift(bitmask);
        readback_value = (original_value & bitmask) >> bitshift;
 
-       spin_unlock_irqrestore(&rtlpriv->locks.rf_lock, flags);
+       spin_unlock(&rtlpriv->locks.rf_lock);
 
        RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
                 ("regaddr(%#x), rfpath(%#x), "
@@ -120,13 +119,12 @@ void rtl92ce_phy_set_rf_reg(struct ieee80211_hw *hw,
        struct rtl_priv *rtlpriv = rtl_priv(hw);
        struct rtl_phy *rtlphy = &(rtlpriv->phy);
        u32 original_value, bitshift;
-       unsigned long flags;
 
        RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
                 ("regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n",
                  regaddr, bitmask, data, rfpath));
 
-       spin_lock_irqsave(&rtlpriv->locks.rf_lock, flags);
+       spin_lock(&rtlpriv->locks.rf_lock);
 
        if (rtlphy->rf_mode != RF_OP_BY_FW) {
                if (bitmask != RFREG_OFFSET_MASK) {
@@ -153,7 +151,7 @@ void rtl92ce_phy_set_rf_reg(struct ieee80211_hw *hw,
                _rtl92c_phy_fw_rf_serial_write(hw, rfpath, regaddr, data);
        }
 
-       spin_unlock_irqrestore(&rtlpriv->locks.rf_lock, flags);
+       spin_unlock(&rtlpriv->locks.rf_lock);
 
        RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), "
                                               "bitmask(%#x), data(%#x), "
@@ -281,7 +279,6 @@ bool rtl92c_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,
 {
 
        int i;
-       bool rtstatus = true;
        u32 *radioa_array_table;
        u32 *radiob_array_table;
        u16 radioa_arraylen, radiob_arraylen;
@@ -308,7 +305,6 @@ bool rtl92c_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,
                         ("Radio_B:RTL8192CE_RADIOB_1TARRAY\n"));
        }
        RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("Radio No %x\n", rfpath));
-       rtstatus = true;
        switch (rfpath) {
        case RF90_PATH_A:
                for (i = 0; i < radioa_arraylen; i = i + 2) {
@@ -521,7 +517,6 @@ static bool _rtl92ce_phy_set_rf_power_state(struct ieee80211_hw *hw,
        u8 i, queue_id;
        struct rtl8192_tx_ring *ring = NULL;
 
-       ppsc->set_rfpowerstate_inprogress = true;
        switch (rfpwr_state) {
        case ERFON:{
                        if ((ppsc->rfpwr_state == ERFOFF) &&
@@ -617,7 +612,6 @@ static bool _rtl92ce_phy_set_rf_power_state(struct ieee80211_hw *hw,
        }
        if (bresult)
                ppsc->rfpwr_state = rfpwr_state;
-       ppsc->set_rfpowerstate_inprogress = false;
        return bresult;
 }
 
index 54b2bd53d36a5d21dea008ec5af17521aeef275f..2492cc234c03b2ff953af7ed1125793dbb8b6cd4 100644 (file)
@@ -592,7 +592,6 @@ static void _rtl92ce_translate_rx_signal_stuff(struct ieee80211_hw *hw,
        struct ieee80211_hdr *hdr;
        u8 *tmp_buf;
        u8 *praddr;
-       u8 *psaddr;
        __le16 fc;
        u16 type, c_fc;
        bool packet_matchbssid, packet_toself, packet_beacon;
@@ -604,7 +603,6 @@ static void _rtl92ce_translate_rx_signal_stuff(struct ieee80211_hw *hw,
        c_fc = le16_to_cpu(fc);
        type = WLAN_FC_GET_TYPE(fc);
        praddr = hdr->addr1;
-       psaddr = hdr->addr2;
 
        packet_matchbssid =
            ((IEEE80211_FTYPE_CTL != type) &&
@@ -932,6 +930,7 @@ void rtl92ce_set_desc(u8 *pdesc, bool istx, u8 desc_name, u8 *val)
        if (istx == true) {
                switch (desc_name) {
                case HW_DESC_OWN:
+                       wmb();
                        SET_TX_DESC_OWN(pdesc, 1);
                        break;
                case HW_DESC_TX_NEXTDESC_ADDR:
@@ -945,6 +944,7 @@ void rtl92ce_set_desc(u8 *pdesc, bool istx, u8 desc_name, u8 *val)
        } else {
                switch (desc_name) {
                case HW_DESC_RXOWN:
+                       wmb();
                        SET_RX_DESC_OWN(pdesc, 1);
                        break;
                case HW_DESC_RXBUFF_ADDR:
index f8514cba17b602068690548137b9cc5682c7e84c..4e057df6f488309e2e03329c0dc86fff169edb56 100644 (file)
@@ -1113,7 +1113,6 @@ void rtl92c_translate_rx_signal_stuff(struct ieee80211_hw *hw,
        struct ieee80211_hdr *hdr;
        u8 *tmp_buf;
        u8 *praddr;
-       u8 *psaddr;
        __le16 fc;
        u16 type, cpu_fc;
        bool packet_matchbssid, packet_toself, packet_beacon;
@@ -1124,7 +1123,6 @@ void rtl92c_translate_rx_signal_stuff(struct ieee80211_hw *hw,
        cpu_fc = le16_to_cpu(fc);
        type = WLAN_FC_GET_TYPE(fc);
        praddr = hdr->addr1;
-       psaddr = hdr->addr2;
        packet_matchbssid =
            ((IEEE80211_FTYPE_CTL != type) &&
             (!compare_ether_addr(mac->bssid,
index 9a3d0239e27e6ae7aa8b1c8665bba3afcabc3279..72852900df84f4dbcd40d40887ae67a645731816 100644 (file)
@@ -470,7 +470,6 @@ static bool _rtl92cu_phy_set_rf_power_state(struct ieee80211_hw *hw,
        u8 i, queue_id;
        struct rtl8192_tx_ring *ring = NULL;
 
-       ppsc->set_rfpowerstate_inprogress = true;
        switch (rfpwr_state) {
        case ERFON:
                if ((ppsc->rfpwr_state == ERFOFF) &&
@@ -590,7 +589,6 @@ static bool _rtl92cu_phy_set_rf_power_state(struct ieee80211_hw *hw,
        }
        if (bresult)
                ppsc->rfpwr_state = rfpwr_state;
-       ppsc->set_rfpowerstate_inprogress = false;
        return bresult;
 }
 
index da86db86fa4a9ac3c8b6d6692d301343892f4368..609c7ec7e66a2da27635550978d7dd1f36b70fb8 100644 (file)
@@ -222,7 +222,6 @@ static void _rtl92s_dm_refresh_rateadaptive_mask(struct ieee80211_hw *hw)
        u32 low_rssi_thresh = 0;
        u32 middle_rssi_thresh = 0;
        u32 high_rssi_thresh = 0;
-       u8 rssi_level;
        struct ieee80211_sta *sta = NULL;
 
        if (is_hal_stop(rtlhal))
@@ -272,18 +271,14 @@ static void _rtl92s_dm_refresh_rateadaptive_mask(struct ieee80211_hw *hw)
                if (rtlpriv->dm.undecorated_smoothed_pwdb >
                    (long)high_rssi_thresh) {
                        ra->ratr_state = DM_RATR_STA_HIGH;
-                       rssi_level = 1;
                } else if (rtlpriv->dm.undecorated_smoothed_pwdb >
                           (long)middle_rssi_thresh) {
                        ra->ratr_state = DM_RATR_STA_LOW;
-                       rssi_level = 3;
                } else if (rtlpriv->dm.undecorated_smoothed_pwdb >
                           (long)low_rssi_thresh) {
                        ra->ratr_state = DM_RATR_STA_LOW;
-                       rssi_level = 5;
                } else {
                        ra->ratr_state = DM_RATR_STA_ULTRALOW;
-                       rssi_level = 6;
                }
 
                if (ra->pre_ratr_state != ra->ratr_state) {
index 3b5af0113d7f9ad86c5d98515bd733aa95313193..6f91a148c2220ad2f4694c21a4f47e52822912e2 100644 (file)
@@ -358,7 +358,6 @@ int rtl92s_download_fw(struct ieee80211_hw *hw)
        struct fw_priv *pfw_priv = NULL;
        u8 *puc_mappedfile = NULL;
        u32 ul_filelength = 0;
-       u32 file_length = 0;
        u8 fwhdr_size = RT_8192S_FIRMWARE_HDR_SIZE;
        u8 fwstatus = FW_STATUS_INIT;
        bool rtstatus = true;
@@ -370,7 +369,6 @@ int rtl92s_download_fw(struct ieee80211_hw *hw)
        firmware->fwstatus = FW_STATUS_INIT;
 
        puc_mappedfile = firmware->sz_fw_tmpbuffer;
-       file_length = firmware->sz_fw_tmpbufferlen;
 
        /* 1. Retrieve FW header. */
        firmware->pfwheader = (struct fw_hdr *) puc_mappedfile;
index 2e9005d0454bc2f4f45f0d8d7e8647090f3fdfac..35dd12d0dcf3ef371cbe2e99009fbff597d8f7ff 100644 (file)
@@ -884,12 +884,10 @@ static void _rtl92se_hw_configure(struct ieee80211_hw *hw)
        struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
 
        u8 reg_bw_opmode = 0;
-       u32 reg_ratr = 0, reg_rrsr = 0;
+       u32 reg_rrsr = 0;
        u8 regtmp = 0;
 
        reg_bw_opmode = BW_OPMODE_20MHZ;
-       reg_ratr = RATE_ALL_CCK | RATE_ALL_OFDM_AG | RATE_ALL_OFDM_1SS |
-                               RATE_ALL_OFDM_2SS;
        reg_rrsr = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
 
        regtmp = rtl_read_byte(rtlpriv, INIRTSMCS_SEL);
@@ -1122,14 +1120,12 @@ static int _rtl92se_set_media_status(struct ieee80211_hw *hw,
 {
        struct rtl_priv *rtlpriv = rtl_priv(hw);
        u8 bt_msr = rtl_read_byte(rtlpriv, MSR);
-       enum led_ctl_mode ledaction = LED_CTL_NO_LINK;
        u32 temp;
        bt_msr &= ~MSR_LINK_MASK;
 
        switch (type) {
        case NL80211_IFTYPE_UNSPECIFIED:
                bt_msr |= (MSR_LINK_NONE << MSR_LINK_SHIFT);
-               ledaction = LED_CTL_LINK;
                RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
                         ("Set Network type to NO LINK!\n"));
                break;
@@ -1140,7 +1136,6 @@ static int _rtl92se_set_media_status(struct ieee80211_hw *hw,
                break;
        case NL80211_IFTYPE_STATION:
                bt_msr |= (MSR_LINK_MANAGED << MSR_LINK_SHIFT);
-               ledaction = LED_CTL_LINK;
                RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
                         ("Set Network type to STA!\n"));
                break;
@@ -1231,6 +1226,7 @@ void rtl92se_disable_interrupt(struct ieee80211_hw *hw)
        rtl_write_dword(rtlpriv, INTA_MASK + 4, 0);
 
        rtlpci->irq_enabled = false;
+       synchronize_irq(rtlpci->pdev->irq);
 }
 
 
@@ -2271,7 +2267,7 @@ bool rtl92se_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 *valid)
        struct rtl_priv *rtlpriv = rtl_priv(hw);
        struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
        struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
-       enum rf_pwrstate rfpwr_toset, cur_rfstate;
+       enum rf_pwrstate rfpwr_toset /*, cur_rfstate */;
        unsigned long flag = 0;
        bool actuallyset = false;
        bool turnonbypowerdomain = false;
@@ -2292,7 +2288,7 @@ bool rtl92se_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 *valid)
                spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag);
        }
 
-       cur_rfstate = ppsc->rfpwr_state;
+       /* cur_rfstate = ppsc->rfpwr_state;*/
 
        /* because after _rtl92s_phy_set_rfhalt, all power
         * closed, so we must open some power for GPIO check,
index 63b45e60a95e5c6a4a80b64acbac6febc3b26c6d..7ee2daccd7d51811764f9c02e796e8a9bd74e8c2 100644 (file)
@@ -180,19 +180,18 @@ u32 rtl92s_phy_query_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath,
 {
        struct rtl_priv *rtlpriv = rtl_priv(hw);
        u32 original_value, readback_value, bitshift;
-       unsigned long flags;
 
        RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), rfpath(%#x), "
                 "bitmask(%#x)\n", regaddr, rfpath, bitmask));
 
-       spin_lock_irqsave(&rtlpriv->locks.rf_lock, flags);
+       spin_lock(&rtlpriv->locks.rf_lock);
 
        original_value = _rtl92s_phy_rf_serial_read(hw, rfpath, regaddr);
 
        bitshift = _rtl92s_phy_calculate_bit_shift(bitmask);
        readback_value = (original_value & bitmask) >> bitshift;
 
-       spin_unlock_irqrestore(&rtlpriv->locks.rf_lock, flags);
+       spin_unlock(&rtlpriv->locks.rf_lock);
 
        RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), rfpath(%#x), "
                 "bitmask(%#x), original_value(%#x)\n", regaddr, rfpath,
@@ -207,7 +206,6 @@ void rtl92s_phy_set_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath,
        struct rtl_priv *rtlpriv = rtl_priv(hw);
        struct rtl_phy *rtlphy = &(rtlpriv->phy);
        u32 original_value, bitshift;
-       unsigned long flags;
 
        if (!((rtlphy->rf_pathmap >> rfpath) & 0x1))
                return;
@@ -215,7 +213,7 @@ void rtl92s_phy_set_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath,
        RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), bitmask(%#x),"
                 " data(%#x), rfpath(%#x)\n", regaddr, bitmask, data, rfpath));
 
-       spin_lock_irqsave(&rtlpriv->locks.rf_lock, flags);
+       spin_lock(&rtlpriv->locks.rf_lock);
 
        if (bitmask != RFREG_OFFSET_MASK) {
                original_value = _rtl92s_phy_rf_serial_read(hw, rfpath,
@@ -226,7 +224,7 @@ void rtl92s_phy_set_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath,
 
        _rtl92s_phy_rf_serial_write(hw, rfpath, regaddr, data);
 
-       spin_unlock_irqrestore(&rtlpriv->locks.rf_lock, flags);
+       spin_unlock(&rtlpriv->locks.rf_lock);
 
        RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), bitmask(%#x), "
                 "data(%#x), rfpath(%#x)\n", regaddr, bitmask, data, rfpath));
@@ -263,7 +261,6 @@ void rtl92s_phy_set_bw_mode(struct ieee80211_hw *hw,
        struct rtl_phy *rtlphy = &(rtlpriv->phy);
        struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
        u8 reg_bw_opmode;
-       u8 reg_prsr_rsc;
 
        RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, ("Switch to %s bandwidth\n",
                  rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ?
@@ -277,7 +274,8 @@ void rtl92s_phy_set_bw_mode(struct ieee80211_hw *hw,
        rtlphy->set_bwmode_inprogress = true;
 
        reg_bw_opmode = rtl_read_byte(rtlpriv, BW_OPMODE);
-       reg_prsr_rsc = rtl_read_byte(rtlpriv, RRSR + 2);
+       /* dummy read */
+       rtl_read_byte(rtlpriv, RRSR + 2);
 
        switch (rtlphy->current_chan_bw) {
        case HT_CHANNEL_WIDTH_20:
@@ -546,8 +544,6 @@ bool rtl92s_phy_set_rf_power_state(struct ieee80211_hw *hw,
        if (rfpwr_state == ppsc->rfpwr_state)
                return false;
 
-       ppsc->set_rfpowerstate_inprogress = true;
-
        switch (rfpwr_state) {
        case ERFON:{
                        if ((ppsc->rfpwr_state == ERFOFF) &&
@@ -659,8 +655,6 @@ bool rtl92s_phy_set_rf_power_state(struct ieee80211_hw *hw,
        if (bresult)
                ppsc->rfpwr_state = rfpwr_state;
 
-       ppsc->set_rfpowerstate_inprogress = false;
-
        return bresult;
 }
 
index 5cf442373d46e63717949a7c4bb8d06e9aaa7848..d509cf6a1e4df4bfc9f2a4dfb27e4056a1f5b91d 100644 (file)
@@ -581,7 +581,6 @@ static void _rtl92se_translate_rx_signal_stuff(struct ieee80211_hw *hw,
        struct ieee80211_hdr *hdr;
        u8 *tmp_buf;
        u8 *praddr;
-       u8 *psaddr;
        __le16 fc;
        u16 type, cfc;
        bool packet_matchbssid, packet_toself, packet_beacon;
@@ -593,7 +592,6 @@ static void _rtl92se_translate_rx_signal_stuff(struct ieee80211_hw *hw,
        cfc = le16_to_cpu(fc);
        type = WLAN_FC_GET_TYPE(fc);
        praddr = hdr->addr1;
-       psaddr = hdr->addr2;
 
        packet_matchbssid = ((IEEE80211_FTYPE_CTL != type) &&
             (!compare_ether_addr(mac->bssid, (cfc & IEEE80211_FCTL_TODS) ?
@@ -875,6 +873,7 @@ void rtl92se_tx_fill_cmddesc(struct ieee80211_hw *hw, u8 *pdesc,
                SET_TX_DESC_TX_BUFFER_SIZE(pdesc, (u16)(skb->len));
                SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, cpu_to_le32(mapping));
 
+               wmb();
                SET_TX_DESC_OWN(pdesc, 1);
        } else { /* H2C Command Desc format (Host TXCMD) */
                /* 92SE must set as 1 for firmware download HW DMA error */
@@ -893,6 +892,7 @@ void rtl92se_tx_fill_cmddesc(struct ieee80211_hw *hw, u8 *pdesc,
                SET_TX_DESC_TX_BUFFER_SIZE(pdesc, (u16)(skb->len));
                SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, cpu_to_le32(mapping));
 
+               wmb();
                SET_TX_DESC_OWN(pdesc, 1);
 
        }
@@ -903,6 +903,7 @@ void rtl92se_set_desc(u8 *pdesc, bool istx, u8 desc_name, u8 *val)
        if (istx == true) {
                switch (desc_name) {
                case HW_DESC_OWN:
+                       wmb();
                        SET_TX_DESC_OWN(pdesc, 1);
                        break;
                case HW_DESC_TX_NEXTDESC_ADDR:
@@ -916,6 +917,7 @@ void rtl92se_set_desc(u8 *pdesc, bool istx, u8 desc_name, u8 *val)
        } else {
                switch (desc_name) {
                case HW_DESC_RXOWN:
+                       wmb();
                        SET_RX_STATUS_DESC_OWN(pdesc, 1);
                        break;
                case HW_DESC_RXBUFF_ADDR:
index 693395ee98f9d75c1687afb8594c7716878d7907..9d003e0864f53f65a2358be644f400368d64088e 100644 (file)
@@ -1188,7 +1188,6 @@ struct rtl_efuse {
 
 struct rtl_ps_ctl {
        bool pwrdomain_protect;
-       bool set_rfpowerstate_inprogress;
        bool in_powersavemode;
        bool rfchange_inprogress;
        bool swrf_processing;
@@ -1536,6 +1535,7 @@ struct rtl_works {
        /* For SW LPS */
        struct delayed_work ps_work;
        struct delayed_work ps_rfon_wq;
+       struct tasklet_struct ips_leave_tasklet;
 };
 
 struct rtl_debug {
index b07f8b7e5f115eee23e640206c022851209ad3e0..7ccec07a600cb59b97847ef79d7043b74bd965bc 100644 (file)
@@ -485,7 +485,8 @@ static int wl1271_boot_run_firmware(struct wl1271 *wl)
        if (wl->bss_type == BSS_TYPE_AP_BSS)
                wl->event_mask |= STA_REMOVE_COMPLETE_EVENT_ID;
        else
-               wl->event_mask |= DUMMY_PACKET_EVENT_ID;
+               wl->event_mask |= DUMMY_PACKET_EVENT_ID |
+                       BA_SESSION_RX_CONSTRAINT_EVENT_ID;
 
        ret = wl1271_event_unmask(wl);
        if (ret < 0) {
index c3c554cd6580dd63c31dd369c7b3a1e6294b8d20..94bbd00ec31b4ff5ab6d01e250e3c32dec88668f 100644 (file)
@@ -168,6 +168,21 @@ static void wl1271_event_rssi_trigger(struct wl1271 *wl,
        wl->last_rssi_event = event;
 }
 
+static void wl1271_stop_ba_event(struct wl1271 *wl, u8 ba_allowed)
+{
+       /* Convert the value to bool */
+       wl->ba_allowed = !!ba_allowed;
+
+       /*
+        * Return in case:
+        * there are not BA open or the event indication is to allowed BA
+        */
+       if ((!wl->ba_rx_bitmap) || (wl->ba_allowed))
+               return;
+
+       ieee80211_stop_rx_ba_session(wl->vif, wl->ba_rx_bitmap, wl->bssid);
+}
+
 static void wl1271_event_mbox_dump(struct event_mailbox *mbox)
 {
        wl1271_debug(DEBUG_EVENT, "MBOX DUMP:");
@@ -252,6 +267,14 @@ static int wl1271_event_process(struct wl1271 *wl, struct event_mailbox *mbox)
                        wl1271_event_rssi_trigger(wl, mbox);
        }
 
+       if ((vector & BA_SESSION_RX_CONSTRAINT_EVENT_ID) && !is_ap) {
+               wl1271_debug(DEBUG_EVENT, "BA_SESSION_RX_CONSTRAINT_EVENT_ID. "
+                            "ba_allowed = 0x%x", mbox->ba_allowed);
+
+               if (wl->vif)
+                       wl1271_stop_ba_event(wl, mbox->ba_allowed);
+       }
+
        if ((vector & DUMMY_PACKET_EVENT_ID) && !is_ap) {
                wl1271_debug(DEBUG_EVENT, "DUMMY_PACKET_ID_EVENT_ID");
                if (wl->vif)
index b6cf06e565a470aa65c4ab501489821007223ac0..ce99adf4256ea3a7cdcf3b08872f35e9bf7ad479 100644 (file)
@@ -71,7 +71,7 @@ enum {
        HEALTH_CHECK_REPLY_EVENT_ID              = BIT(27),
        PERIODIC_SCAN_COMPLETE_EVENT_ID          = BIT(28),
        PERIODIC_SCAN_REPORT_EVENT_ID            = BIT(29),
-       BA_SESSION_TEAR_DOWN_EVENT_ID            = BIT(30),
+       BA_SESSION_RX_CONSTRAINT_EVENT_ID        = BIT(30),
        EVENT_MBOX_ALL_EVENT_ID                  = 0x7fffffff,
 };
 
@@ -122,7 +122,20 @@ struct event_mailbox {
        __le16 sta_aging_status;
        __le16 sta_tx_retry_exceeded;
 
-       u8 reserved_5[24];
+       /*
+        * Bitmap, Each bit set represents the Role ID for which this constraint
+        * is set. Range: 0 - FF, FF means ANY role
+        */
+       u8 ba_role_id;
+       /*
+        * Bitmap, Each bit set represents the Link ID for which this constraint
+        * is set. Not applicable if ba_role_id is set to ANY role (FF).
+        * Range: 0 - FFFF, FFFF means ANY link in that role
+        */
+       u8 ba_link_id;
+       u8 ba_allowed;
+
+       u8 reserved_5[21];
 } __packed;
 
 int wl1271_event_unmask(struct wl1271 *wl);
index a8f4f156c05555807fbc1f3595db27563abb7e1b..f5c2c9e6f84b10a1b382e4c232f439a752c43af7 100644 (file)
@@ -541,6 +541,7 @@ static int wl1271_set_ba_policies(struct wl1271 *wl)
 
        /* Reset the BA RX indicators */
        wl->ba_rx_bitmap = 0;
+       wl->ba_allowed = true;
 
        /* validate that FW support BA */
        wl1271_check_ba_support(wl);
index e6497dc669df096a57bc914e515b9212c18784c8..f37f0b873c73341c4ca1c03d702a7a774a0d0f12 100644 (file)
@@ -3354,9 +3354,12 @@ static int wl1271_op_ampdu_action(struct ieee80211_hw *hw,
        if (ret < 0)
                goto out;
 
+       wl1271_debug(DEBUG_MAC80211, "mac80211 ampdu: Rx tid %d action %d",
+                    tid, action);
+
        switch (action) {
        case IEEE80211_AMPDU_RX_START:
-               if (wl->ba_support) {
+               if ((wl->ba_support) && (wl->ba_allowed)) {
                        ret = wl1271_acx_set_ba_receiver_session(wl, tid, *ssn,
                                                                 true);
                        if (!ret)
index fbe8f46d123243efe86d6ce3098f176da2c75628..3bc794a1ee75b71cb3730fbe621523577ed9a113 100644 (file)
@@ -564,6 +564,7 @@ struct wl1271 {
        /* RX BA constraint value */
        bool ba_support;
        u8 ba_rx_bitmap;
+       bool ba_allowed;
 
        int tcxo_clock;
 
index 82feb348c8bbf3762195aaf2cf07668792f72721..2a20dabec76d722d1c311aad9e1e34a13382b6d2 100644 (file)
@@ -539,10 +539,12 @@ void ssb_pcicore_init(struct ssb_pcicore *pc)
        if (!pc->hostmode)
                ssb_pcicore_init_clientmode(pc);
 
-       /* Additional always once-executed workarounds */
-       ssb_pcicore_serdes_workaround(pc);
-       /* TODO: ASPM */
-       /* TODO: Clock Request Update */
+       /* Additional PCIe always once-executed workarounds */
+       if (dev->id.coreid == SSB_DEV_PCIE) {
+               ssb_pcicore_serdes_workaround(pc);
+               /* TODO: ASPM */
+               /* TODO: Clock Request Update */
+       }
 }
 
 static u32 ssb_pcie_read(struct ssb_pcicore *pc, u32 address)
index 08763e4e848f763d6a345f0f925add947ea4c12e..6ff080eac0b21e403100c85c6141f67d3811fbeb 100644 (file)
@@ -6,6 +6,7 @@
 
 #include <linux/bcma/bcma_driver_chipcommon.h>
 #include <linux/bcma/bcma_driver_pci.h>
+#include <linux/ssb/ssb.h> /* SPROM sharing */
 
 #include "bcma_regs.h"
 
@@ -31,6 +32,12 @@ struct bcma_host_ops {
        void (*write8)(struct bcma_device *core, u16 offset, u8 value);
        void (*write16)(struct bcma_device *core, u16 offset, u16 value);
        void (*write32)(struct bcma_device *core, u16 offset, u32 value);
+#ifdef CONFIG_BCMA_BLOCKIO
+       void (*block_read)(struct bcma_device *core, void *buffer,
+                          size_t count, u16 offset, u8 reg_width);
+       void (*block_write)(struct bcma_device *core, const void *buffer,
+                           size_t count, u16 offset, u8 reg_width);
+#endif
        /* Agent ops */
        u32 (*aread32)(struct bcma_device *core, u16 offset);
        void (*awrite32)(struct bcma_device *core, u16 offset, u32 value);
@@ -117,6 +124,8 @@ struct bcma_device {
        struct bcma_device_id id;
 
        struct device dev;
+       struct device *dma_dev;
+       unsigned int irq;
        bool dev_registered;
 
        u8 core_index;
@@ -179,6 +188,10 @@ struct bcma_bus {
 
        struct bcma_drv_cc drv_cc;
        struct bcma_drv_pci drv_pci;
+
+       /* We decided to share SPROM struct with SSB as long as we do not need
+        * any hacks for BCMA. This simplifies drivers code. */
+       struct ssb_sprom sprom;
 };
 
 extern inline u32 bcma_read8(struct bcma_device *core, u16 offset)
@@ -208,6 +221,18 @@ void bcma_write32(struct bcma_device *core, u16 offset, u32 value)
 {
        core->bus->ops->write32(core, offset, value);
 }
+#ifdef CONFIG_BCMA_BLOCKIO
+extern inline void bcma_block_read(struct bcma_device *core, void *buffer,
+                                  size_t count, u16 offset, u8 reg_width)
+{
+       core->bus->ops->block_read(core, buffer, count, offset, reg_width);
+}
+extern inline void bcma_block_write(struct bcma_device *core, const void *buffer,
+                                   size_t count, u16 offset, u8 reg_width)
+{
+       core->bus->ops->block_write(core, buffer, count, offset, reg_width);
+}
+#endif
 extern inline u32 bcma_aread32(struct bcma_device *core, u16 offset)
 {
        return core->bus->ops->aread32(core, offset);
index 083c3b6cd5ce71e64c369bc9472ad2dfca4e2ba4..9c5b69fc985a1fbfb3e6d44e3afe9209c5f2aaef 100644 (file)
 #define BCMA_CC_REGCTL_DATA            0x065C
 #define BCMA_CC_PLLCTL_ADDR            0x0660
 #define BCMA_CC_PLLCTL_DATA            0x0664
+#define BCMA_CC_SPROM                  0x0830 /* SPROM beginning */
 
 /* Data for the PMU, if available.
  * Check availability with ((struct bcma_chipcommon)->capabilities & BCMA_CC_CAP_PMU)
diff --git a/include/linux/cordic.h b/include/linux/cordic.h
new file mode 100644 (file)
index 0000000..f932093
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2011 Broadcom Corporation
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+#ifndef __CORDIC_H_
+#define __CORDIC_H_
+
+#include <linux/types.h>
+
+/**
+ * struct cordic_iq - i/q coordinate.
+ *
+ * @i: real part of coordinate (in phase).
+ * @q: imaginary part of coordinate (quadrature).
+ */
+struct cordic_iq {
+       s32 i;
+       s32 q;
+};
+
+/**
+ * cordic_calc_iq() - calculates the i/q coordinate for given angle.
+ *
+ * @theta: angle in degrees for which i/q coordinate is to be calculated.
+ * @coord: function output parameter holding the i/q coordinate.
+ *
+ * The function calculates the i/q coordinate for a given angle using
+ * cordic algorithm. The coordinate consists of a real (i) and an
+ * imaginary (q) part. The real part is essentially the cosine of the
+ * angle and the imaginary part is the sine of the angle. The returned
+ * values are scaled by 2^16 for precision. The range for theta is
+ * for -180 degrees to +180 degrees. Passed values outside this range are
+ * converted before doing the actual calculation.
+ */
+struct cordic_iq cordic_calc_iq(s32 theta);
+
+#endif /* __CORDIC_H_ */
diff --git a/include/linux/crc8.h b/include/linux/crc8.h
new file mode 100644 (file)
index 0000000..13c8dab
--- /dev/null
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2011 Broadcom Corporation
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+#ifndef __CRC8_H_
+#define __CRC8_H_
+
+#include <linux/types.h>
+
+/* see usage of this value in crc8() description */
+#define CRC8_INIT_VALUE                0xFF
+
+/*
+ * Return value of crc8() indicating valid message+crc. This is true
+ * if a CRC is inverted before transmission. The CRC computed over the
+ * whole received bitstream is _table[x], where x is the bit pattern
+ * of the modification (almost always 0xff).
+ */
+#define CRC8_GOOD_VALUE(_table)        (_table[0xFF])
+
+/* required table size for crc8 algorithm */
+#define CRC8_TABLE_SIZE                        256
+
+/* helper macro assuring right table size is used */
+#define DECLARE_CRC8_TABLE(_table) \
+       static u8 _table[CRC8_TABLE_SIZE]
+
+/**
+ * crc8_populate_lsb - fill crc table for given polynomial in regular bit order.
+ *
+ * @table:     table to be filled.
+ * @polynomial:        polynomial for which table is to be filled.
+ *
+ * This function fills the provided table according the polynomial provided for
+ * regular bit order (lsb first). Polynomials in CRC algorithms are typically
+ * represented as shown below.
+ *
+ *     poly = x^8 + x^7 + x^6 + x^4 + x^2 + 1
+ *
+ * For lsb first direction x^7 maps to the lsb. So the polynomial is as below.
+ *
+ * - lsb first: poly = 10101011(1) = 0xAB
+ */
+void crc8_populate_lsb(u8 table[CRC8_TABLE_SIZE], u8 polynomial);
+
+/**
+ * crc8_populate_msb - fill crc table for given polynomial in reverse bit order.
+ *
+ * @table:     table to be filled.
+ * @polynomial:        polynomial for which table is to be filled.
+ *
+ * This function fills the provided table according the polynomial provided for
+ * reverse bit order (msb first). Polynomials in CRC algorithms are typically
+ * represented as shown below.
+ *
+ *     poly = x^8 + x^7 + x^6 + x^4 + x^2 + 1
+ *
+ * For msb first direction x^7 maps to the msb. So the polynomial is as below.
+ *
+ * - msb first: poly = (1)11010101 = 0xD5
+ */
+void crc8_populate_msb(u8 table[CRC8_TABLE_SIZE], u8 polynomial);
+
+/**
+ * crc8() - calculate a crc8 over the given input data.
+ *
+ * @table:     crc table used for calculation.
+ * @pdata:     pointer to data buffer.
+ * @nbytes:    number of bytes in data buffer.
+ * @crc:       previous returned crc8 value.
+ *
+ * The CRC8 is calculated using the polynomial given in crc8_populate_msb()
+ * or crc8_populate_lsb().
+ *
+ * The caller provides the initial value (either %CRC8_INIT_VALUE
+ * or the previous returned value) to allow for processing of
+ * discontiguous blocks of data.  When generating the CRC the
+ * caller is responsible for complementing the final return value
+ * and inserting it into the byte stream.  When validating a byte
+ * stream (including CRC8), a final return value of %CRC8_GOOD_VALUE
+ * indicates the byte stream data can be considered valid.
+ *
+ * Reference:
+ * "A Painless Guide to CRC Error Detection Algorithms", ver 3, Aug 1993
+ * Williams, Ross N., ross<at>ross.net
+ * (see URL http://www.ross.net/crc/download/crc_v3.txt).
+ */
+u8 crc8(const u8 table[CRC8_TABLE_SIZE], u8 *pdata, size_t nbytes, u8 crc);
+
+#endif /* __CRC8_H_ */
index 0589f554788aea2dd5dc28c9a372ee10637e3eb6..6cb2543a2ee14ff6521fd24d62f73cf1a6776167 100644 (file)
@@ -1284,6 +1284,12 @@ struct cfg80211_wowlan {
  *     frame on another channel
  *
  * @testmode_cmd: run a test mode command
+ * @testmode_dump: Implement a test mode dump. The cb->args[2] and up may be
+ *     used by the function, but 0 and 1 must not be touched. Additionally,
+ *     return error codes other than -ENOBUFS and -ENOENT will terminate the
+ *     dump and return to userspace with an error, so be careful. If any data
+ *     was passed in from userspace then the data/len arguments will be present
+ *     and point to the data contained in %NL80211_ATTR_TESTDATA.
  *
  * @set_bitrate_mask: set the bitrate mask configuration
  *
@@ -1433,6 +1439,9 @@ struct cfg80211_ops {
 
 #ifdef CONFIG_NL80211_TESTMODE
        int     (*testmode_cmd)(struct wiphy *wiphy, void *data, int len);
+       int     (*testmode_dump)(struct wiphy *wiphy, struct sk_buff *skb,
+                                struct netlink_callback *cb,
+                                void *data, int len);
 #endif
 
        int     (*set_bitrate_mask)(struct wiphy *wiphy,
@@ -2849,8 +2858,10 @@ struct sk_buff *cfg80211_testmode_alloc_event_skb(struct wiphy *wiphy,
 void cfg80211_testmode_event(struct sk_buff *skb, gfp_t gfp);
 
 #define CFG80211_TESTMODE_CMD(cmd)     .testmode_cmd = (cmd),
+#define CFG80211_TESTMODE_DUMP(cmd)    .testmode_dump = (cmd),
 #else
 #define CFG80211_TESTMODE_CMD(cmd)
+#define CFG80211_TESTMODE_DUMP(cmd)
 #endif
 
 /**
index e6d6a66a8f715a48d741a2331576fef7ea614ec8..3b31ec95dd8e938df43f4478cdd0e455eba09776 100644 (file)
@@ -1816,6 +1816,7 @@ enum ieee80211_ampdu_mlme_action {
  *
  * @testmode_cmd: Implement a cfg80211 test mode command.
  *     The callback can sleep.
+ * @testmode_dump: Implement a cfg80211 test mode dump. The callback can sleep.
  *
  * @flush: Flush all pending frames from the hardware queue, making sure
  *     that the hardware queues are empty. If the parameter @drop is set
@@ -1936,6 +1937,9 @@ struct ieee80211_ops {
        void (*set_coverage_class)(struct ieee80211_hw *hw, u8 coverage_class);
 #ifdef CONFIG_NL80211_TESTMODE
        int (*testmode_cmd)(struct ieee80211_hw *hw, void *data, int len);
+       int (*testmode_dump)(struct ieee80211_hw *hw, struct sk_buff *skb,
+                            struct netlink_callback *cb,
+                            void *data, int len);
 #endif
        void (*flush)(struct ieee80211_hw *hw, bool drop);
        void (*channel_switch)(struct ieee80211_hw *hw,
@@ -2965,6 +2969,23 @@ void ieee80211_ready_on_channel(struct ieee80211_hw *hw);
  */
 void ieee80211_remain_on_channel_expired(struct ieee80211_hw *hw);
 
+/**
+ * ieee80211_stop_rx_ba_session - callback to stop existing BA sessions
+ *
+ * in order not to harm the system performance and user experience, the device
+ * may request not to allow any rx ba session and tear down existing rx ba
+ * sessions based on system constraints such as periodic BT activity that needs
+ * to limit wlan activity (eg.sco or a2dp)."
+ * in such cases, the intention is to limit the duration of the rx ppdu and
+ * therefore prevent the peer device to use a-mpdu aggregation.
+ *
+ * @vif: &struct ieee80211_vif pointer from the add_interface callback.
+ * @ba_rx_bitmap: Bit map of open rx ba per tid
+ * @addr: & to bssid mac address
+ */
+void ieee80211_stop_rx_ba_session(struct ieee80211_vif *vif, u16 ba_rx_bitmap,
+                                 const u8 *addr);
+
 /* Rate control API */
 
 /**
index 830181cc7a83b3a7fa5d6898d6b83461a118fe92..32f3e5ae2be543c59ae3e50682ca504010eb87a3 100644 (file)
@@ -79,6 +79,13 @@ config LIBCRC32C
          require M here.  See Castagnoli93.
          Module will be libcrc32c.
 
+config CRC8
+       tristate "CRC8 function"
+       help
+         This option provides CRC8 function. Drivers may select this
+         when they need to do cyclic redundancy check according CRC8
+         algorithm. Module will be called crc8.
+
 config AUDIT_GENERIC
        bool
        depends on AUDIT && !AUDIT_ARCH
@@ -262,4 +269,11 @@ config AVERAGE
 
          If unsure, say N.
 
+config CORDIC
+       tristate "Cordic function"
+       help
+         The option provides arithmetic function using cordic algorithm
+         so its calculations are in fixed point. Modules can select this
+         when they require this function. Module will be called cordic.
+
 endmenu
index 6b597fdb1898c9a132dde2a343e9ec8fa2a5f1bf..892f4e282ea1c0aecf8a60c33ec8c6bde2d2c175 100644 (file)
@@ -61,6 +61,7 @@ obj-$(CONFIG_CRC_ITU_T)       += crc-itu-t.o
 obj-$(CONFIG_CRC32)    += crc32.o
 obj-$(CONFIG_CRC7)     += crc7.o
 obj-$(CONFIG_LIBCRC32C)        += libcrc32c.o
+obj-$(CONFIG_CRC8)     += crc8.o
 obj-$(CONFIG_GENERIC_ALLOCATOR) += genalloc.o
 
 obj-$(CONFIG_ZLIB_INFLATE) += zlib_inflate/
@@ -112,6 +113,8 @@ obj-$(CONFIG_AVERAGE) += average.o
 
 obj-$(CONFIG_CPU_RMAP) += cpu_rmap.o
 
+obj-$(CONFIG_CORDIC) += cordic.o
+
 hostprogs-y    := gen_crc32table
 clean-files    := crc32table.h
 
diff --git a/lib/cordic.c b/lib/cordic.c
new file mode 100644 (file)
index 0000000..aa27a88
--- /dev/null
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2011 Broadcom Corporation
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+#include <linux/module.h>
+#include <linux/cordic.h>
+
+#define CORDIC_ANGLE_GEN       39797
+#define CORDIC_PRECISION_SHIFT 16
+#define        CORDIC_NUM_ITER         (CORDIC_PRECISION_SHIFT + 2)
+
+#define        FIXED(X)        ((s32)((X) << CORDIC_PRECISION_SHIFT))
+#define        FLOAT(X)        (((X) >= 0) \
+               ? ((((X) >> (CORDIC_PRECISION_SHIFT - 1)) + 1) >> 1) \
+               : -((((-(X)) >> (CORDIC_PRECISION_SHIFT - 1)) + 1) >> 1))
+
+static const s32 arctan_table[] = {
+       2949120,
+       1740967,
+       919879,
+       466945,
+       234379,
+       117304,
+       58666,
+       29335,
+       14668,
+       7334,
+       3667,
+       1833,
+       917,
+       458,
+       229,
+       115,
+       57,
+       29
+};
+
+/*
+ * cordic_calc_iq() - calculates the i/q coordinate for given angle
+ *
+ * theta: angle in degrees for which i/q coordinate is to be calculated
+ * coord: function output parameter holding the i/q coordinate
+ */
+struct cordic_iq cordic_calc_iq(s32 theta)
+{
+       struct cordic_iq coord;
+       s32 angle, valtmp;
+       unsigned iter;
+       int signx = 1;
+       int signtheta;
+
+       coord.i = CORDIC_ANGLE_GEN;
+       coord.q = 0;
+       angle = 0;
+
+       theta = FIXED(theta);
+       signtheta = (theta < 0) ? -1 : 1;
+       theta = ((theta + FIXED(180) * signtheta) % FIXED(360)) -
+               FIXED(180) * signtheta;
+
+       if (FLOAT(theta) > 90) {
+               theta -= FIXED(180);
+               signx = -1;
+       } else if (FLOAT(theta) < -90) {
+               theta += FIXED(180);
+               signx = -1;
+       }
+
+       for (iter = 0; iter < CORDIC_NUM_ITER; iter++) {
+               if (theta > angle) {
+                       valtmp = coord.i - (coord.q >> iter);
+                       coord.q += (coord.i >> iter);
+                       angle += arctan_table[iter];
+               } else {
+                       valtmp = coord.i + (coord.q >> iter);
+                       coord.q -= (coord.i >> iter);
+                       angle -= arctan_table[iter];
+               }
+               coord.i = valtmp;
+       }
+
+       coord.i *= signx;
+       coord.q *= signx;
+       return coord;
+}
+EXPORT_SYMBOL(cordic_calc_iq);
+
+MODULE_DESCRIPTION("Cordic functions");
+MODULE_AUTHOR("Broadcom Corporation");
+MODULE_LICENSE("Dual BSD/GPL");
diff --git a/lib/crc8.c b/lib/crc8.c
new file mode 100644 (file)
index 0000000..87b59ca
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2011 Broadcom Corporation
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#define pr_fmt(fmt)            KBUILD_MODNAME ": " fmt
+
+#include <linux/module.h>
+#include <linux/crc8.h>
+#include <linux/printk.h>
+
+/*
+ * crc8_populate_msb - fill crc table for given polynomial in reverse bit order.
+ *
+ * table:      table to be filled.
+ * polynomial: polynomial for which table is to be filled.
+ */
+void crc8_populate_msb(u8 table[CRC8_TABLE_SIZE], u8 polynomial)
+{
+       int i, j;
+       const u8 msbit = 0x80;
+       u8 t = msbit;
+
+       table[0] = 0;
+
+       for (i = 1; i < CRC8_TABLE_SIZE; i *= 2) {
+               t = (t << 1) ^ (t & msbit ? polynomial : 0);
+               for (j = 0; j < i; j++)
+                       table[i+j] = table[j] ^ t;
+       }
+}
+EXPORT_SYMBOL(crc8_populate_msb);
+
+/*
+ * crc8_populate_lsb - fill crc table for given polynomial in regular bit order.
+ *
+ * table:      table to be filled.
+ * polynomial: polynomial for which table is to be filled.
+ */
+void crc8_populate_lsb(u8 table[CRC8_TABLE_SIZE], u8 polynomial)
+{
+       int i, j;
+       u8 t = 1;
+
+       table[0] = 0;
+
+       for (i = (CRC8_TABLE_SIZE >> 1); i; i >>= 1) {
+               t = (t >> 1) ^ (t & 1 ? polynomial : 0);
+               for (j = 0; j < CRC8_TABLE_SIZE; j += 2*i)
+                       table[i+j] = table[j] ^ t;
+       }
+}
+EXPORT_SYMBOL(crc8_populate_lsb);
+
+/*
+ * crc8 - calculate a crc8 over the given input data.
+ *
+ * table: crc table used for calculation.
+ * pdata: pointer to data buffer.
+ * nbytes: number of bytes in data buffer.
+ * crc:        previous returned crc8 value.
+ */
+u8 crc8(const u8 table[CRC8_TABLE_SIZE], u8 *pdata, size_t nbytes, u8 crc)
+{
+       /* loop over the buffer data */
+       while (nbytes-- > 0)
+               crc = table[(crc ^ *pdata++) & 0xff];
+
+       return crc;
+}
+EXPORT_SYMBOL(crc8);
+
+MODULE_DESCRIPTION("CRC8 (by Williams, Ross N.) function");
+MODULE_AUTHOR("Broadcom Corporation");
+MODULE_LICENSE("Dual BSD/GPL");
index 9c0d76cdca920ed3b322c4b70ed86f044b4a404b..89b0b2ca6db673978057ae8754e3a6f0af10963b 100644 (file)
@@ -100,6 +100,21 @@ void __ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid,
        mutex_unlock(&sta->ampdu_mlme.mtx);
 }
 
+void ieee80211_stop_rx_ba_session(struct ieee80211_vif *vif, u16 ba_rx_bitmap,
+                                 const u8 *addr)
+{
+       struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
+       struct sta_info *sta = sta_info_get(sdata, addr);
+       int i;
+
+       for (i = 0; i < STA_TID_NUM; i++)
+               if (ba_rx_bitmap & BIT(i))
+                       set_bit(i, sta->ampdu_mlme.tid_rx_stop_requested);
+
+       ieee80211_queue_work(&sta->local->hw, &sta->ampdu_mlme.work);
+}
+EXPORT_SYMBOL(ieee80211_stop_rx_ba_session);
+
 /*
  * After accepting the AddBA Request we activated a timer,
  * resetting it after each frame that arrives from the originator.
index be70c70d3f5bfa6ecfb57e56d3b12eb06e6f78e9..6e56c6ee7ccd866fd16f2272467f315579b9fd34 100644 (file)
@@ -1554,6 +1554,19 @@ static int ieee80211_testmode_cmd(struct wiphy *wiphy, void *data, int len)
 
        return local->ops->testmode_cmd(&local->hw, data, len);
 }
+
+static int ieee80211_testmode_dump(struct wiphy *wiphy,
+                                  struct sk_buff *skb,
+                                  struct netlink_callback *cb,
+                                  void *data, int len)
+{
+       struct ieee80211_local *local = wiphy_priv(wiphy);
+
+       if (!local->ops->testmode_dump)
+               return -EOPNOTSUPP;
+
+       return local->ops->testmode_dump(&local->hw, skb, cb, data, len);
+}
 #endif
 
 int __ieee80211_request_smps(struct ieee80211_sub_if_data *sdata,
@@ -2134,6 +2147,7 @@ struct cfg80211_ops mac80211_config_ops = {
        .set_wds_peer = ieee80211_set_wds_peer,
        .rfkill_poll = ieee80211_rfkill_poll,
        CFG80211_TESTMODE_CMD(ieee80211_testmode_cmd)
+       CFG80211_TESTMODE_DUMP(ieee80211_testmode_dump)
        .set_power_mgmt = ieee80211_set_power_mgmt,
        .set_bitrate_mask = ieee80211_set_bitrate_mask,
        .remain_on_channel = ieee80211_remain_on_channel,
index 591add22bcc07e178fe3ffe6215aa2cf84fcf7cc..7cfc286946c07db43e5b41b0705f827f9551f59b 100644 (file)
@@ -140,6 +140,12 @@ void ieee80211_ba_session_work(struct work_struct *work)
                                sta, tid, WLAN_BACK_RECIPIENT,
                                WLAN_REASON_QSTA_TIMEOUT, true);
 
+               if (test_and_clear_bit(tid,
+                                      sta->ampdu_mlme.tid_rx_stop_requested))
+                       ___ieee80211_stop_rx_ba_session(
+                               sta, tid, WLAN_BACK_RECIPIENT,
+                               WLAN_REASON_UNSPECIFIED, true);
+
                tid_tx = sta->ampdu_mlme.tid_start_tx[tid];
                if (tid_tx) {
                        /*
index 2025af52b195647a3e83794ae090b8ca84a7cdfa..090b0ec1e05653c246973a74de8fe4c6057f261e 100644 (file)
@@ -775,9 +775,6 @@ struct ieee80211_local {
 
        int tx_headroom; /* required headroom for hardware/radiotap */
 
-       /* count for keys needing tailroom space allocation */
-       int crypto_tx_tailroom_needed_cnt;
-
        /* Tasklet and skb queue to process calls from IRQ mode. All frames
         * added to skb_queue will be processed, but frames in
         * skb_queue_unreliable may be dropped if the total length of these
index 49d4f869e0bc74cfcd397558b2283440da761c1d..dee30aea9ab31eba7021812894c35d495e28ab71 100644 (file)
@@ -1145,6 +1145,10 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name,
                                + IEEE80211_ENCRYPT_HEADROOM;
        ndev->needed_tailroom = IEEE80211_ENCRYPT_TAILROOM;
 
+       ret = dev_alloc_name(ndev, ndev->name);
+       if (ret < 0)
+               goto fail;
+
        ieee80211_assign_perm_addr(local, ndev, type);
        memcpy(ndev->dev_addr, ndev->perm_addr, ETH_ALEN);
        SET_NETDEV_DEV(ndev, wiphy_dev(local->hw.wiphy));
index 31afd712930df2a7507505a26cd24f4f4e1ee2bd..f825e2f0a57e034a839f37bfafc19e12206367b9 100644 (file)
@@ -101,11 +101,6 @@ static int ieee80211_key_enable_hw_accel(struct ieee80211_key *key)
 
        if (!ret) {
                key->flags |= KEY_FLAG_UPLOADED_TO_HARDWARE;
-
-               if (!((key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIC) ||
-                     (key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV)))
-                       key->local->crypto_tx_tailroom_needed_cnt--;
-
                return 0;
        }
 
@@ -161,10 +156,6 @@ static void ieee80211_key_disable_hw_accel(struct ieee80211_key *key)
                          key->conf.keyidx, sta ? sta->addr : bcast_addr, ret);
 
        key->flags &= ~KEY_FLAG_UPLOADED_TO_HARDWARE;
-
-       if (!((key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIC) ||
-             (key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV)))
-               key->local->crypto_tx_tailroom_needed_cnt++;
 }
 
 void ieee80211_key_removed(struct ieee80211_key_conf *key_conf)
@@ -403,10 +394,8 @@ static void __ieee80211_key_destroy(struct ieee80211_key *key)
                ieee80211_aes_key_free(key->u.ccmp.tfm);
        if (key->conf.cipher == WLAN_CIPHER_SUITE_AES_CMAC)
                ieee80211_aes_cmac_key_free(key->u.aes_cmac.tfm);
-       if (key->local) {
+       if (key->local)
                ieee80211_debugfs_key_remove(key);
-               key->local->crypto_tx_tailroom_needed_cnt--;
-       }
 
        kfree(key);
 }
@@ -468,8 +457,6 @@ int ieee80211_key_link(struct ieee80211_key *key,
 
        ieee80211_debugfs_key_add(key);
 
-       key->local->crypto_tx_tailroom_needed_cnt++;
-
        ret = ieee80211_key_enable_hw_accel(key);
 
        mutex_unlock(&sdata->local->key_mtx);
@@ -511,12 +498,8 @@ void ieee80211_enable_keys(struct ieee80211_sub_if_data *sdata)
 
        mutex_lock(&sdata->local->key_mtx);
 
-       sdata->local->crypto_tx_tailroom_needed_cnt = 0;
-
-       list_for_each_entry(key, &sdata->key_list, list) {
-               sdata->local->crypto_tx_tailroom_needed_cnt++;
+       list_for_each_entry(key, &sdata->key_list, list)
                ieee80211_key_enable_hw_accel(key);
-       }
 
        mutex_unlock(&sdata->local->key_mtx);
 }
index 8adac67395f7802445df4d64f622b3a34b5a750d..58a89554b7882cc940ad6f7dce624c786e7f5c83 100644 (file)
@@ -532,12 +532,21 @@ minstrel_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir)
        mp->hw = hw;
        mp->update_interval = 100;
 
+#ifdef CONFIG_MAC80211_DEBUGFS
+       mp->fixed_rate_idx = (u32) -1;
+       mp->dbg_fixed_rate = debugfs_create_u32("fixed_rate_idx",
+                       S_IRUGO | S_IWUGO, debugfsdir, &mp->fixed_rate_idx);
+#endif
+
        return mp;
 }
 
 static void
 minstrel_free(void *priv)
 {
+#ifdef CONFIG_MAC80211_DEBUGFS
+       debugfs_remove(((struct minstrel_priv *)priv)->dbg_fixed_rate);
+#endif
        kfree(priv);
 }
 
index 0f5a83370aa637f18f854c7469cc21e8a491257c..5d278eccaef0722927448b63d31566260e416a90 100644 (file)
@@ -78,6 +78,18 @@ struct minstrel_priv {
        unsigned int update_interval;
        unsigned int lookaround_rate;
        unsigned int lookaround_rate_mrr;
+
+#ifdef CONFIG_MAC80211_DEBUGFS
+       /*
+        * enable fixed rate processing per RC
+        *   - write static index to debugfs:ieee80211/phyX/rc/fixed_rate_idx
+        *   - write -1 to enable RC processing again
+        *   - setting will be applied on next update
+        */
+       u32 fixed_rate_idx;
+       struct dentry *dbg_fixed_rate;
+#endif
+
 };
 
 struct minstrel_debugfs_info {
index 333b5118be6d54472e349bbce059a13eda5f418b..66a1eeb279c697f1fc11f0bc0ef17f5fbcd0d40b 100644 (file)
@@ -609,6 +609,13 @@ minstrel_ht_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta,
 
        info->flags |= mi->tx_flags;
        sample_idx = minstrel_get_sample_rate(mp, mi);
+
+#ifdef CONFIG_MAC80211_DEBUGFS
+       /* use fixed index if set */
+       if (mp->fixed_rate_idx != -1)
+               sample_idx = mp->fixed_rate_idx;
+#endif
+
        if (sample_idx >= 0) {
                sample = true;
                minstrel_ht_set_rate(mp, mi, &ar[0], sample_idx,
index c6ae8718bd571f5d37ab7687d5894056d1b35837..a06d64ebc1776bba755454d58a33e255eb5ebb56 100644 (file)
@@ -158,6 +158,8 @@ struct tid_ampdu_rx {
  * @work: work struct for starting/stopping aggregation
  * @tid_rx_timer_expired: bitmap indicating on which TIDs the
  *     RX timer expired until the work for it runs
+ * @tid_rx_stop_requested:  bitmap indicating which BA sessions per TID the
+ *     driver requested to close until the work for it runs
  * @mtx: mutex to protect all TX data (except non-NULL assignments
  *     to tid_tx[idx], which are protected by the sta spinlock)
  */
@@ -166,6 +168,7 @@ struct sta_ampdu_mlme {
        /* rx */
        struct tid_ampdu_rx __rcu *tid_rx[STA_TID_NUM];
        unsigned long tid_rx_timer_expired[BITS_TO_LONGS(STA_TID_NUM)];
+       unsigned long tid_rx_stop_requested[BITS_TO_LONGS(STA_TID_NUM)];
        /* tx */
        struct work_struct work;
        struct tid_ampdu_tx __rcu *tid_tx[STA_TID_NUM];
index 64e0f7587e6d6f09e11a8029ef7a995e406ff60d..3104c844b544c5465ef5ba1e7efcff05ca920501 100644 (file)
@@ -1480,7 +1480,12 @@ static int ieee80211_skb_resize(struct ieee80211_local *local,
 {
        int tail_need = 0;
 
-       if (may_encrypt && local->crypto_tx_tailroom_needed_cnt) {
+       /*
+        * This could be optimised, devices that do full hardware
+        * crypto (including TKIP MMIC) need no tailroom... But we
+        * have no drivers for such devices currently.
+        */
+       if (may_encrypt) {
                tail_need = IEEE80211_ENCRYPT_TAILROOM;
                tail_need -= skb_tailroom(skb);
                tail_need = max_t(int, tail_need, 0);
index 88a565f130a5a2e2e0f72fca3c204505a810a652..70cbc8ca371e73aa3a8cf58058a3df2b285ab659 100644 (file)
@@ -3754,10 +3754,6 @@ static int nl80211_send_survey(struct sk_buff *msg, u32 pid, u32 seq,
        void *hdr;
        struct nlattr *infoattr;
 
-       /* Survey without a channel doesn't make sense */
-       if (!survey->channel)
-               return -EINVAL;
-
        hdr = nl80211hdr_put(msg, pid, seq, flags,
                             NL80211_CMD_NEW_SURVEY_RESULTS);
        if (!hdr)
@@ -3820,6 +3816,8 @@ static int nl80211_dump_survey(struct sk_buff *skb,
        }
 
        while (1) {
+               struct ieee80211_channel *chan;
+
                res = dev->ops->dump_survey(&dev->wiphy, netdev, survey_idx,
                                            &survey);
                if (res == -ENOENT)
@@ -3827,6 +3825,19 @@ static int nl80211_dump_survey(struct sk_buff *skb,
                if (res)
                        goto out_err;
 
+               /* Survey without a channel doesn't make sense */
+               if (!survey.channel) {
+                       res = -EINVAL;
+                       goto out;
+               }
+
+               chan = ieee80211_get_channel(&dev->wiphy,
+                                            survey.channel->center_freq);
+               if (!chan || chan->flags & IEEE80211_CHAN_DISABLED) {
+                       survey_idx++;
+                       continue;
+               }
+
                if (nl80211_send_survey(skb,
                                NETLINK_CB(cb->skb).pid,
                                cb->nlh->nlmsg_seq, NLM_F_MULTI,
@@ -4361,6 +4372,93 @@ static int nl80211_testmode_do(struct sk_buff *skb, struct genl_info *info)
        return err;
 }
 
+static int nl80211_testmode_dump(struct sk_buff *skb,
+                                struct netlink_callback *cb)
+{
+       struct cfg80211_registered_device *dev;
+       int err;
+       long phy_idx;
+       void *data = NULL;
+       int data_len = 0;
+
+       if (cb->args[0]) {
+               /*
+                * 0 is a valid index, but not valid for args[0],
+                * so we need to offset by 1.
+                */
+               phy_idx = cb->args[0] - 1;
+       } else {
+               err = nlmsg_parse(cb->nlh, GENL_HDRLEN + nl80211_fam.hdrsize,
+                                 nl80211_fam.attrbuf, nl80211_fam.maxattr,
+                                 nl80211_policy);
+               if (err)
+                       return err;
+               if (!nl80211_fam.attrbuf[NL80211_ATTR_WIPHY])
+                       return -EINVAL;
+               phy_idx = nla_get_u32(nl80211_fam.attrbuf[NL80211_ATTR_WIPHY]);
+               if (nl80211_fam.attrbuf[NL80211_ATTR_TESTDATA])
+                       cb->args[1] =
+                               (long)nl80211_fam.attrbuf[NL80211_ATTR_TESTDATA];
+       }
+
+       if (cb->args[1]) {
+               data = nla_data((void *)cb->args[1]);
+               data_len = nla_len((void *)cb->args[1]);
+       }
+
+       mutex_lock(&cfg80211_mutex);
+       dev = cfg80211_rdev_by_wiphy_idx(phy_idx);
+       if (!dev) {
+               mutex_unlock(&cfg80211_mutex);
+               return -ENOENT;
+       }
+       cfg80211_lock_rdev(dev);
+       mutex_unlock(&cfg80211_mutex);
+
+       if (!dev->ops->testmode_dump) {
+               err = -EOPNOTSUPP;
+               goto out_err;
+       }
+
+       while (1) {
+               void *hdr = nl80211hdr_put(skb, NETLINK_CB(cb->skb).pid,
+                                          cb->nlh->nlmsg_seq, NLM_F_MULTI,
+                                          NL80211_CMD_TESTMODE);
+               struct nlattr *tmdata;
+
+               if (nla_put_u32(skb, NL80211_ATTR_WIPHY, dev->wiphy_idx) < 0) {
+                       genlmsg_cancel(skb, hdr);
+                       break;
+               }
+
+               tmdata = nla_nest_start(skb, NL80211_ATTR_TESTDATA);
+               if (!tmdata) {
+                       genlmsg_cancel(skb, hdr);
+                       break;
+               }
+               err = dev->ops->testmode_dump(&dev->wiphy, skb, cb,
+                                             data, data_len);
+               nla_nest_end(skb, tmdata);
+
+               if (err == -ENOBUFS || err == -ENOENT) {
+                       genlmsg_cancel(skb, hdr);
+                       break;
+               } else if (err) {
+                       genlmsg_cancel(skb, hdr);
+                       goto out_err;
+               }
+
+               genlmsg_end(skb, hdr);
+       }
+
+       err = skb->len;
+       /* see above */
+       cb->args[0] = phy_idx + 1;
+ out_err:
+       cfg80211_unlock_rdev(dev);
+       return err;
+}
+
 static struct sk_buff *
 __cfg80211_testmode_alloc_skb(struct cfg80211_registered_device *rdev,
                              int approxlen, u32 pid, u32 seq, gfp_t gfp)
@@ -5658,6 +5756,7 @@ static struct genl_ops nl80211_ops[] = {
        {
                .cmd = NL80211_CMD_TESTMODE,
                .doit = nl80211_testmode_do,
+               .dumpit = nl80211_testmode_dump,
                .policy = nl80211_policy,
                .flags = GENL_ADMIN_PERM,
                .internal_flags = NL80211_FLAG_NEED_WIPHY |