Merge branch 'for-john' of git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi...
authorJohn W. Linville <linville@tuxdriver.com>
Mon, 10 Jun 2013 18:51:17 +0000 (14:51 -0400)
committerJohn W. Linville <linville@tuxdriver.com>
Mon, 10 Jun 2013 18:51:17 +0000 (14:51 -0400)
50 files changed:
drivers/net/wireless/ath/ath9k/ani.c
drivers/net/wireless/ath/ath9k/ani.h
drivers/net/wireless/ath/ath9k/ar5008_phy.c
drivers/net/wireless/ath/ath9k/ar9002_hw.c
drivers/net/wireless/ath/ath9k/ar9002_initvals.h
drivers/net/wireless/ath/ath9k/ar9003_mac.c
drivers/net/wireless/ath/ath9k/ar9003_phy.c
drivers/net/wireless/ath/ath9k/debug.c
drivers/net/wireless/ath/ath9k/debug.h
drivers/net/wireless/ath/ath9k/htc_drv_main.c
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/link.c
drivers/net/wireless/ath/ath9k/mac.c
drivers/net/wireless/ath/ath9k/mac.h
drivers/net/wireless/ath/ath9k/main.c
drivers/net/wireless/ath/ath9k/recv.c
drivers/net/wireless/ath/ath9k/wow.c
drivers/net/wireless/brcm80211/brcmsmac/ampdu.c
drivers/net/wireless/cw1200/Kconfig
drivers/net/wireless/cw1200/Makefile
drivers/net/wireless/cw1200/bh.c
drivers/net/wireless/cw1200/cw1200.h
drivers/net/wireless/cw1200/cw1200_sagrad.c [deleted file]
drivers/net/wireless/cw1200/cw1200_sdio.c
drivers/net/wireless/cw1200/cw1200_spi.c
drivers/net/wireless/cw1200/debug.c
drivers/net/wireless/cw1200/fwio.c
drivers/net/wireless/cw1200/hwbus.h [new file with mode: 0644]
drivers/net/wireless/cw1200/hwio.c
drivers/net/wireless/cw1200/main.c
drivers/net/wireless/cw1200/pm.c
drivers/net/wireless/cw1200/pm.h
drivers/net/wireless/cw1200/sbus.h [deleted file]
drivers/net/wireless/cw1200/txrx.c
drivers/net/wireless/cw1200/wsm.c
drivers/net/wireless/ipw2x00/ipw2100.c
drivers/net/wireless/iwlwifi/mvm/mac80211.c
drivers/net/wireless/mac80211_hwsim.c
include/linux/cw1200_platform.h [deleted file]
include/linux/platform_data/net-cw1200.h [new file with mode: 0644]
include/net/cfg80211.h
include/uapi/linux/nl80211.h
net/mac80211/cfg.c
net/mac80211/driver-ops.h
net/mac80211/iface.c
net/mac80211/tx.c
net/mac80211/util.c
net/wireless/nl80211.c

index 7ecd40f..e91725b 100644 (file)
@@ -118,10 +118,10 @@ static void ath9k_ani_restart(struct ath_hw *ah)
 {
        struct ar5416AniState *aniState;
 
-       if (!DO_ANI(ah))
+       if (!ah->curchan)
                return;
 
-       aniState = &ah->curchan->ani;
+       aniState = &ah->ani;
        aniState->listenTime = 0;
 
        ENABLE_REGWRITE_BUFFER(ah);
@@ -143,7 +143,7 @@ static void ath9k_ani_restart(struct ath_hw *ah)
 static void ath9k_hw_set_ofdm_nil(struct ath_hw *ah, u8 immunityLevel,
                                  bool scan)
 {
-       struct ar5416AniState *aniState = &ah->curchan->ani;
+       struct ar5416AniState *aniState = &ah->ani;
        struct ath_common *common = ath9k_hw_common(ah);
        const struct ani_ofdm_level_entry *entry_ofdm;
        const struct ani_cck_level_entry *entry_cck;
@@ -195,10 +195,10 @@ static void ath9k_hw_ani_ofdm_err_trigger(struct ath_hw *ah)
 {
        struct ar5416AniState *aniState;
 
-       if (!DO_ANI(ah))
+       if (!ah->curchan)
                return;
 
-       aniState = &ah->curchan->ani;
+       aniState = &ah->ani;
 
        if (aniState->ofdmNoiseImmunityLevel < ATH9K_ANI_OFDM_MAX_LEVEL)
                ath9k_hw_set_ofdm_nil(ah, aniState->ofdmNoiseImmunityLevel + 1, false);
@@ -210,7 +210,7 @@ static void ath9k_hw_ani_ofdm_err_trigger(struct ath_hw *ah)
 static void ath9k_hw_set_cck_nil(struct ath_hw *ah, u_int8_t immunityLevel,
                                 bool scan)
 {
-       struct ar5416AniState *aniState = &ah->curchan->ani;
+       struct ar5416AniState *aniState = &ah->ani;
        struct ath_common *common = ath9k_hw_common(ah);
        const struct ani_ofdm_level_entry *entry_ofdm;
        const struct ani_cck_level_entry *entry_cck;
@@ -251,10 +251,10 @@ static void ath9k_hw_ani_cck_err_trigger(struct ath_hw *ah)
 {
        struct ar5416AniState *aniState;
 
-       if (!DO_ANI(ah))
+       if (!ah->curchan)
                return;
 
-       aniState = &ah->curchan->ani;
+       aniState = &ah->ani;
 
        if (aniState->cckNoiseImmunityLevel < ATH9K_ANI_CCK_MAX_LEVEL)
                ath9k_hw_set_cck_nil(ah, aniState->cckNoiseImmunityLevel + 1,
@@ -269,7 +269,7 @@ static void ath9k_hw_ani_lower_immunity(struct ath_hw *ah)
 {
        struct ar5416AniState *aniState;
 
-       aniState = &ah->curchan->ani;
+       aniState = &ah->ani;
 
        /* lower OFDM noise immunity */
        if (aniState->ofdmNoiseImmunityLevel > 0 &&
@@ -292,12 +292,12 @@ static void ath9k_hw_ani_lower_immunity(struct ath_hw *ah)
  */
 void ath9k_ani_reset(struct ath_hw *ah, bool is_scanning)
 {
-       struct ar5416AniState *aniState = &ah->curchan->ani;
+       struct ar5416AniState *aniState = &ah->ani;
        struct ath9k_channel *chan = ah->curchan;
        struct ath_common *common = ath9k_hw_common(ah);
        int ofdm_nil, cck_nil;
 
-       if (!DO_ANI(ah))
+       if (!ah->curchan)
                return;
 
        BUG_ON(aniState == NULL);
@@ -380,7 +380,7 @@ void ath9k_ani_reset(struct ath_hw *ah, bool is_scanning)
 static bool ath9k_hw_ani_read_counters(struct ath_hw *ah)
 {
        struct ath_common *common = ath9k_hw_common(ah);
-       struct ar5416AniState *aniState = &ah->curchan->ani;
+       struct ar5416AniState *aniState = &ah->ani;
        u32 phyCnt1, phyCnt2;
        int32_t listenTime;
 
@@ -415,10 +415,10 @@ void ath9k_hw_ani_monitor(struct ath_hw *ah, struct ath9k_channel *chan)
        struct ath_common *common = ath9k_hw_common(ah);
        u32 ofdmPhyErrRate, cckPhyErrRate;
 
-       if (!DO_ANI(ah))
+       if (!ah->curchan)
                return;
 
-       aniState = &ah->curchan->ani;
+       aniState = &ah->ani;
        if (!ath9k_hw_ani_read_counters(ah))
                return;
 
@@ -490,32 +490,22 @@ EXPORT_SYMBOL(ath9k_hw_disable_mib_counters);
 void ath9k_hw_ani_init(struct ath_hw *ah)
 {
        struct ath_common *common = ath9k_hw_common(ah);
-       int i;
+       struct ar5416AniState *ani = &ah->ani;
 
        ath_dbg(common, ANI, "Initialize ANI\n");
 
        ah->config.ofdm_trig_high = ATH9K_ANI_OFDM_TRIG_HIGH;
        ah->config.ofdm_trig_low = ATH9K_ANI_OFDM_TRIG_LOW;
-
        ah->config.cck_trig_high = ATH9K_ANI_CCK_TRIG_HIGH;
        ah->config.cck_trig_low = ATH9K_ANI_CCK_TRIG_LOW;
 
-       for (i = 0; i < ARRAY_SIZE(ah->channels); i++) {
-               struct ath9k_channel *chan = &ah->channels[i];
-               struct ar5416AniState *ani = &chan->ani;
-
-               ani->spurImmunityLevel = ATH9K_ANI_SPUR_IMMUNE_LVL;
-
-               ani->firstepLevel = ATH9K_ANI_FIRSTEP_LVL;
-
-               ani->mrcCCK = AR_SREV_9300_20_OR_LATER(ah) ? true : false;
-
-               ani->ofdmsTurn = true;
-
-               ani->ofdmWeakSigDetect = ATH9K_ANI_USE_OFDM_WEAK_SIG;
-               ani->cckNoiseImmunityLevel = ATH9K_ANI_CCK_DEF_LEVEL;
-               ani->ofdmNoiseImmunityLevel = ATH9K_ANI_OFDM_DEF_LEVEL;
-       }
+       ani->spurImmunityLevel = ATH9K_ANI_SPUR_IMMUNE_LVL;
+       ani->firstepLevel = ATH9K_ANI_FIRSTEP_LVL;
+       ani->mrcCCK = AR_SREV_9300_20_OR_LATER(ah) ? true : false;
+       ani->ofdmsTurn = true;
+       ani->ofdmWeakSigDetect = true;
+       ani->cckNoiseImmunityLevel = ATH9K_ANI_CCK_DEF_LEVEL;
+       ani->ofdmNoiseImmunityLevel = ATH9K_ANI_OFDM_DEF_LEVEL;
 
        /*
         * since we expect some ongoing maintenance on the tables, let's sanity
@@ -524,9 +514,6 @@ void ath9k_hw_ani_init(struct ath_hw *ah)
        ah->aniperiod = ATH9K_ANI_PERIOD;
        ah->config.ani_poll_interval = ATH9K_ANI_POLLINTERVAL;
 
-       if (ah->config.enable_ani)
-               ah->proc_phyerr |= HAL_PROCESS_ANI;
-
        ath9k_ani_restart(ah);
        ath9k_enable_mib_counters(ah);
 }
index dddb136..78b9fa9 100644 (file)
 #ifndef ANI_H
 #define ANI_H
 
-#define HAL_PROCESS_ANI           0x00000001
-
-#define DO_ANI(ah) (((ah)->proc_phyerr & HAL_PROCESS_ANI) && ah->curchan)
-
 #define BEACON_RSSI(ahp) (ahp->stats.avgbrssi)
 
 /* units are errors per second */
 #define ATH9K_ANI_CCK_TRIG_LOW            300
 
 #define ATH9K_ANI_NOISE_IMMUNE_LVL        4
-#define ATH9K_ANI_USE_OFDM_WEAK_SIG       true
-#define ATH9K_ANI_CCK_WEAK_SIG_THR        false
-
 #define ATH9K_ANI_SPUR_IMMUNE_LVL         3
-
 #define ATH9K_ANI_FIRSTEP_LVL             2
 
 #define ATH9K_ANI_RSSI_THR_HIGH           40
@@ -111,7 +103,7 @@ struct ar5416AniState {
        u8 mrcCCK;
        u8 spurImmunityLevel;
        u8 firstepLevel;
-       u8 ofdmWeakSigDetect;
+       bool ofdmWeakSigDetect;
        u32 listenTime;
        u32 ofdmPhyErrCount;
        u32 cckPhyErrCount;
@@ -119,8 +111,6 @@ struct ar5416AniState {
 };
 
 struct ar5416Stats {
-       u32 ast_ani_niup;
-       u32 ast_ani_nidown;
        u32 ast_ani_spurup;
        u32 ast_ani_spurdown;
        u32 ast_ani_ofdmon;
index 391da5a..d1acfe9 100644 (file)
@@ -931,7 +931,7 @@ static bool ar5008_hw_ani_control_new(struct ath_hw *ah,
 {
        struct ath_common *common = ath9k_hw_common(ah);
        struct ath9k_channel *chan = ah->curchan;
-       struct ar5416AniState *aniState = &chan->ani;
+       struct ar5416AniState *aniState = &ah->ani;
        s32 value, value2;
 
        switch (cmd & ah->ani_function) {
@@ -1207,7 +1207,7 @@ static void ar5008_hw_ani_cache_ini_regs(struct ath_hw *ah)
 {
        struct ath_common *common = ath9k_hw_common(ah);
        struct ath9k_channel *chan = ah->curchan;
-       struct ar5416AniState *aniState = &chan->ani;
+       struct ar5416AniState *aniState = &ah->ani;
        struct ath9k_ani_default *iniDef;
        u32 val;
 
@@ -1251,7 +1251,7 @@ static void ar5008_hw_ani_cache_ini_regs(struct ath_hw *ah)
        /* these levels just got reset to defaults by the INI */
        aniState->spurImmunityLevel = ATH9K_ANI_SPUR_IMMUNE_LVL;
        aniState->firstepLevel = ATH9K_ANI_FIRSTEP_LVL;
-       aniState->ofdmWeakSigDetect = ATH9K_ANI_USE_OFDM_WEAK_SIG;
+       aniState->ofdmWeakSigDetect = true;
        aniState->mrcCCK = false; /* not available on pre AR9003 */
 }
 
index 830daa1..8dc2d08 100644 (file)
@@ -38,10 +38,6 @@ static int ar9002_hw_init_mode_regs(struct ath_hw *ah)
        else
                INIT_INI_ARRAY(&ah->iniPcieSerdes,
                           ar9280PciePhy_clkreq_always_on_L1_9280);
-#ifdef CONFIG_PM_SLEEP
-               INIT_INI_ARRAY(&ah->iniPcieSerdesWow,
-                              ar9280PciePhy_awow);
-#endif
 
        if (AR_SREV_9287_11_OR_LATER(ah)) {
                INIT_INI_ARRAY(&ah->iniModes, ar9287Modes_9287_1_1);
index beb6162..4d18c66 100644 (file)
@@ -925,20 +925,6 @@ static const u32 ar9280PciePhy_clkreq_always_on_L1_9280[][2] = {
        {0x00004044, 0x00000000},
 };
 
-static const u32 ar9280PciePhy_awow[][2] = {
-       /* Addr      allmodes  */
-       {0x00004040, 0x9248fd00},
-       {0x00004040, 0x24924924},
-       {0x00004040, 0xa8000019},
-       {0x00004040, 0x13160820},
-       {0x00004040, 0xe5980560},
-       {0x00004040, 0xc01dcffd},
-       {0x00004040, 0x1aaabe41},
-       {0x00004040, 0xbe105554},
-       {0x00004040, 0x00043007},
-       {0x00004044, 0x00000000},
-};
-
 static const u32 ar9285Modes_9285_1_2[][5] = {
        /* Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20   */
        {0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160},
index 301bf72..5163abd 100644 (file)
@@ -469,6 +469,7 @@ int ath9k_hw_process_rxdesc_edma(struct ath_hw *ah, struct ath_rx_status *rxs,
 
        rxs->rs_status = 0;
        rxs->rs_flags =  0;
+       rxs->flag =  0;
 
        rxs->rs_datalen = rxsp->status2 & AR_DataLen;
        rxs->rs_tstamp =  rxsp->status3;
@@ -493,8 +494,8 @@ int ath9k_hw_process_rxdesc_edma(struct ath_hw *ah, struct ath_rx_status *rxs,
        rxs->rs_isaggr = (rxsp->status11 & AR_RxAggr) ? 1 : 0;
        rxs->rs_moreaggr = (rxsp->status11 & AR_RxMoreAggr) ? 1 : 0;
        rxs->rs_antenna = (MS(rxsp->status4, AR_RxAntenna) & 0x7);
-       rxs->rs_flags  = (rxsp->status4 & AR_GI) ? ATH9K_RX_GI : 0;
-       rxs->rs_flags  |= (rxsp->status4 & AR_2040) ? ATH9K_RX_2040 : 0;
+       rxs->flag  |= (rxsp->status4 & AR_GI) ? RX_FLAG_SHORT_GI : 0;
+       rxs->flag  |= (rxsp->status4 & AR_2040) ? RX_FLAG_40MHZ : 0;
 
        rxs->evm0 = rxsp->status6;
        rxs->evm1 = rxsp->status7;
index 2bf6548..0d05350 100644 (file)
@@ -904,7 +904,7 @@ static bool ar9003_hw_ani_control(struct ath_hw *ah,
 {
        struct ath_common *common = ath9k_hw_common(ah);
        struct ath9k_channel *chan = ah->curchan;
-       struct ar5416AniState *aniState = &chan->ani;
+       struct ar5416AniState *aniState = &ah->ani;
        s32 value, value2;
 
        switch (cmd & ah->ani_function) {
@@ -1172,7 +1172,7 @@ static void ar9003_hw_ani_cache_ini_regs(struct ath_hw *ah)
        struct ath9k_ani_default *iniDef;
        u32 val;
 
-       aniState = &ah->curchan->ani;
+       aniState = &ah->ani;
        iniDef = &aniState->iniDef;
 
        ath_dbg(common, ANI, "ver %d.%d opmode %u chan %d Mhz/0x%x\n",
@@ -1213,7 +1213,7 @@ static void ar9003_hw_ani_cache_ini_regs(struct ath_hw *ah)
        /* these levels just got reset to defaults by the INI */
        aniState->spurImmunityLevel = ATH9K_ANI_SPUR_IMMUNE_LVL;
        aniState->firstepLevel = ATH9K_ANI_FIRSTEP_LVL;
-       aniState->ofdmWeakSigDetect = ATH9K_ANI_USE_OFDM_WEAK_SIG;
+       aniState->ofdmWeakSigDetect = true;
        aniState->mrcCCK = true;
 }
 
index fc96ad3..7852f6e 100644 (file)
@@ -173,25 +173,69 @@ 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,
+static ssize_t read_file_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;
+       struct ath_hw *ah = sc->sc_ah;
+       unsigned int len = 0, size = 1024;
+       ssize_t retval = 0;
+       char *buf;
 
-       len = sprintf(buf, "%d\n", common->disable_ani);
-       return simple_read_from_buffer(user_buf, count, ppos, buf, len);
+       buf = kzalloc(size, GFP_KERNEL);
+       if (buf == NULL)
+               return -ENOMEM;
+
+       if (common->disable_ani) {
+               len += snprintf(buf + len, size - len, "%s: %s\n",
+                               "ANI", "DISABLED");
+               goto exit;
+       }
+
+       len += snprintf(buf + len, size - len, "%15s: %s\n",
+                       "ANI", "ENABLED");
+       len += snprintf(buf + len, size - len, "%15s: %u\n",
+                       "ANI RESET", ah->stats.ast_ani_reset);
+       len += snprintf(buf + len, size - len, "%15s: %u\n",
+                       "SPUR UP", ah->stats.ast_ani_spurup);
+       len += snprintf(buf + len, size - len, "%15s: %u\n",
+                       "SPUR DOWN", ah->stats.ast_ani_spurup);
+       len += snprintf(buf + len, size - len, "%15s: %u\n",
+                       "OFDM WS-DET ON", ah->stats.ast_ani_ofdmon);
+       len += snprintf(buf + len, size - len, "%15s: %u\n",
+                       "OFDM WS-DET OFF", ah->stats.ast_ani_ofdmoff);
+       len += snprintf(buf + len, size - len, "%15s: %u\n",
+                       "MRC-CCK ON", ah->stats.ast_ani_ccklow);
+       len += snprintf(buf + len, size - len, "%15s: %u\n",
+                       "MRC-CCK OFF", ah->stats.ast_ani_cckhigh);
+       len += snprintf(buf + len, size - len, "%15s: %u\n",
+                       "FIR-STEP UP", ah->stats.ast_ani_stepup);
+       len += snprintf(buf + len, size - len, "%15s: %u\n",
+                       "FIR-STEP DOWN", ah->stats.ast_ani_stepdown);
+       len += snprintf(buf + len, size - len, "%15s: %u\n",
+                       "INV LISTENTIME", ah->stats.ast_ani_lneg_or_lzero);
+       len += snprintf(buf + len, size - len, "%15s: %u\n",
+                       "OFDM ERRORS", ah->stats.ast_ani_ofdmerrs);
+       len += snprintf(buf + len, size - len, "%15s: %u\n",
+                       "CCK ERRORS", ah->stats.ast_ani_cckerrs);
+exit:
+       if (len > size)
+               len = size;
+
+       retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
+       kfree(buf);
+
+       return retval;
 }
 
-static ssize_t write_file_disable_ani(struct file *file,
-                                     const char __user *user_buf,
-                                     size_t count, loff_t *ppos)
+static ssize_t write_file_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;
+       unsigned long ani;
        char buf[32];
        ssize_t len;
 
@@ -200,12 +244,15 @@ static ssize_t write_file_disable_ani(struct file *file,
                return -EFAULT;
 
        buf[len] = '\0';
-       if (strict_strtoul(buf, 0, &disable_ani))
+       if (strict_strtoul(buf, 0, &ani))
+               return -EINVAL;
+
+       if (ani < 0 || ani > 1)
                return -EINVAL;
 
-       common->disable_ani = !!disable_ani;
+       common->disable_ani = !ani;
 
-       if (disable_ani) {
+       if (common->disable_ani) {
                clear_bit(SC_OP_ANI_RUN, &sc->sc_flags);
                ath_stop_ani(sc);
        } else {
@@ -215,9 +262,9 @@ static ssize_t write_file_disable_ani(struct file *file,
        return count;
 }
 
-static const struct file_operations fops_disable_ani = {
-       .read = read_file_disable_ani,
-       .write = write_file_disable_ani,
+static const struct file_operations fops_ani = {
+       .read = read_file_ani,
+       .write = write_file_ani,
        .open = simple_open,
        .owner = THIS_MODULE,
        .llseek = default_llseek,
@@ -1719,8 +1766,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("ani", S_IRUSR | S_IWUSR,
+                           sc->debug.debugfs_phy, sc, &fops_ani);
        debugfs_create_bool("paprd", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy,
                            &sc->sc_ah->config.enable_paprd);
        debugfs_create_file("regidx", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy,
index 62da19c..9719378 100644 (file)
@@ -251,45 +251,6 @@ struct ath_stats {
        u32 reset[__RESET_TYPE_MAX];
 };
 
-#define ATH_DBG_MAX_SAMPLES    10
-struct ath_dbg_bb_mac_samp {
-       u32 dma_dbg_reg_vals[ATH9K_NUM_DMA_DEBUG_REGS];
-       u32 pcu_obs, pcu_cr, noise;
-       struct {
-               u64 jiffies;
-               int8_t rssi_ctl0;
-               int8_t rssi_ctl1;
-               int8_t rssi_ctl2;
-               int8_t rssi_ext0;
-               int8_t rssi_ext1;
-               int8_t rssi_ext2;
-               int8_t rssi;
-               bool isok;
-               u8 rts_fail_cnt;
-               u8 data_fail_cnt;
-               u8 rateindex;
-               u8 qid;
-               u8 tid;
-               u32 ba_low;
-               u32 ba_high;
-       } ts[ATH_DBG_MAX_SAMPLES];
-       struct {
-               u64 jiffies;
-               int8_t rssi_ctl0;
-               int8_t rssi_ctl1;
-               int8_t rssi_ctl2;
-               int8_t rssi_ext0;
-               int8_t rssi_ext1;
-               int8_t rssi_ext2;
-               int8_t rssi;
-               bool is_mybeacon;
-               u8 antenna;
-               u8 rate;
-       } rs[ATH_DBG_MAX_SAMPLES];
-       struct ath_cycle_counters cc;
-       struct ath9k_nfcal_hist nfCalHist[NUM_NF_READINGS];
-};
-
 struct ath9k_debug {
        struct dentry *debugfs_phy;
        u32 regidx;
index 2a67b57..34869c2 100644 (file)
@@ -814,8 +814,7 @@ void ath9k_htc_ani_work(struct work_struct *work)
        }
 
        /* Verify whether we must check ANI */
-       if (ah->config.enable_ani &&
-           (timestamp - common->ani.checkani_timer) >= ATH_ANI_POLLINTERVAL) {
+       if ((timestamp - common->ani.checkani_timer) >= ATH_ANI_POLLINTERVAL) {
                aniflag = true;
                common->ani.checkani_timer = timestamp;
        }
@@ -845,8 +844,7 @@ set_timer:
        * short calibration and long calibration.
        */
        cal_interval = ATH_LONG_CALINTERVAL;
-       if (ah->config.enable_ani)
-               cal_interval = min(cal_interval, (u32)ATH_ANI_POLLINTERVAL);
+       cal_interval = min(cal_interval, (u32)ATH_ANI_POLLINTERVAL);
        if (!common->ani.caldone)
                cal_interval = min(cal_interval, (u32)short_cal_interval);
 
index a263ccc..a13f6ce 100644 (file)
@@ -452,7 +452,6 @@ static void ath9k_hw_init_config(struct ath_hw *ah)
        ah->config.pcie_clock_req = 0;
        ah->config.pcie_waen = 0;
        ah->config.analog_shiftreg = 1;
-       ah->config.enable_ani = true;
 
        for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
                ah->config.spurchans[i][0] = AR_NO_SPUR;
@@ -549,8 +548,7 @@ static int ath9k_hw_post_init(struct ath_hw *ah)
                ah->eep_ops->get_eeprom_ver(ah),
                ah->eep_ops->get_eeprom_rev(ah));
 
-       if (ah->config.enable_ani)
-               ath9k_hw_ani_init(ah);
+       ath9k_hw_ani_init(ah);
 
        return 0;
 }
@@ -2595,13 +2593,8 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
                        pCap->hw_caps |= ATH9K_HW_CAP_RTT;
        }
 
-       if (AR_SREV_9280_20_OR_LATER(ah)) {
-               pCap->hw_caps |= ATH9K_HW_WOW_DEVICE_CAPABLE |
-                                ATH9K_HW_WOW_PATTERN_MATCH_EXACT;
-
-               if (AR_SREV_9280(ah))
-                       pCap->hw_caps |= ATH9K_HW_WOW_PATTERN_MATCH_DWORD;
-       }
+       if (AR_SREV_9462(ah))
+               pCap->hw_caps |= ATH9K_HW_WOW_DEVICE_CAPABLE;
 
        if (AR_SREV_9300_20_OR_LATER(ah) &&
            ah->eep_ops->get_eeprom(ah, EEP_PAPRD))
index ae30343..7d259b7 100644 (file)
@@ -246,9 +246,7 @@ enum ath9k_hw_caps {
        ATH9K_HW_CAP_MCI                        = BIT(15),
        ATH9K_HW_CAP_DFS                        = BIT(16),
        ATH9K_HW_WOW_DEVICE_CAPABLE             = BIT(17),
-       ATH9K_HW_WOW_PATTERN_MATCH_EXACT        = BIT(18),
-       ATH9K_HW_WOW_PATTERN_MATCH_DWORD        = BIT(19),
-       ATH9K_HW_CAP_PAPRD                      = BIT(20),
+       ATH9K_HW_CAP_PAPRD                      = BIT(18),
 };
 
 /*
@@ -291,7 +289,6 @@ struct ath9k_ops_config {
        u32 ofdm_trig_high;
        u32 cck_trig_high;
        u32 cck_trig_low;
-       u32 enable_ani;
        u32 enable_paprd;
        int serialize_regmode;
        bool rx_intr_mitigation;
@@ -423,7 +420,6 @@ struct ath9k_hw_cal_data {
 
 struct ath9k_channel {
        struct ieee80211_channel *chan;
-       struct ar5416AniState ani;
        u16 channel;
        u32 channelFlags;
        u32 chanmode;
@@ -854,10 +850,10 @@ struct ath_hw {
        u32 globaltxtimeout;
 
        /* ANI */
-       u32 proc_phyerr;
        u32 aniperiod;
        enum ath9k_ani_cmd ani_function;
        u32 ani_skip_count;
+       struct ar5416AniState ani;
 
 #ifdef CONFIG_ATH9K_BTCOEX_SUPPORT
        struct ath_btcoex_hw btcoex_hw;
@@ -882,9 +878,6 @@ struct ath_hw {
        struct ar5416IniArray iniBank6;
        struct ar5416IniArray iniAddac;
        struct ar5416IniArray iniPcieSerdes;
-#ifdef CONFIG_PM_SLEEP
-       struct ar5416IniArray iniPcieSerdesWow;
-#endif
        struct ar5416IniArray iniPcieSerdesLowPower;
        struct ar5416IniArray iniModesFastClock;
        struct ar5416IniArray iniAdditional;
@@ -1165,8 +1158,6 @@ static inline void ath9k_hw_wow_enable(struct ath_hw *ah, u32 pattern_enable)
 }
 #endif
 
-
-
 #define ATH9K_CLOCK_RATE_CCK           22
 #define ATH9K_CLOCK_RATE_5GHZ_OFDM     40
 #define ATH9K_CLOCK_RATE_2GHZ_OFDM     44
index c7b888f..979bde3 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/ath9k_platform.h>
 #include <linux/module.h>
 #include <linux/relay.h>
+#include <net/ieee80211_radiotap.h>
 
 #include "ath9k.h"
 
@@ -766,12 +767,19 @@ void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
                IEEE80211_HW_REPORTS_TX_ACK_STATUS |
                IEEE80211_HW_SUPPORTS_RC_TABLE;
 
-       if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT)
-                hw->flags |= IEEE80211_HW_AMPDU_AGGREGATION;
+       if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) {
+               hw->flags |= IEEE80211_HW_AMPDU_AGGREGATION;
+
+               if (AR_SREV_9280_20_OR_LATER(ah))
+                       hw->radiotap_mcs_details |=
+                               IEEE80211_RADIOTAP_MCS_HAVE_STBC;
+       }
 
        if (AR_SREV_9160_10_OR_LATER(sc->sc_ah) || ath9k_modparam_nohwcrypt)
                hw->flags |= IEEE80211_HW_MFP_CAPABLE;
 
+       hw->wiphy->features |= NL80211_FEATURE_ACTIVE_MONITOR;
+
        hw->wiphy->interface_modes =
                BIT(NL80211_IFTYPE_P2P_GO) |
                BIT(NL80211_IFTYPE_P2P_CLIENT) |
@@ -792,21 +800,17 @@ void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
        hw->wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
 
 #ifdef CONFIG_PM_SLEEP
-
        if ((ah->caps.hw_caps & ATH9K_HW_WOW_DEVICE_CAPABLE) &&
            device_can_wakeup(sc->dev)) {
-
                hw->wiphy->wowlan.flags = WIPHY_WOWLAN_MAGIC_PKT |
                                          WIPHY_WOWLAN_DISCONNECT;
                hw->wiphy->wowlan.n_patterns = MAX_NUM_USER_PATTERN;
                hw->wiphy->wowlan.pattern_min_len = 1;
                hw->wiphy->wowlan.pattern_max_len = MAX_PATTERN_SIZE;
-
        }
 
        atomic_set(&sc->wow_sleep_proc_intr, -1);
        atomic_set(&sc->wow_got_bmiss_intr, -1);
-
 #endif
 
        hw->queues = 4;
index cc422a4..fff5d3c 100644 (file)
@@ -390,9 +390,7 @@ void ath_ani_calibrate(unsigned long data)
        }
 
        /* Verify whether we must check ANI */
-       if (sc->sc_ah->config.enable_ani
-           && (timestamp - common->ani.checkani_timer) >=
-           ah->config.ani_poll_interval) {
+       if ((timestamp - common->ani.checkani_timer) >= ah->config.ani_poll_interval) {
                aniflag = true;
                common->ani.checkani_timer = timestamp;
        }
@@ -427,9 +425,7 @@ set_timer:
        * short calibration and long calibration.
        */
        cal_interval = ATH_LONG_CALINTERVAL;
-       if (sc->sc_ah->config.enable_ani)
-               cal_interval = min(cal_interval,
-                                  (u32)ah->config.ani_poll_interval);
+       cal_interval = min(cal_interval, (u32)ah->config.ani_poll_interval);
        if (!common->ani.caldone)
                cal_interval = min(cal_interval, (u32)short_cal_interval);
 
index 498fee0..d055e38 100644 (file)
@@ -547,6 +547,7 @@ int ath9k_hw_rxprocdesc(struct ath_hw *ah, struct ath_desc *ds,
 
        rs->rs_status = 0;
        rs->rs_flags = 0;
+       rs->flag = 0;
 
        rs->rs_datalen = ads.ds_rxstatus1 & AR_DataLen;
        rs->rs_tstamp = ads.AR_RcvTimestamp;
@@ -586,10 +587,17 @@ int ath9k_hw_rxprocdesc(struct ath_hw *ah, struct ath_desc *ds,
        rs->rs_moreaggr =
                (ads.ds_rxstatus8 & AR_RxMoreAggr) ? 1 : 0;
        rs->rs_antenna = MS(ads.ds_rxstatus3, AR_RxAntenna);
-       rs->rs_flags =
-               (ads.ds_rxstatus3 & AR_GI) ? ATH9K_RX_GI : 0;
-       rs->rs_flags |=
-               (ads.ds_rxstatus3 & AR_2040) ? ATH9K_RX_2040 : 0;
+
+       /* directly mapped flags for ieee80211_rx_status */
+       rs->flag |=
+               (ads.ds_rxstatus3 & AR_GI) ? RX_FLAG_SHORT_GI : 0;
+       rs->flag |=
+               (ads.ds_rxstatus3 & AR_2040) ? RX_FLAG_40MHZ : 0;
+       if (AR_SREV_9280_20_OR_LATER(ah))
+               rs->flag |=
+                       (ads.ds_rxstatus3 & AR_STBC) ?
+                               /* we can only Nss=1 STBC */
+                               (1 << RX_FLAG_STBC_SHIFT) : 0;
 
        if (ads.ds_rxstatus8 & AR_PreDelimCRCErr)
                rs->rs_flags |= ATH9K_RX_DELIM_CRC_PRE;
index 5865f92..b02dfce 100644 (file)
@@ -149,6 +149,7 @@ struct ath_rx_status {
        u32 evm2;
        u32 evm3;
        u32 evm4;
+       u32 flag; /* see enum mac80211_rx_flags */
 };
 
 struct ath_htc_rx_status {
@@ -533,7 +534,8 @@ struct ar5416_desc {
 #define AR_2040             0x00000002
 #define AR_Parallel40       0x00000004
 #define AR_Parallel40_S     2
-#define AR_RxStatusRsvd30   0x000000f8
+#define AR_STBC             0x00000008 /* on ar9280 and later */
+#define AR_RxStatusRsvd30   0x000000f0
 #define AR_RxAntenna       0xffffff00
 #define AR_RxAntenna_S     8
 
index a1630d1..cc5a98b 100644 (file)
@@ -2003,7 +2003,6 @@ static void ath9k_wow_add_disassoc_deauth_pattern(struct ath_softc *sc)
 {
        struct ath_hw *ah = sc->sc_ah;
        struct ath_common *common = ath9k_hw_common(ah);
-       struct ath9k_hw_capabilities *pcaps = &ah->caps;
        int pattern_count = 0;
        int i, byte_cnt;
        u8 dis_deauth_pattern[MAX_PATTERN_SIZE];
@@ -2073,36 +2072,9 @@ static void ath9k_wow_add_disassoc_deauth_pattern(struct ath_softc *sc)
 
        /* Create Disassociate pattern mask */
 
-       if (pcaps->hw_caps & ATH9K_HW_WOW_PATTERN_MATCH_EXACT) {
-
-               if (pcaps->hw_caps & ATH9K_HW_WOW_PATTERN_MATCH_DWORD) {
-                       /*
-                        * for AR9280, because of hardware limitation, the
-                        * first 4 bytes have to be matched for all patterns.
-                        * the mask for disassociation and de-auth pattern
-                        * matching need to enable the first 4 bytes.
-                        * also the duration field needs to be filled.
-                        */
-                       dis_deauth_mask[0] = 0xf0;
-
-                       /*
-                        * fill in duration field
-                        FIXME: what is the exact value ?
-                        */
-                       dis_deauth_pattern[2] = 0xff;
-                       dis_deauth_pattern[3] = 0xff;
-               } else {
-                       dis_deauth_mask[0] = 0xfe;
-               }
-
-               dis_deauth_mask[1] = 0x03;
-               dis_deauth_mask[2] = 0xc0;
-       } else {
-               dis_deauth_mask[0] = 0xef;
-               dis_deauth_mask[1] = 0x3f;
-               dis_deauth_mask[2] = 0x00;
-               dis_deauth_mask[3] = 0xfc;
-       }
+       dis_deauth_mask[0] = 0xfe;
+       dis_deauth_mask[1] = 0x03;
+       dis_deauth_mask[2] = 0xc0;
 
        ath_dbg(common, WOW, "Adding disassoc/deauth patterns for WoW\n");
 
index 8be2b5d..865e043 100644 (file)
@@ -868,10 +868,7 @@ static int ath9k_process_rate(struct ath_common *common,
        if (rx_stats->rs_rate & 0x80) {
                /* HT rate */
                rxs->flag |= RX_FLAG_HT;
-               if (rx_stats->rs_flags & ATH9K_RX_2040)
-                       rxs->flag |= RX_FLAG_40MHZ;
-               if (rx_stats->rs_flags & ATH9K_RX_GI)
-                       rxs->flag |= RX_FLAG_SHORT_GI;
+               rxs->flag |= rx_stats->flag;
                rxs->rate_idx = rx_stats->rs_rate & 0x7f;
                return 0;
        }
@@ -958,11 +955,11 @@ static int ath9k_rx_skb_preprocess(struct ath_softc *sc,
        if (rx_stats->rs_more)
                return 0;
 
-       ath9k_process_rssi(common, hw, hdr, rx_stats);
-
        if (ath9k_process_rate(common, hw, rx_stats, rx_status))
                return -EINVAL;
 
+       ath9k_process_rssi(common, hw, hdr, rx_stats);
+
        rx_status->band = hw->conf.chandef.chan->band;
        rx_status->freq = hw->conf.chandef.chan->center_freq;
        rx_status->signal = ah->noise + rx_stats->rs_rssi;
index 9f85630..81c88dd 100644 (file)
@@ -34,17 +34,6 @@ const char *ath9k_hw_wow_event_to_string(u32 wow_event)
 }
 EXPORT_SYMBOL(ath9k_hw_wow_event_to_string);
 
-static void ath9k_hw_config_serdes_wow_sleep(struct ath_hw *ah)
-{
-       int i;
-
-       for (i = 0; i < ah->iniPcieSerdesWow.ia_rows; i++)
-               REG_WRITE(ah, INI_RA(&ah->iniPcieSerdesWow, i, 0),
-                         INI_RA(&ah->iniPcieSerdesWow, i, 1));
-
-       usleep_range(1000, 1500);
-}
-
 static void ath9k_hw_set_powermode_wow_sleep(struct ath_hw *ah)
 {
        struct ath_common *common = ath9k_hw_common(ah);
@@ -58,15 +47,8 @@ static void ath9k_hw_set_powermode_wow_sleep(struct ath_hw *ah)
                ath_err(common, "Failed to stop Rx DMA in 10ms AR_CR=0x%08x AR_DIAG_SW=0x%08x\n",
                        REG_READ(ah, AR_CR), REG_READ(ah, AR_DIAG_SW));
                return;
-       } else {
-               if (!AR_SREV_9300_20_OR_LATER(ah))
-                       REG_WRITE(ah, AR_RXDP, 0x0);
        }
 
-       /* AR9280 WoW has sleep issue, do not set it to sleep */
-       if (AR_SREV_9280_20(ah))
-               return;
-
        REG_WRITE(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_ON_INT);
 }
 
@@ -84,27 +66,16 @@ static void ath9k_wow_create_keep_alive_pattern(struct ath_hw *ah)
 
        /* set the transmit buffer */
        ctl[0] = (KAL_FRAME_LEN | (MAX_RATE_POWER << 16));
-
-       if (!(AR_SREV_9300_20_OR_LATER(ah)))
-               ctl[0] += (KAL_ANTENNA_MODE << 25);
-
        ctl[1] = 0;
        ctl[3] = 0xb;   /* OFDM_6M hardware value for this rate */
        ctl[4] = 0;
        ctl[7] = (ah->txchainmask) << 2;
-
-       if (AR_SREV_9300_20_OR_LATER(ah))
-               ctl[2] = 0xf << 16; /* tx_tries 0 */
-       else
-               ctl[2] = 0x7 << 16; /* tx_tries 0 */
-
+       ctl[2] = 0xf << 16; /* tx_tries 0 */
 
        for (i = 0; i < KAL_NUM_DESC_WORDS; i++)
                REG_WRITE(ah, (AR_WOW_KA_DESC_WORD2 + i * 4), ctl[i]);
 
-       /* for AR9300 family 13 descriptor words */
-       if (AR_SREV_9300_20_OR_LATER(ah))
-               REG_WRITE(ah, (AR_WOW_KA_DESC_WORD2 + i * 4), ctl[i]);
+       REG_WRITE(ah, (AR_WOW_KA_DESC_WORD2 + i * 4), ctl[i]);
 
        data_word[0] = (KAL_FRAME_TYPE << 2) | (KAL_FRAME_SUB_TYPE << 4) |
                       (KAL_TO_DS << 8) | (KAL_DURATION_ID << 16);
@@ -183,9 +154,6 @@ void ath9k_hw_wow_apply_pattern(struct ath_hw *ah, u8 *user_pattern,
 
        ah->wow_event_mask |= BIT(pattern_count + AR_WOW_PAT_FOUND_SHIFT);
 
-       if (!AR_SREV_9285_12_OR_LATER(ah))
-               return;
-
        if (pattern_count < 4) {
                /* Pattern 0-3 uses AR_WOW_LENGTH1 register */
                set = (pattern_len & AR_WOW_LENGTH_MAX) <<
@@ -207,6 +175,7 @@ u32 ath9k_hw_wow_wakeup(struct ath_hw *ah)
 {
        u32 wow_status = 0;
        u32 val = 0, rval;
+
        /*
         * read the WoW status register to know
         * the wakeup reason
@@ -223,19 +192,14 @@ u32 ath9k_hw_wow_wakeup(struct ath_hw *ah)
        val &= ah->wow_event_mask;
 
        if (val) {
-
                if (val & AR_WOW_MAGIC_PAT_FOUND)
                        wow_status |= AH_WOW_MAGIC_PATTERN_EN;
-
                if (AR_WOW_PATTERN_FOUND(val))
                        wow_status |= AH_WOW_USER_PATTERN_EN;
-
                if (val & AR_WOW_KEEP_ALIVE_FAIL)
                        wow_status |= AH_WOW_LINK_CHANGE;
-
                if (val & AR_WOW_BEACON_FAIL)
                        wow_status |= AH_WOW_BEACON_MISS;
-
        }
 
        /*
@@ -255,17 +219,6 @@ u32 ath9k_hw_wow_wakeup(struct ath_hw *ah)
                  AR_WOW_CLEAR_EVENTS(REG_READ(ah, AR_WOW_PATTERN)));
 
        /*
-        * tie reset register for AR9002 family of chipsets
-        * NB: not tieing it back might have some repurcussions.
-        */
-
-       if (!AR_SREV_9300_20_OR_LATER(ah)) {
-               REG_SET_BIT(ah, AR_WA, AR_WA_UNTIE_RESET_EN |
-                           AR_WA_POR_SHORT | AR_WA_RESET_EN);
-       }
-
-
-       /*
         * restore the beacon threshold to init value
         */
        REG_WRITE(ah, AR_RSSI_THR, INIT_RSSI_THR);
@@ -277,8 +230,7 @@ u32 ath9k_hw_wow_wakeup(struct ath_hw *ah)
         * reset to our Chip's Power On Reset so that any PCI-E
         * reset from the bus will not reset our chip
         */
-
-       if (AR_SREV_9280_20_OR_LATER(ah) && ah->is_pciexpress)
+       if (ah->is_pciexpress)
                ath9k_hw_configpcipowersave(ah, false);
 
        ah->wow_event_mask = 0;
@@ -298,7 +250,6 @@ void ath9k_hw_wow_enable(struct ath_hw *ah, u32 pattern_enable)
         * are from the 'pattern_enable' in this function and
         * 'pattern_count' of ath9k_hw_wow_apply_pattern()
         */
-
        wow_event_mask = ah->wow_event_mask;
 
        /*
@@ -306,50 +257,15 @@ void ath9k_hw_wow_enable(struct ath_hw *ah, u32 pattern_enable)
         * WOW sleep, we do want the Reset from the PCI-E to disturb
         * our hw state
         */
-
        if (ah->is_pciexpress) {
-
                /*
                 * we need to untie the internal POR (power-on-reset)
                 * to the external PCI-E reset. We also need to tie
                 * the PCI-E Phy reset to the PCI-E reset.
                 */
-
-               if (AR_SREV_9300_20_OR_LATER(ah)) {
-                       set = AR_WA_RESET_EN | AR_WA_POR_SHORT;
-                       clr = AR_WA_UNTIE_RESET_EN | AR_WA_D3_L1_DISABLE;
-                       REG_RMW(ah, AR_WA, set, clr);
-               } else {
-                       if (AR_SREV_9285(ah) || AR_SREV_9287(ah))
-                               set = AR9285_WA_DEFAULT;
-                       else
-                               set = AR9280_WA_DEFAULT;
-
-                       /*
-                        * In AR9280 and AR9285, bit 14 in WA register
-                        * (disable L1) should only be set when device
-                        * enters D3 state and be cleared when device
-                        * comes back to D0
-                        */
-
-                       if (ah->config.pcie_waen & AR_WA_D3_L1_DISABLE)
-                               set |= AR_WA_D3_L1_DISABLE;
-
-                       clr = AR_WA_UNTIE_RESET_EN;
-                       set |= AR_WA_RESET_EN | AR_WA_POR_SHORT;
-                       REG_RMW(ah, AR_WA, set, clr);
-
-                       /*
-                        * for WoW sleep, we reprogram the SerDes so that the
-                        * PLL and CLK REQ are both enabled. This uses more
-                        * power but otherwise WoW sleep is unstable and the
-                        * chip may disappear.
-                        */
-
-                       if (AR_SREV_9285_12_OR_LATER(ah))
-                               ath9k_hw_config_serdes_wow_sleep(ah);
-
-               }
+               set = AR_WA_RESET_EN | AR_WA_POR_SHORT;
+               clr = AR_WA_UNTIE_RESET_EN | AR_WA_D3_L1_DISABLE;
+               REG_RMW(ah, AR_WA, set, clr);
        }
 
        /*
@@ -378,7 +294,6 @@ void ath9k_hw_wow_enable(struct ath_hw *ah, u32 pattern_enable)
         * Program default values for pattern backoff, aifs/slot/KAL count,
         * beacon miss timeout, KAL timeout, etc.
         */
-
        set = AR_WOW_BACK_OFF_SHIFT(AR_WOW_PAT_BACKOFF);
        REG_SET_BIT(ah, AR_WOW_PATTERN, set);
 
@@ -398,7 +313,7 @@ void ath9k_hw_wow_enable(struct ath_hw *ah, u32 pattern_enable)
        /*
         * Keep alive timo in ms except AR9280
         */
-       if (!pattern_enable || AR_SREV_9280(ah))
+       if (!pattern_enable)
                set = AR_WOW_KEEP_ALIVE_NEVER;
        else
                set = KAL_TIMEOUT * 32;
@@ -420,7 +335,6 @@ void ath9k_hw_wow_enable(struct ath_hw *ah, u32 pattern_enable)
        /*
         * Configure MAC WoW Registers
         */
-
        set = 0;
        /* Send keep alive timeouts anyway */
        clr = AR_WOW_KEEP_ALIVE_AUTO_DIS;
@@ -430,16 +344,9 @@ void ath9k_hw_wow_enable(struct ath_hw *ah, u32 pattern_enable)
        else
                set = AR_WOW_KEEP_ALIVE_FAIL_DIS;
 
-       /*
-        * FIXME: For now disable keep alive frame
-        * failure. This seems to sometimes trigger
-        * unnecessary wake up with AR9485 chipsets.
-        */
        set = AR_WOW_KEEP_ALIVE_FAIL_DIS;
-
        REG_RMW(ah, AR_WOW_KEEP_ALIVE, set, clr);
 
-
        /*
         * we are relying on a bmiss failure. ensure we have
         * enough threshold to prevent false positives
@@ -473,14 +380,8 @@ void ath9k_hw_wow_enable(struct ath_hw *ah, u32 pattern_enable)
        set |= AR_WOW_MAC_INTR_EN;
        REG_RMW(ah, AR_WOW_PATTERN, set, clr);
 
-       /*
-        * For AR9285 and later version of chipsets
-        * enable WoW pattern match for packets less
-        * than 256 bytes for all patterns
-        */
-       if (AR_SREV_9285_12_OR_LATER(ah))
-               REG_WRITE(ah, AR_WOW_PATTERN_MATCH_LT_256B,
-                         AR_WOW_PATTERN_SUPPORTED);
+       REG_WRITE(ah, AR_WOW_PATTERN_MATCH_LT_256B,
+                 AR_WOW_PATTERN_SUPPORTED);
 
        /*
         * Set the power states appropriately and enable PME
@@ -488,43 +389,32 @@ void ath9k_hw_wow_enable(struct ath_hw *ah, u32 pattern_enable)
        clr = 0;
        set = AR_PMCTRL_PWR_STATE_D1D3 | AR_PMCTRL_HOST_PME_EN |
              AR_PMCTRL_PWR_PM_CTRL_ENA;
-       /*
-        * This is needed for AR9300 chipsets to wake-up
-        * the host.
-        */
-       if (AR_SREV_9300_20_OR_LATER(ah))
-               clr = AR_PCIE_PM_CTRL_ENA;
 
+       clr = AR_PCIE_PM_CTRL_ENA;
        REG_RMW(ah, AR_PCIE_PM_CTRL, set, clr);
 
-       if (AR_SREV_9462(ah) || AR_SREV_9565(ah)) {
-               /*
-                * this is needed to prevent the chip waking up
-                * the host within 3-4 seconds with certain
-                * platform/BIOS. The fix is to enable
-                * D1 & D3 to match original definition and
-                * also match the OTP value. Anyway this
-                * is more related to SW WOW.
-                */
-               clr = AR_PMCTRL_PWR_STATE_D1D3;
-               REG_CLR_BIT(ah, AR_PCIE_PM_CTRL, clr);
-
-               set = AR_PMCTRL_PWR_STATE_D1D3_REAL;
-               REG_SET_BIT(ah, AR_PCIE_PM_CTRL, set);
-       }
-
+       /*
+        * this is needed to prevent the chip waking up
+        * the host within 3-4 seconds with certain
+        * platform/BIOS. The fix is to enable
+        * D1 & D3 to match original definition and
+        * also match the OTP value. Anyway this
+        * is more related to SW WOW.
+        */
+       clr = AR_PMCTRL_PWR_STATE_D1D3;
+       REG_CLR_BIT(ah, AR_PCIE_PM_CTRL, clr);
 
+       set = AR_PMCTRL_PWR_STATE_D1D3_REAL;
+       REG_SET_BIT(ah, AR_PCIE_PM_CTRL, set);
 
        REG_CLR_BIT(ah, AR_STA_ID1, AR_STA_ID1_PRESERVE_SEQNUM);
 
-       if (AR_SREV_9300_20_OR_LATER(ah)) {
-               /* to bring down WOW power low margin */
-               set = BIT(13);
-               REG_SET_BIT(ah, AR_PCIE_PHY_REG3, set);
-               /* HW WoW */
-               clr = BIT(5);
-               REG_CLR_BIT(ah, AR_PCU_MISC_MODE3, clr);
-       }
+       /* to bring down WOW power low margin */
+       set = BIT(13);
+       REG_SET_BIT(ah, AR_PCIE_PHY_REG3, set);
+       /* HW WoW */
+       clr = BIT(5);
+       REG_CLR_BIT(ah, AR_PCU_MISC_MODE3, clr);
 
        ath9k_hw_set_powermode_wow_sleep(ah);
        ah->wow_event_mask = wow_event_mask;
index 1585cc5..bd98285 100644 (file)
@@ -900,7 +900,7 @@ brcms_c_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb,
                if (supr_status) {
                        update_rate = false;
                        if (supr_status == TX_STATUS_SUPR_BADCH) {
-                               brcms_err(wlc->hw->d11core,
+                               brcms_dbg_ht(wlc->hw->d11core,
                                          "%s: Pkt tx suppressed, illegal channel possibly %d\n",
                                          __func__, CHSPEC_CHANNEL(
                                          wlc->default_bss->chanspec));
index 13e3611..7a585d4 100644 (file)
@@ -13,20 +13,19 @@ config CW1200_WLAN_SDIO
        depends on CW1200 && MMC
        help
          Enable support for the CW1200 connected via an SDIO bus.
+         By default this driver only supports the Sagrad SG901-1091/1098 EVK
+         and similar designs that utilize a hardware reset circuit. To
+         support different CW1200 SDIO designs you will need to override
+         the default platform data by calling cw1200_sdio_set_platform_data()
+         in your board setup file.
 
 config CW1200_WLAN_SPI
        tristate "Support SPI platforms"
        depends on CW1200 && SPI
        help
-         Enables support for the CW1200 connected via a SPI bus.
-
-config CW1200_WLAN_SAGRAD
-       tristate "Support Sagrad SG901-1091/1098 modules"
-       depends on CW1200_WLAN_SDIO
-       help
-         This provides the platform data glue to support the
-         Sagrad SG901-1091/1098 modules in their standard SDIO EVK.
-         It also includes example SPI platform data.
+         Enables support for the CW1200 connected via a SPI bus.  You will
+         need to add appropriate platform data glue in your board setup
+         file.
 
 menu "Driver debug features"
        depends on CW1200 && DEBUG_FS
index c197372..bc6cbf9 100644 (file)
@@ -8,17 +8,15 @@ cw1200_core-y := \
                wsm.o \
                sta.o \
                scan.o \
-               pm.o \
                debug.o
 cw1200_core-$(CONFIG_CW1200_ITP)       += itp.o
+cw1200_core-$(CONFIG_PM)       += pm.o
 
 # CFLAGS_sta.o += -DDEBUG
 
 cw1200_wlan_sdio-y := cw1200_sdio.o
 cw1200_wlan_spi-y := cw1200_spi.o
-cw1200_wlan_sagrad-y := cw1200_sagrad.o
 
 obj-$(CONFIG_CW1200) += cw1200_core.o
 obj-$(CONFIG_CW1200_WLAN_SDIO) += cw1200_wlan_sdio.o
 obj-$(CONFIG_CW1200_WLAN_SPI) += cw1200_wlan_spi.o
-obj-$(CONFIG_CW1200_WLAN_SAGRAD) += cw1200_wlan_sagrad.o
index cf7375f..324b570 100644 (file)
@@ -23,7 +23,7 @@
 #include "bh.h"
 #include "hwio.h"
 #include "wsm.h"
-#include "sbus.h"
+#include "hwbus.h"
 #include "debug.h"
 #include "fwio.h"
 
@@ -103,7 +103,7 @@ void cw1200_irq_handler(struct cw1200_common *priv)
        pr_debug("[BH] irq.\n");
 
        /* Disable Interrupts! */
-       /* NOTE:  sbus_ops->lock already held */
+       /* NOTE:  hwbus_ops->lock already held */
        __cw1200_irq_enable(priv, 0);
 
        if (/* WARN_ON */(priv->bh_error))
@@ -265,8 +265,8 @@ static int cw1200_bh_rx_helper(struct cw1200_common *priv,
         * to the NEXT Message length + 2 Bytes for SKB */
        read_len = read_len + 2;
 
-       alloc_len = priv->sbus_ops->align_size(
-               priv->sbus_priv, read_len);
+       alloc_len = priv->hwbus_ops->align_size(
+               priv->hwbus_priv, read_len);
 
        /* Check if not exceeding CW1200 capabilities */
        if (WARN_ON_ONCE(alloc_len > EFFECTIVE_BUF_SIZE)) {
@@ -384,8 +384,8 @@ static int cw1200_bh_tx_helper(struct cw1200_common *priv,
 
        atomic_add(1, &priv->bh_tx);
 
-       tx_len = priv->sbus_ops->align_size(
-               priv->sbus_priv, tx_len);
+       tx_len = priv->hwbus_ops->align_size(
+               priv->hwbus_priv, tx_len);
 
        /* Check if not exceeding CW1200 capabilities */
        if (WARN_ON_ONCE(tx_len > EFFECTIVE_BUF_SIZE))
@@ -597,15 +597,15 @@ static int cw1200_bh(void *arg)
 
        done:
                /* Re-enable device interrupts */
-               priv->sbus_ops->lock(priv->sbus_priv);
+               priv->hwbus_ops->lock(priv->hwbus_priv);
                __cw1200_irq_enable(priv, 1);
-               priv->sbus_ops->unlock(priv->sbus_priv);
+               priv->hwbus_ops->unlock(priv->hwbus_priv);
        }
 
        /* Explicitly disable device interrupts */
-       priv->sbus_ops->lock(priv->sbus_priv);
+       priv->hwbus_ops->lock(priv->hwbus_priv);
        __cw1200_irq_enable(priv, 0);
-       priv->sbus_ops->unlock(priv->sbus_priv);
+       priv->hwbus_ops->unlock(priv->hwbus_priv);
 
        if (!term) {
                pr_err("[BH] Fatal error, exiting.\n");
index 2aa17ca..95320f2 100644 (file)
@@ -19,7 +19,6 @@
 #define CW1200_H
 
 #include <linux/wait.h>
-#include <linux/version.h>
 #include <linux/mutex.h>
 #include <linux/workqueue.h>
 #include <net/mac80211.h>
@@ -31,7 +30,7 @@
 #include "pm.h"
 
 /* Forward declarations */
-struct sbus_ops;
+struct hwbus_ops;
 struct task_struct;
 struct cw1200_debug_priv;
 struct firmware;
@@ -110,8 +109,8 @@ struct cw1200_common {
        u8 mac_addr[ETH_ALEN];
 
        /* Hardware interface */
-       const struct sbus_ops           *sbus_ops;
-       struct sbus_priv                *sbus_priv;
+       const struct hwbus_ops          *hwbus_ops;
+       struct hwbus_priv               *hwbus_priv;
 
        /* Hardware information */
        enum {
@@ -299,8 +298,8 @@ struct cw1200_sta_priv {
 };
 
 /* interfaces for the drivers */
-int cw1200_core_probe(const struct sbus_ops *sbus_ops,
-                     struct sbus_priv *sbus,
+int cw1200_core_probe(const struct hwbus_ops *hwbus_ops,
+                     struct hwbus_priv *hwbus,
                      struct device *pdev,
                      struct cw1200_common **pself,
                      int ref_clk, const u8 *macaddr,
diff --git a/drivers/net/wireless/cw1200/cw1200_sagrad.c b/drivers/net/wireless/cw1200/cw1200_sagrad.c
deleted file mode 100644 (file)
index a5ada0e..0000000
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * Platform glue data for ST-Ericsson CW1200 driver
- *
- * Copyright (c) 2013, Sagrad, Inc
- * Author: Solomon Peachy <speachy@sagrad.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.
- */
-
-#include <linux/module.h>
-#include <linux/cw1200_platform.h>
-
-MODULE_AUTHOR("Solomon Peachy <speachy@sagrad.com>");
-MODULE_DESCRIPTION("ST-Ericsson CW1200 Platform glue driver");
-MODULE_LICENSE("GPL");
-
-/* Define just one of these.  Feel free to customize as needed */
-#define SAGRAD_1091_1098_EVK_SDIO
-/* #define SAGRAD_1091_1098_EVK_SPI */
-
-#ifdef SAGRAD_1091_1098_EVK_SDIO
-#if 0
-static struct resource cw1200_href_resources[] = {
-       {
-               .start = 215,  /* fix me as appropriate */
-               .end = 215,    /* ditto */
-               .flags = IORESOURCE_IO,
-               .name = "cw1200_wlan_reset",
-       },
-       {
-               .start = 216,  /* fix me as appropriate */
-               .end = 216,    /* ditto */
-               .flags = IORESOURCE_IO,
-               .name = "cw1200_wlan_powerup",
-       },
-       {
-               .start = NOMADIK_GPIO_TO_IRQ(216), /* fix me as appropriate */
-               .end = NOMADIK_GPIO_TO_IRQ(216),   /* ditto */
-               .flags = IORESOURCE_IRQ,
-               .name = "cw1200_wlan_irq",
-       },
-};
-#endif
-
-static int cw1200_power_ctrl(const struct cw1200_platform_data_sdio *pdata,
-                            bool enable)
-{
-       /* Control 3v3 and 1v8 to hardware as appropriate */
-       /* Note this is not needed if it's controlled elsewhere or always on */
-
-       /* May require delay for power to stabilize */
-       return 0;
-}
-
-static int cw1200_clk_ctrl(const struct cw1200_platform_data_sdio *pdata,
-                          bool enable)
-{
-       /* Turn CLK_32K off and on as appropriate. */
-       /* Note this is not needed if it's always on */
-
-       /* May require delay for clock to stabilize */
-       return 0;
-}
-
-static struct cw1200_platform_data_sdio cw1200_platform_data = {
-       .ref_clk = 38400,
-       .have_5ghz = false,
-#if 0
-       .reset = &cw1200_href_resources[0],
-       .powerup = &cw1200_href_resources[1],
-       .irq = &cw1200_href_resources[2],
-#endif
-       .power_ctrl = cw1200_power_ctrl,
-       .clk_ctrl = cw1200_clk_ctrl,
-/*     .macaddr = ??? */
-       .sdd_file = "sdd_sagrad_1091_1098.bin",
-};
-#endif
-
-#ifdef SAGRAD_1091_1098_EVK_SPI
-/* Note that this is an example of integrating into your board support file */
-static struct resource cw1200_href_resources[] = {
-       {
-               .start = GPIO_RF_RESET,
-               .end = GPIO_RF_RESET,
-               .flags = IORESOURCE_IO,
-               .name = "cw1200_wlan_reset",
-       },
-       {
-               .start = GPIO_RF_POWERUP,
-               .end = GPIO_RF_POWERUP,
-               .flags = IORESOURCE_IO,
-               .name = "cw1200_wlan_powerup",
-       },
-};
-
-static int cw1200_power_ctrl(const struct cw1200_platform_data_spi *pdata,
-                            bool enable)
-{
-       /* Control 3v3 and 1v8 to hardware as appropriate */
-       /* Note this is not needed if it's controlled elsewhere or always on */
-
-       /* May require delay for power to stabilize */
-       return 0;
-}
-static int cw1200_clk_ctrl(const struct cw1200_platform_data_spi *pdata,
-                          bool enable)
-{
-       /* Turn CLK_32K off and on as appropriate. */
-       /* Note this is not needed if it's always on */
-
-       /* May require delay for clock to stabilize */
-       return 0;
-}
-
-static struct cw1200_platform_data_spi cw1200_platform_data = {
-       .ref_clk = 38400,
-       .spi_bits_per_word = 16,
-       .reset = &cw1200_href_resources[0],
-       .powerup = &cw1200_href_resources[1],
-       .power_ctrl = cw1200_power_ctrl,
-       .clk_ctrl = cw1200_clk_ctrl,
-/*     .macaddr = ??? */
-       .sdd_file = "sdd_sagrad_1091_1098.bin",
-};
-static struct spi_board_info myboard_spi_devices[] __initdata = {
-       {
-               .modalias = "cw1200_wlan_spi",
-               .max_speed_hz = 10000000, /* 52MHz Max */
-               .bus_num = 0,
-               .irq = WIFI_IRQ,
-               .platform_data = &cw1200_platform_data,
-               .chip_select = 0,
-       },
-};
-#endif
-
-
-const void *cw1200_get_platform_data(void)
-{
-       return &cw1200_platform_data;
-}
-EXPORT_SYMBOL_GPL(cw1200_get_platform_data);
index f6e2219..bb1f405 100644 (file)
@@ -9,7 +9,6 @@
  * published by the Free Software Foundation.
  */
 
-#include <linux/version.h>
 #include <linux/module.h>
 #include <linux/gpio.h>
 #include <linux/delay.h>
@@ -20,8 +19,8 @@
 #include <net/mac80211.h>
 
 #include "cw1200.h"
-#include "sbus.h"
-#include <linux/cw1200_platform.h>
+#include "hwbus.h"
+#include <linux/platform_data/net-cw1200.h>
 #include "hwio.h"
 
 MODULE_AUTHOR("Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>");
@@ -30,7 +29,22 @@ MODULE_LICENSE("GPL");
 
 #define SDIO_BLOCK_SIZE (512)
 
-struct sbus_priv {
+/* Default platform data for Sagrad modules */
+static struct cw1200_platform_data_sdio sagrad_109x_evk_platform_data = {
+       .ref_clk = 38400,
+       .have_5ghz = false,
+       .sdd_file = "sdd_sagrad_1091_1098.bin",
+};
+
+/* Allow platform data to be overridden */
+static struct cw1200_platform_data_sdio *global_plat_data = &sagrad_109x_evk_platform_data;
+
+void __init cw1200_sdio_set_platform_data(struct cw1200_platform_data_sdio *pdata)
+{
+       global_plat_data = pdata;
+}
+
+struct hwbus_priv {
        struct sdio_func        *func;
        struct cw1200_common    *core;
        const struct cw1200_platform_data_sdio *pdata;
@@ -49,35 +63,35 @@ static const struct sdio_device_id cw1200_sdio_ids[] = {
        { /* end: all zeroes */                 },
 };
 
-/* sbus_ops implemetation */
+/* hwbus_ops implemetation */
 
-static int cw1200_sdio_memcpy_fromio(struct sbus_priv *self,
+static int cw1200_sdio_memcpy_fromio(struct hwbus_priv *self,
                                     unsigned int addr,
                                     void *dst, int count)
 {
        return sdio_memcpy_fromio(self->func, dst, addr, count);
 }
 
-static int cw1200_sdio_memcpy_toio(struct sbus_priv *self,
+static int cw1200_sdio_memcpy_toio(struct hwbus_priv *self,
                                   unsigned int addr,
                                   const void *src, int count)
 {
        return sdio_memcpy_toio(self->func, addr, (void *)src, count);
 }
 
-static void cw1200_sdio_lock(struct sbus_priv *self)
+static void cw1200_sdio_lock(struct hwbus_priv *self)
 {
        sdio_claim_host(self->func);
 }
 
-static void cw1200_sdio_unlock(struct sbus_priv *self)
+static void cw1200_sdio_unlock(struct hwbus_priv *self)
 {
        sdio_release_host(self->func);
 }
 
 static void cw1200_sdio_irq_handler(struct sdio_func *func)
 {
-       struct sbus_priv *self = sdio_get_drvdata(func);
+       struct hwbus_priv *self = sdio_get_drvdata(func);
 
        /* note:  sdio_host already claimed here. */
        if (self->core)
@@ -91,7 +105,7 @@ static irqreturn_t cw1200_gpio_hardirq(int irq, void *dev_id)
 
 static irqreturn_t cw1200_gpio_irq(int irq, void *dev_id)
 {
-       struct sbus_priv *self = dev_id;
+       struct hwbus_priv *self = dev_id;
 
        if (self->core) {
                sdio_claim_host(self->func);
@@ -103,10 +117,9 @@ static irqreturn_t cw1200_gpio_irq(int irq, void *dev_id)
        }
 }
 
-static int cw1200_request_irq(struct sbus_priv *self)
+static int cw1200_request_irq(struct hwbus_priv *self)
 {
        int ret;
-       const struct resource *irq = self->pdata->irq;
        u8 cccr;
 
        cccr = sdio_f0_readb(self->func, SDIO_CCCR_IENx, &ret);
@@ -123,15 +136,15 @@ static int cw1200_request_irq(struct sbus_priv *self)
        if (WARN_ON(ret))
                goto err;
 
-       ret = enable_irq_wake(irq->start);
+       ret = enable_irq_wake(self->pdata->irq);
        if (WARN_ON(ret))
                goto err;
 
        /* Request the IRQ */
-       ret =  request_threaded_irq(irq->start, cw1200_gpio_hardirq,
+       ret =  request_threaded_irq(self->pdata->irq, cw1200_gpio_hardirq,
                                    cw1200_gpio_irq,
                                    IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
-                                   irq->name, self);
+                                   "cw1200_wlan_irq", self);
        if (WARN_ON(ret))
                goto err;
 
@@ -141,7 +154,7 @@ err:
        return ret;
 }
 
-static int cw1200_sdio_irq_subscribe(struct sbus_priv *self)
+static int cw1200_sdio_irq_subscribe(struct hwbus_priv *self)
 {
        int ret = 0;
 
@@ -156,15 +169,15 @@ static int cw1200_sdio_irq_subscribe(struct sbus_priv *self)
        return ret;
 }
 
-static int cw1200_sdio_irq_unsubscribe(struct sbus_priv *self)
+static int cw1200_sdio_irq_unsubscribe(struct hwbus_priv *self)
 {
        int ret = 0;
 
        pr_debug("SW IRQ unsubscribe\n");
 
        if (self->pdata->irq) {
-               disable_irq_wake(self->pdata->irq->start);
-               free_irq(self->pdata->irq->start, self);
+               disable_irq_wake(self->pdata->irq);
+               free_irq(self->pdata->irq, self);
        } else {
                sdio_claim_host(self->func);
                ret = sdio_release_irq(self->func);
@@ -175,12 +188,10 @@ static int cw1200_sdio_irq_unsubscribe(struct sbus_priv *self)
 
 static int cw1200_sdio_off(const struct cw1200_platform_data_sdio *pdata)
 {
-       const struct resource *reset = pdata->reset;
-
-       if (reset) {
-               gpio_set_value(reset->start, 0);
+       if (pdata->reset) {
+               gpio_set_value(pdata->reset, 0);
                msleep(30); /* Min is 2 * CLK32K cycles */
-               gpio_free(reset->start);
+               gpio_free(pdata->reset);
        }
 
        if (pdata->power_ctrl)
@@ -193,20 +204,17 @@ static int cw1200_sdio_off(const struct cw1200_platform_data_sdio *pdata)
 
 static int cw1200_sdio_on(const struct cw1200_platform_data_sdio *pdata)
 {
-       const struct resource *reset = pdata->reset;
-       const struct resource *powerup = pdata->reset;
-
        /* Ensure I/Os are pulled low */
-       if (reset) {
-               gpio_request(reset->start, reset->name);
-               gpio_direction_output(reset->start, 0);
+       if (pdata->reset) {
+               gpio_request(pdata->reset, "cw1200_wlan_reset");
+               gpio_direction_output(pdata->reset, 0);
        }
-       if (powerup) {
-               gpio_request(powerup->start, powerup->name);
-               gpio_direction_output(powerup->start, 0);
+       if (pdata->powerup) {
+               gpio_request(pdata->powerup, "cw1200_wlan_powerup");
+               gpio_direction_output(pdata->powerup, 0);
        }
-       if (reset || powerup)
-               msleep(50); /* Settle time */
+       if (pdata->reset || pdata->powerup)
+               msleep(10); /* Settle time? */
 
        /* Enable 3v3 and 1v8 to hardware */
        if (pdata->power_ctrl) {
@@ -226,19 +234,19 @@ static int cw1200_sdio_on(const struct cw1200_platform_data_sdio *pdata)
        }
 
        /* Enable POWERUP signal */
-       if (powerup) {
-               gpio_set_value(powerup->start, 1);
+       if (pdata->powerup) {
+               gpio_set_value(pdata->powerup, 1);
                msleep(250); /* or more..? */
        }
        /* Enable RSTn signal */
-       if (reset) {
-               gpio_set_value(reset->start, 1);
+       if (pdata->reset) {
+               gpio_set_value(pdata->reset, 1);
                msleep(50); /* Or more..? */
        }
        return 0;
 }
 
-static size_t cw1200_sdio_align_size(struct sbus_priv *self, size_t size)
+static size_t cw1200_sdio_align_size(struct hwbus_priv *self, size_t size)
 {
        if (self->pdata->no_nptb)
                size = round_up(size, SDIO_BLOCK_SIZE);
@@ -248,18 +256,18 @@ static size_t cw1200_sdio_align_size(struct sbus_priv *self, size_t size)
        return size;
 }
 
-static int cw1200_sdio_pm(struct sbus_priv *self, bool suspend)
+static int cw1200_sdio_pm(struct hwbus_priv *self, bool suspend)
 {
        int ret = 0;
 
        if (self->pdata->irq)
-               ret = irq_set_irq_wake(self->pdata->irq->start, suspend);
+               ret = irq_set_irq_wake(self->pdata->irq, suspend);
        return ret;
 }
 
-static struct sbus_ops cw1200_sdio_sbus_ops = {
-       .sbus_memcpy_fromio     = cw1200_sdio_memcpy_fromio,
-       .sbus_memcpy_toio       = cw1200_sdio_memcpy_toio,
+static struct hwbus_ops cw1200_sdio_hwbus_ops = {
+       .hwbus_memcpy_fromio    = cw1200_sdio_memcpy_fromio,
+       .hwbus_memcpy_toio      = cw1200_sdio_memcpy_toio,
        .lock                   = cw1200_sdio_lock,
        .unlock                 = cw1200_sdio_unlock,
        .align_size             = cw1200_sdio_align_size,
@@ -268,26 +276,26 @@ static struct sbus_ops cw1200_sdio_sbus_ops = {
 
 /* Probe Function to be called by SDIO stack when device is discovered */
 static int cw1200_sdio_probe(struct sdio_func *func,
-                                      const struct sdio_device_id *id)
+                            const struct sdio_device_id *id)
 {
-       struct sbus_priv *self;
+       struct hwbus_priv *self;
        int status;
 
        pr_info("cw1200_wlan_sdio: Probe called\n");
 
-       /* We are only able to handle the wlan function */
+       /* We are only able to handle the wlan function */
        if (func->num != 0x01)
                return -ENODEV;
 
        self = kzalloc(sizeof(*self), GFP_KERNEL);
        if (!self) {
-               pr_err("Can't allocate SDIO sbus_priv.\n");
+               pr_err("Can't allocate SDIO hwbus_priv.\n");
                return -ENOMEM;
        }
 
        func->card->quirks |= MMC_QUIRK_LENIENT_FN0;
 
-       self->pdata = cw1200_get_platform_data();
+       self->pdata = global_plat_data; /* FIXME */
        self->func = func;
        sdio_set_drvdata(func, self);
        sdio_claim_host(func);
@@ -296,7 +304,7 @@ static int cw1200_sdio_probe(struct sdio_func *func,
 
        status = cw1200_sdio_irq_subscribe(self);
 
-       status = cw1200_core_probe(&cw1200_sdio_sbus_ops,
+       status = cw1200_core_probe(&cw1200_sdio_hwbus_ops,
                                   self, &func->dev, &self->core,
                                   self->pdata->ref_clk,
                                   self->pdata->macaddr,
@@ -318,7 +326,7 @@ static int cw1200_sdio_probe(struct sdio_func *func,
  * device is disconnected */
 static void cw1200_sdio_disconnect(struct sdio_func *func)
 {
-       struct sbus_priv *self = sdio_get_drvdata(func);
+       struct hwbus_priv *self = sdio_get_drvdata(func);
 
        if (self) {
                cw1200_sdio_irq_unsubscribe(self);
@@ -334,11 +342,12 @@ static void cw1200_sdio_disconnect(struct sdio_func *func)
        }
 }
 
+#ifdef CONFIG_PM
 static int cw1200_sdio_suspend(struct device *dev)
 {
        int ret;
        struct sdio_func *func = dev_to_sdio_func(dev);
-       struct sbus_priv *self = sdio_get_drvdata(func);
+       struct hwbus_priv *self = sdio_get_drvdata(func);
 
        if (!cw1200_can_suspend(self->core))
                return -EAGAIN;
@@ -360,15 +369,18 @@ static const struct dev_pm_ops cw1200_pm_ops = {
        .suspend = cw1200_sdio_suspend,
        .resume = cw1200_sdio_resume,
 };
+#endif
 
 static struct sdio_driver sdio_driver = {
        .name           = "cw1200_wlan_sdio",
        .id_table       = cw1200_sdio_ids,
        .probe          = cw1200_sdio_probe,
        .remove         = cw1200_sdio_disconnect,
+#ifdef CONFIG_PM
        .drv = {
                .pm = &cw1200_pm_ops,
        }
+#endif
 };
 
 /* Init Module function -> Called by insmod */
@@ -377,7 +389,8 @@ static int __init cw1200_sdio_init(void)
        const struct cw1200_platform_data_sdio *pdata;
        int ret;
 
-       pdata = cw1200_get_platform_data();
+       /* FIXME -- this won't support multiple devices */
+       pdata = global_plat_data;
 
        if (cw1200_sdio_on(pdata)) {
                ret = -1;
@@ -399,7 +412,9 @@ err:
 static void __exit cw1200_sdio_exit(void)
 {
        const struct cw1200_platform_data_sdio *pdata;
-       pdata = cw1200_get_platform_data();
+
+       /* FIXME -- this won't support multiple devices */
+       pdata = global_plat_data;
        sdio_unregister_driver(&sdio_driver);
        cw1200_sdio_off(pdata);
 }
index 04af685..e58f0a5 100644 (file)
@@ -13,7 +13,6 @@
  * published by the Free Software Foundation.
  */
 
-#include <linux/version.h>
 #include <linux/module.h>
 #include <linux/gpio.h>
 #include <linux/delay.h>
@@ -25,8 +24,8 @@
 #include <linux/device.h>
 
 #include "cw1200.h"
-#include "sbus.h"
-#include <linux/cw1200_platform.h>
+#include "hwbus.h"
+#include <linux/platform_data/net-cw1200.h>
 #include "hwio.h"
 
 MODULE_AUTHOR("Solomon Peachy <speachy@sagrad.com>");
@@ -36,7 +35,7 @@ MODULE_ALIAS("spi:cw1200_wlan_spi");
 
 /* #define SPI_DEBUG */
 
-struct sbus_priv {
+struct hwbus_priv {
        struct spi_device       *func;
        struct cw1200_common    *core;
        const struct cw1200_platform_data_spi *pdata;
@@ -59,7 +58,7 @@ struct sbus_priv {
 
 */
 
-static int cw1200_spi_memcpy_fromio(struct sbus_priv *self,
+static int cw1200_spi_memcpy_fromio(struct hwbus_priv *self,
                                     unsigned int addr,
                                     void *dst, int count)
 {
@@ -120,7 +119,7 @@ static int cw1200_spi_memcpy_fromio(struct sbus_priv *self,
        return ret;
 }
 
-static int cw1200_spi_memcpy_toio(struct sbus_priv *self,
+static int cw1200_spi_memcpy_toio(struct hwbus_priv *self,
                                   unsigned int addr,
                                   const void *src, int count)
 {
@@ -188,7 +187,7 @@ static int cw1200_spi_memcpy_toio(struct sbus_priv *self,
        return rval;
 }
 
-static void cw1200_spi_lock(struct sbus_priv *self)
+static void cw1200_spi_lock(struct hwbus_priv *self)
 {
        unsigned long flags;
 
@@ -210,7 +209,7 @@ static void cw1200_spi_lock(struct sbus_priv *self)
        return;
 }
 
-static void cw1200_spi_unlock(struct sbus_priv *self)
+static void cw1200_spi_unlock(struct hwbus_priv *self)
 {
        unsigned long flags;
 
@@ -222,7 +221,7 @@ static void cw1200_spi_unlock(struct sbus_priv *self)
 
 static irqreturn_t cw1200_spi_irq_handler(int irq, void *dev_id)
 {
-       struct sbus_priv *self = dev_id;
+       struct hwbus_priv *self = dev_id;
 
        if (self->core) {
                cw1200_irq_handler(self->core);
@@ -232,7 +231,7 @@ static irqreturn_t cw1200_spi_irq_handler(int irq, void *dev_id)
        }
 }
 
-static int cw1200_spi_irq_subscribe(struct sbus_priv *self)
+static int cw1200_spi_irq_subscribe(struct hwbus_priv *self)
 {
        int ret;
 
@@ -256,7 +255,7 @@ exit:
        return ret;
 }
 
-static int cw1200_spi_irq_unsubscribe(struct sbus_priv *self)
+static int cw1200_spi_irq_unsubscribe(struct hwbus_priv *self)
 {
        int ret = 0;
 
@@ -269,12 +268,10 @@ static int cw1200_spi_irq_unsubscribe(struct sbus_priv *self)
 
 static int cw1200_spi_off(const struct cw1200_platform_data_spi *pdata)
 {
-       const struct resource *reset = pdata->reset;
-
-       if (reset) {
-               gpio_set_value(reset->start, 0);
+       if (pdata->reset) {
+               gpio_set_value(pdata->reset, 0);
                msleep(30); /* Min is 2 * CLK32K cycles */
-               gpio_free(reset->start);
+               gpio_free(pdata->reset);
        }
 
        if (pdata->power_ctrl)
@@ -287,19 +284,16 @@ static int cw1200_spi_off(const struct cw1200_platform_data_spi *pdata)
 
 static int cw1200_spi_on(const struct cw1200_platform_data_spi *pdata)
 {
-       const struct resource *reset = pdata->reset;
-       const struct resource *powerup = pdata->reset;
-
        /* Ensure I/Os are pulled low */
-       if (reset) {
-               gpio_request(reset->start, reset->name);
-               gpio_direction_output(reset->start, 0);
+       if (pdata->reset) {
+               gpio_request(pdata->reset, "cw1200_wlan_reset");
+               gpio_direction_output(pdata->reset, 0);
        }
-       if (powerup) {
-               gpio_request(powerup->start, powerup->name);
-               gpio_direction_output(powerup->start, 0);
+       if (pdata->powerup) {
+               gpio_request(pdata->powerup, "cw1200_wlan_powerup");
+               gpio_direction_output(pdata->powerup, 0);
        }
-       if (reset || powerup)
+       if (pdata->reset || pdata->powerup)
                msleep(10); /* Settle time? */
 
        /* Enable 3v3 and 1v8 to hardware */
@@ -320,31 +314,31 @@ static int cw1200_spi_on(const struct cw1200_platform_data_spi *pdata)
        }
 
        /* Enable POWERUP signal */
-       if (powerup) {
-               gpio_set_value(powerup->start, 1);
+       if (pdata->powerup) {
+               gpio_set_value(pdata->powerup, 1);
                msleep(250); /* or more..? */
        }
        /* Enable RSTn signal */
-       if (reset) {
-               gpio_set_value(reset->start, 1);
+       if (pdata->reset) {
+               gpio_set_value(pdata->reset, 1);
                msleep(50); /* Or more..? */
        }
        return 0;
 }
 
-static size_t cw1200_spi_align_size(struct sbus_priv *self, size_t size)
+static size_t cw1200_spi_align_size(struct hwbus_priv *self, size_t size)
 {
        return size & 1 ? size + 1 : size;
 }
 
-static int cw1200_spi_pm(struct sbus_priv *self, bool suspend)
+static int cw1200_spi_pm(struct hwbus_priv *self, bool suspend)
 {
        return irq_set_irq_wake(self->func->irq, suspend);
 }
 
-static struct sbus_ops cw1200_spi_sbus_ops = {
-       .sbus_memcpy_fromio     = cw1200_spi_memcpy_fromio,
-       .sbus_memcpy_toio       = cw1200_spi_memcpy_toio,
+static struct hwbus_ops cw1200_spi_hwbus_ops = {
+       .hwbus_memcpy_fromio    = cw1200_spi_memcpy_fromio,
+       .hwbus_memcpy_toio      = cw1200_spi_memcpy_toio,
        .lock                   = cw1200_spi_lock,
        .unlock                 = cw1200_spi_unlock,
        .align_size             = cw1200_spi_align_size,
@@ -356,7 +350,7 @@ static int cw1200_spi_probe(struct spi_device *func)
 {
        const struct cw1200_platform_data_spi *plat_data =
                func->dev.platform_data;
-       struct sbus_priv *self;
+       struct hwbus_priv *self;
        int status;
 
        /* Sanity check speed */
@@ -390,7 +384,7 @@ static int cw1200_spi_probe(struct spi_device *func)
 
        self = kzalloc(sizeof(*self), GFP_KERNEL);
        if (!self) {
-               pr_err("Can't allocate SPI sbus_priv.");
+               pr_err("Can't allocate SPI hwbus_priv.");
                return -ENOMEM;
        }
 
@@ -402,7 +396,7 @@ static int cw1200_spi_probe(struct spi_device *func)
 
        status = cw1200_spi_irq_subscribe(self);
 
-       status = cw1200_core_probe(&cw1200_spi_sbus_ops,
+       status = cw1200_core_probe(&cw1200_spi_hwbus_ops,
                                   self, &func->dev, &self->core,
                                   self->pdata->ref_clk,
                                   self->pdata->macaddr,
@@ -421,7 +415,7 @@ static int cw1200_spi_probe(struct spi_device *func)
 /* Disconnect Function to be called by SPI stack when device is disconnected */
 static int cw1200_spi_disconnect(struct spi_device *func)
 {
-       struct sbus_priv *self = spi_get_drvdata(func);
+       struct hwbus_priv *self = spi_get_drvdata(func);
 
        if (self) {
                cw1200_spi_irq_unsubscribe(self);
@@ -436,9 +430,10 @@ static int cw1200_spi_disconnect(struct spi_device *func)
        return 0;
 }
 
+#ifdef CONFIG_PM
 static int cw1200_spi_suspend(struct device *dev, pm_message_t state)
 {
-       struct sbus_priv *self = spi_get_drvdata(to_spi_device(dev));
+       struct hwbus_priv *self = spi_get_drvdata(to_spi_device(dev));
 
        if (!cw1200_can_suspend(self->core))
                return -EAGAIN;
@@ -451,6 +446,7 @@ static int cw1200_spi_resume(struct device *dev)
 {
        return 0;
 }
+#endif
 
 static struct spi_driver spi_driver = {
        .probe          = cw1200_spi_probe,
@@ -459,22 +455,11 @@ static struct spi_driver spi_driver = {
                .name           = "cw1200_wlan_spi",
                .bus            = &spi_bus_type,
                .owner          = THIS_MODULE,
+#ifdef CONFIG_PM
                .suspend        = cw1200_spi_suspend,
                .resume         = cw1200_spi_resume,
+#endif
        },
 };
 
-/* Init Module function -> Called by insmod */
-static int __init cw1200_spi_init(void)
-{
-       return spi_register_driver(&spi_driver);
-}
-
-/* Called at Driver Unloading */
-static void __exit cw1200_spi_exit(void)
-{
-       spi_unregister_driver(&spi_driver);
-}
-
-module_init(cw1200_spi_init);
-module_exit(cw1200_spi_exit);
+module_spi_driver(spi_driver);
index b815181..1596b70 100644 (file)
@@ -357,12 +357,6 @@ static const struct file_operations fops_counters = {
        .owner = THIS_MODULE,
 };
 
-static int cw1200_generic_open(struct inode *inode, struct file *file)
-{
-       file->private_data = inode->i_private;
-       return 0;
-}
-
 #ifdef CONFIG_CW1200_ETF
 static int cw1200_etf_out_show(struct seq_file *seq, void *v)
 {
@@ -403,13 +397,13 @@ struct etf_req_msg;
 static int etf_request(struct cw1200_common *priv,
                       struct etf_req_msg *msg, u32 len);
 
-#define MAX_RX_SZE 2600
+#define MAX_RX_SIZE 2600
 
 struct etf_in_state {
        struct cw1200_common *priv;
-       u32 total_len;
-       u8 buf[MAX_RX_SZE];
-       u32 written;
+       u16 total_len;
+       u16 written;
+       u8 buf[MAX_RX_SIZE];
 };
 
 static int cw1200_etf_in_open(struct inode *inode, struct file *file)
@@ -454,6 +448,11 @@ static ssize_t cw1200_etf_in_write(struct file *file,
                        return -EFAULT;
                }
 
+               if (etf->total_len > MAX_RX_SIZE) {
+                       pr_err("requested length > MAX_RX_SIZE\n");
+                       return -EINVAL;
+               }
+
                written += sizeof(etf->total_len);
                count -= sizeof(etf->total_len);
        }
@@ -461,6 +460,11 @@ static ssize_t cw1200_etf_in_write(struct file *file,
        if (!count)
                goto done;
 
+       if (count > (etf->total_len - written)) {
+               pr_err("Tried to write > MAX_RX_SIZE\n");
+               return -EINVAL;
+       }
+
        if (copy_from_user(etf->buf + etf->written, user_buf + written,
                           count)) {
                pr_err("copy_from_user (payload %zu) failed\n", count);
@@ -511,7 +515,7 @@ static ssize_t cw1200_wsm_dumps(struct file *file,
 }
 
 static const struct file_operations fops_wsm_dumps = {
-       .open = cw1200_generic_open,
+       .open = simple_open,
        .write = cw1200_wsm_dumps,
        .llseek = default_llseek,
 };
index ad01cd2..427c9f2 100644 (file)
@@ -22,7 +22,7 @@
 #include "cw1200.h"
 #include "fwio.h"
 #include "hwio.h"
-#include "sbus.h"
+#include "hwbus.h"
 #include "bh.h"
 
 static int cw1200_get_hw_type(u32 config_reg_val, int *major_revision)
@@ -489,9 +489,9 @@ int cw1200_load_firmware(struct cw1200_common *priv)
        }
 
        /* Enable interrupt signalling */
-       priv->sbus_ops->lock(priv->sbus_priv);
+       priv->hwbus_ops->lock(priv->hwbus_priv);
        ret = __cw1200_irq_enable(priv, 1);
-       priv->sbus_ops->unlock(priv->sbus_priv);
+       priv->hwbus_ops->unlock(priv->hwbus_priv);
        if (ret < 0)
                goto unsubscribe;
 
@@ -518,8 +518,8 @@ out:
 
 unsubscribe:
        /* Disable interrupt signalling */
-       priv->sbus_ops->lock(priv->sbus_priv);
+       priv->hwbus_ops->lock(priv->hwbus_priv);
        ret = __cw1200_irq_enable(priv, 0);
-       priv->sbus_ops->unlock(priv->sbus_priv);
+       priv->hwbus_ops->unlock(priv->hwbus_priv);
        return ret;
 }
diff --git a/drivers/net/wireless/cw1200/hwbus.h b/drivers/net/wireless/cw1200/hwbus.h
new file mode 100644 (file)
index 0000000..8b2fc83
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * Common hwbus abstraction layer interface for cw1200 wireless driver
+ *
+ * Copyright (c) 2010, ST-Ericsson
+ * Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
+ *
+ * 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 CW1200_HWBUS_H
+#define CW1200_HWBUS_H
+
+struct hwbus_priv;
+
+void cw1200_irq_handler(struct cw1200_common *priv);
+
+/* This MUST be wrapped with hwbus_ops->lock/unlock! */
+int __cw1200_irq_enable(struct cw1200_common *priv, int enable);
+
+struct hwbus_ops {
+       int (*hwbus_memcpy_fromio)(struct hwbus_priv *self, unsigned int addr,
+                                       void *dst, int count);
+       int (*hwbus_memcpy_toio)(struct hwbus_priv *self, unsigned int addr,
+                                       const void *src, int count);
+       void (*lock)(struct hwbus_priv *self);
+       void (*unlock)(struct hwbus_priv *self);
+       size_t (*align_size)(struct hwbus_priv *self, size_t size);
+       int (*power_mgmt)(struct hwbus_priv *self, bool suspend);
+};
+
+#endif /* CW1200_HWBUS_H */
index 1af7b3d..dad3fb3 100644 (file)
@@ -18,7 +18,7 @@
 
 #include "cw1200.h"
 #include "hwio.h"
-#include "sbus.h"
+#include "hwbus.h"
 
  /* Sdio addr is 4*spi_addr */
 #define SPI_REG_ADDR_TO_SDIO(spi_reg_addr) ((spi_reg_addr) << 2)
@@ -46,7 +46,7 @@ static int __cw1200_reg_read(struct cw1200_common *priv, u16 addr,
        addr_sdio = SPI_REG_ADDR_TO_SDIO(addr);
        sdio_reg_addr_17bit = SDIO_ADDR17BIT(buf_id, 0, 0, addr_sdio);
 
-       return priv->sbus_ops->sbus_memcpy_fromio(priv->sbus_priv,
+       return priv->hwbus_ops->hwbus_memcpy_fromio(priv->hwbus_priv,
                                                  sdio_reg_addr_17bit,
                                                  buf, buf_len);
 }
@@ -61,7 +61,7 @@ static int __cw1200_reg_write(struct cw1200_common *priv, u16 addr,
        addr_sdio = SPI_REG_ADDR_TO_SDIO(addr);
        sdio_reg_addr_17bit = SDIO_ADDR17BIT(buf_id, 0, 0, addr_sdio);
 
-       return priv->sbus_ops->sbus_memcpy_toio(priv->sbus_priv,
+       return priv->hwbus_ops->hwbus_memcpy_toio(priv->hwbus_priv,
                                                sdio_reg_addr_17bit,
                                                buf, buf_len);
 }
@@ -100,9 +100,9 @@ int cw1200_reg_read(struct cw1200_common *priv, u16 addr, void *buf,
                        size_t buf_len)
 {
        int ret;
-       priv->sbus_ops->lock(priv->sbus_priv);
+       priv->hwbus_ops->lock(priv->hwbus_priv);
        ret = __cw1200_reg_read(priv, addr, buf, buf_len, 0);
-       priv->sbus_ops->unlock(priv->sbus_priv);
+       priv->hwbus_ops->unlock(priv->hwbus_priv);
        return ret;
 }
 
@@ -110,9 +110,9 @@ int cw1200_reg_write(struct cw1200_common *priv, u16 addr, const void *buf,
                        size_t buf_len)
 {
        int ret;
-       priv->sbus_ops->lock(priv->sbus_priv);
+       priv->hwbus_ops->lock(priv->hwbus_priv);
        ret = __cw1200_reg_write(priv, addr, buf, buf_len, 0);
-       priv->sbus_ops->unlock(priv->sbus_priv);
+       priv->hwbus_ops->unlock(priv->hwbus_priv);
        return ret;
 }
 
@@ -121,7 +121,7 @@ int cw1200_data_read(struct cw1200_common *priv, void *buf, size_t buf_len)
        int ret, retry = 1;
        int buf_id_rx = priv->buf_id_rx;
 
-       priv->sbus_ops->lock(priv->sbus_priv);
+       priv->hwbus_ops->lock(priv->hwbus_priv);
 
        while (retry <= MAX_RETRY) {
                ret = __cw1200_reg_read(priv,
@@ -138,7 +138,7 @@ int cw1200_data_read(struct cw1200_common *priv, void *buf, size_t buf_len)
                }
        }
 
-       priv->sbus_ops->unlock(priv->sbus_priv);
+       priv->hwbus_ops->unlock(priv->hwbus_priv);
        return ret;
 }
 
@@ -148,7 +148,7 @@ int cw1200_data_write(struct cw1200_common *priv, const void *buf,
        int ret, retry = 1;
        int buf_id_tx = priv->buf_id_tx;
 
-       priv->sbus_ops->lock(priv->sbus_priv);
+       priv->hwbus_ops->lock(priv->hwbus_priv);
 
        while (retry <= MAX_RETRY) {
                ret = __cw1200_reg_write(priv,
@@ -165,7 +165,7 @@ int cw1200_data_write(struct cw1200_common *priv, const void *buf,
                }
        }
 
-       priv->sbus_ops->unlock(priv->sbus_priv);
+       priv->hwbus_ops->unlock(priv->hwbus_priv);
        return ret;
 }
 
@@ -178,10 +178,9 @@ int cw1200_indirect_read(struct cw1200_common *priv, u32 addr, void *buf,
        if ((buf_len / 2) >= 0x1000) {
                pr_err("Can't read more than 0xfff words.\n");
                return -EINVAL;
-               goto out;
        }
 
-       priv->sbus_ops->lock(priv->sbus_priv);
+       priv->hwbus_ops->lock(priv->hwbus_priv);
        /* Write address */
        ret = __cw1200_reg_write_32(priv, ST90TDS_SRAM_BASE_ADDR_REG_ID, addr);
        if (ret < 0) {
@@ -230,7 +229,7 @@ int cw1200_indirect_read(struct cw1200_common *priv, u32 addr, void *buf,
        }
 
 out:
-       priv->sbus_ops->unlock(priv->sbus_priv);
+       priv->hwbus_ops->unlock(priv->hwbus_priv);
        return ret;
 }
 
@@ -244,7 +243,7 @@ int cw1200_apb_write(struct cw1200_common *priv, u32 addr, const void *buf,
                return -EINVAL;
        }
 
-       priv->sbus_ops->lock(priv->sbus_priv);
+       priv->hwbus_ops->lock(priv->hwbus_priv);
 
        /* Write address */
        ret = __cw1200_reg_write_32(priv, ST90TDS_SRAM_BASE_ADDR_REG_ID, addr);
@@ -262,7 +261,7 @@ int cw1200_apb_write(struct cw1200_common *priv, u32 addr, const void *buf,
        }
 
 out:
-       priv->sbus_ops->unlock(priv->sbus_priv);
+       priv->hwbus_ops->unlock(priv->hwbus_priv);
        return ret;
 }
 
index 8426d3d..2ea1bad 100644 (file)
@@ -31,7 +31,7 @@
 
 #include "cw1200.h"
 #include "txrx.h"
-#include "sbus.h"
+#include "hwbus.h"
 #include "fwio.h"
 #include "hwio.h"
 #include "bh.h"
@@ -234,8 +234,10 @@ static const struct ieee80211_ops cw1200_ops = {
        .get_stats              = cw1200_get_stats,
        .ampdu_action           = cw1200_ampdu_action,
        .flush                  = cw1200_flush,
+#ifdef CONFIG_PM
        .suspend                = cw1200_wow_suspend,
        .resume                 = cw1200_wow_resume,
+#endif
        /* Intentionally not offloaded:                                 */
        /*.channel_switch       = cw1200_channel_switch,                */
        /*.remain_on_channel    = cw1200_remain_on_channel,             */
@@ -292,10 +294,12 @@ static struct ieee80211_hw *cw1200_init_common(const u8 *macaddr,
                                          BIT(NL80211_IFTYPE_P2P_CLIENT) |
                                          BIT(NL80211_IFTYPE_P2P_GO);
 
+#ifdef CONFIG_PM
        /* Support only for limited wowlan functionalities */
        hw->wiphy->wowlan.flags = WIPHY_WOWLAN_ANY |
                WIPHY_WOWLAN_DISCONNECT;
        hw->wiphy->wowlan.n_patterns = 0;
+#endif
 
        hw->wiphy->flags |= WIPHY_FLAG_AP_UAPSD;
 
@@ -419,18 +423,22 @@ static int cw1200_register_common(struct ieee80211_hw *dev)
                goto done;
 #endif
 
+#ifdef CONFIG_PM
        err = cw1200_pm_init(&priv->pm_state, priv);
        if (err) {
                pr_err("Cannot init PM. (%d).\n",
                       err);
                return err;
        }
+#endif
 
        err = ieee80211_register_hw(dev);
        if (err) {
                pr_err("Cannot register device (%d).\n",
                       err);
+#ifdef CONFIG_PM
                cw1200_pm_deinit(&priv->pm_state);
+#endif
                return err;
        }
 
@@ -482,7 +490,9 @@ static void cw1200_unregister_common(struct ieee80211_hw *dev)
                cw1200_queue_deinit(&priv->tx_queue[i]);
 
        cw1200_queue_stats_deinit(&priv->tx_queue_stats);
+#ifdef CONFIG_PM
        cw1200_pm_deinit(&priv->pm_state);
+#endif
 }
 
 /* Clock is in KHz */
@@ -518,8 +528,8 @@ u32 cw1200_dpll_from_clk(u16 clk_khz)
        }
 }
 
-int cw1200_core_probe(const struct sbus_ops *sbus_ops,
-                     struct sbus_priv *sbus,
+int cw1200_core_probe(const struct hwbus_ops *hwbus_ops,
+                     struct hwbus_priv *hwbus,
                      struct device *pdev,
                      struct cw1200_common **core,
                      int ref_clk, const u8 *macaddr,
@@ -546,8 +556,8 @@ int cw1200_core_probe(const struct sbus_ops *sbus_ops,
        if (cw1200_sdd_path)
                priv->sdd_path = cw1200_sdd_path;
 
-       priv->sbus_ops = sbus_ops;
-       priv->sbus_priv = sbus;
+       priv->hwbus_ops = hwbus_ops;
+       priv->hwbus_priv = hwbus;
        priv->pdev = pdev;
        SET_IEEE80211_DEV(priv->hw, pdev);
 
@@ -606,9 +616,9 @@ EXPORT_SYMBOL_GPL(cw1200_core_probe);
 void cw1200_core_release(struct cw1200_common *self)
 {
        /* Disable device interrupts */
-       self->sbus_ops->lock(self->sbus_priv);
+       self->hwbus_ops->lock(self->hwbus_priv);
        __cw1200_irq_enable(self, 0);
-       self->sbus_ops->unlock(self->sbus_priv);
+       self->hwbus_ops->unlock(self->hwbus_priv);
 
        /* And then clean up */
        cw1200_unregister_common(self->hw);
index 79edfb9..b37abb9 100644 (file)
@@ -15,7 +15,7 @@
 #include "pm.h"
 #include "sta.h"
 #include "bh.h"
-#include "sbus.h"
+#include "hwbus.h"
 
 #define CW1200_BEACON_SKIPPING_MULTIPLIER 3
 
@@ -264,7 +264,7 @@ int cw1200_wow_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
        pm_state->suspend_state = state;
 
        /* Enable IRQ wake */
-       ret = priv->sbus_ops->power_mgmt(priv->sbus_priv, true);
+       ret = priv->hwbus_ops->power_mgmt(priv->hwbus_priv, true);
        if (ret) {
                wiphy_err(priv->hw->wiphy,
                          "PM request failed: %d. WoW is disabled.\n", ret);
@@ -313,7 +313,7 @@ int cw1200_wow_resume(struct ieee80211_hw *hw)
        pm_state->suspend_state = NULL;
 
        /* Disable IRQ wake */
-       priv->sbus_ops->power_mgmt(priv->sbus_priv, false);
+       priv->hwbus_ops->power_mgmt(priv->hwbus_priv, false);
 
        /* Scan.lock must be released before BH is resumed other way
         * in case when BSS_LOST command arrived the processing of the
index 516d967..3ed90ff 100644 (file)
@@ -25,14 +25,19 @@ struct cw1200_pm_state {
        spinlock_t lock; /* Protect access */
 };
 
+#ifdef CONFIG_PM
 int cw1200_pm_init(struct cw1200_pm_state *pm,
                    struct cw1200_common *priv);
 void cw1200_pm_deinit(struct cw1200_pm_state *pm);
-void cw1200_pm_stay_awake(struct cw1200_pm_state *pm,
-                         unsigned long tmo);
 int cw1200_wow_suspend(struct ieee80211_hw *hw,
                       struct cfg80211_wowlan *wowlan);
 int cw1200_wow_resume(struct ieee80211_hw *hw);
 int cw1200_can_suspend(struct cw1200_common *priv);
-
+void cw1200_pm_stay_awake(struct cw1200_pm_state *pm,
+                         unsigned long tmo);
+#else
+static inline void cw1200_pm_stay_awake(struct cw1200_pm_state *pm,
+                                       unsigned long tmo) {
+}
+#endif
 #endif
diff --git a/drivers/net/wireless/cw1200/sbus.h b/drivers/net/wireless/cw1200/sbus.h
deleted file mode 100644 (file)
index 603fd25..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Common sbus abstraction layer interface for cw1200 wireless driver
- *
- * Copyright (c) 2010, ST-Ericsson
- * Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
- *
- * 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 CW1200_SBUS_H
-#define CW1200_SBUS_H
-
-/*
- * sbus priv forward definition.
- * Implemented and instantiated in particular modules.
- */
-struct sbus_priv;
-
-void cw1200_irq_handler(struct cw1200_common *priv);
-
-/* This MUST be wrapped with sbus_ops->lock/unlock! */
-int __cw1200_irq_enable(struct cw1200_common *priv, int enable);
-
-struct sbus_ops {
-       int (*sbus_memcpy_fromio)(struct sbus_priv *self, unsigned int addr,
-                                       void *dst, int count);
-       int (*sbus_memcpy_toio)(struct sbus_priv *self, unsigned int addr,
-                                       const void *src, int count);
-       void (*lock)(struct sbus_priv *self);
-       void (*unlock)(struct sbus_priv *self);
-       size_t (*align_size)(struct sbus_priv *self, size_t size);
-       int (*power_mgmt)(struct sbus_priv *self, bool suspend);
-};
-
-#endif /* CW1200_SBUS_H */
index 0e40890..a254747 100644 (file)
@@ -190,13 +190,12 @@ static void tx_policy_build(const struct cw1200_common *priv,
                policy->retry_count += retries;
        }
 
-       pr_debug("[TX policy] Policy (%zu): %d:%d, %d:%d, %d:%d, %d:%d, %d:%d\n",
+       pr_debug("[TX policy] Policy (%zu): %d:%d, %d:%d, %d:%d, %d:%d\n",
                 count,
                 rates[0].idx, rates[0].count,
                 rates[1].idx, rates[1].count,
                 rates[2].idx, rates[2].count,
-                rates[3].idx, rates[3].count,
-                rates[4].idx, rates[4].count);
+                rates[3].idx, rates[3].count);
 }
 
 static inline bool tx_policy_is_equal(const struct tx_policy *wanted,
index 4db6cc1..3ab25f6 100644 (file)
@@ -12,7 +12,6 @@
 
 #include <linux/skbuff.h>
 #include <linux/wait.h>
-#include <linux/skbuff.h>
 #include <linux/delay.h>
 #include <linux/sched.h>
 #include <linux/random.h>
@@ -930,6 +929,8 @@ static int wsm_event_indication(struct cw1200_common *priv, struct wsm_buf *buf)
        }
 
        event = kzalloc(sizeof(struct cw1200_wsm_event), GFP_KERNEL);
+       if (!event)
+               return -ENOMEM;
 
        event->evt.id = __le32_to_cpu(WSM_GET32(buf));
        event->evt.data = __le32_to_cpu(WSM_GET32(buf));
index 15920aa..f8ab193 100644 (file)
@@ -6242,8 +6242,6 @@ static int ipw2100_pci_init_one(struct pci_dev *pci_dev,
        if ((val & 0x0000ff00) != 0)
                pci_write_config_dword(pci_dev, 0x40, val & 0xffff00ff);
 
-       pci_set_power_state(pci_dev, PCI_D0);
-
        if (!ipw2100_hw_is_adapter_in_system(dev)) {
                printk(KERN_WARNING DRV_NAME
                       "Device not found via register read.\n");
index f297690..2ed296c 100644 (file)
@@ -84,6 +84,15 @@ static const struct ieee80211_iface_limit iwl_mvm_limits[] = {
                .types = BIT(NL80211_IFTYPE_STATION) |
                        BIT(NL80211_IFTYPE_AP),
        },
+       {
+               .max = 1,
+               .types = BIT(NL80211_IFTYPE_P2P_CLIENT) |
+                       BIT(NL80211_IFTYPE_P2P_GO),
+       },
+       {
+               .max = 1,
+               .types = BIT(NL80211_IFTYPE_P2P_DEVICE),
+       },
 };
 
 static const struct ieee80211_iface_combination iwl_mvm_iface_combinations[] = {
@@ -164,7 +173,10 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
        hw->chanctx_data_size = sizeof(u16);
 
        hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
-               BIT(NL80211_IFTYPE_AP);
+               BIT(NL80211_IFTYPE_P2P_CLIENT) |
+               BIT(NL80211_IFTYPE_AP) |
+               BIT(NL80211_IFTYPE_P2P_GO) |
+               BIT(NL80211_IFTYPE_P2P_DEVICE);
 
        hw->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY |
                            WIPHY_FLAG_DISABLE_BEACON_HINTS |
index 69bbf6f..cb34c78 100644 (file)
@@ -2169,6 +2169,7 @@ static const struct ieee80211_iface_limit hwsim_if_limits[] = {
 #endif
                                 BIT(NL80211_IFTYPE_AP) |
                                 BIT(NL80211_IFTYPE_P2P_GO) },
+       { .max = 1, .types = BIT(NL80211_IFTYPE_P2P_DEVICE) },
 };
 
 static struct ieee80211_iface_combination hwsim_if_comb = {
@@ -2294,7 +2295,8 @@ static int __init init_mac80211_hwsim(void)
                        BIT(NL80211_IFTYPE_P2P_CLIENT) |
                        BIT(NL80211_IFTYPE_P2P_GO) |
                        BIT(NL80211_IFTYPE_ADHOC) |
-                       BIT(NL80211_IFTYPE_MESH_POINT);
+                       BIT(NL80211_IFTYPE_MESH_POINT) |
+                       BIT(NL80211_IFTYPE_P2P_DEVICE);
 
                hw->flags = IEEE80211_HW_MFP_CAPABLE |
                            IEEE80211_HW_SIGNAL_DBM |
diff --git a/include/linux/cw1200_platform.h b/include/linux/cw1200_platform.h
deleted file mode 100644 (file)
index c168fa5..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) ST-Ericsson SA 2011
- *
- * Author: Dmitry Tarnyagin <dmitry.tarnyagin@stericsson.com>
- * License terms: GNU General Public License (GPL) version 2
- */
-
-#ifndef CW1200_PLAT_H_INCLUDED
-#define CW1200_PLAT_H_INCLUDED
-
-struct cw1200_platform_data_spi {
-       u8 spi_bits_per_word;           /* REQUIRED */
-       u16 ref_clk;                    /* REQUIRED (in KHz) */
-
-       /* All others are optional */
-       bool have_5ghz;
-       const struct resource *reset;   /* GPIO to RSTn signal */
-       const struct resource *powerup; /* GPIO to POWERUP signal */
-       int (*power_ctrl)(const struct cw1200_platform_data_spi *pdata,
-                         bool enable); /* Control 3v3 / 1v8 supply */
-       int (*clk_ctrl)(const struct cw1200_platform_data_spi *pdata,
-                       bool enable); /* Control CLK32K */
-       const u8 *macaddr;  /* if NULL, use cw1200_mac_template module parameter */
-       const char *sdd_file;  /* if NULL, will use default for detected hw type */
-};
-
-struct cw1200_platform_data_sdio {
-       u16 ref_clk;                    /* REQUIRED (in KHz) */
-
-       /* All others are optional */
-       const struct resource *irq;     /* if using GPIO for IRQ */
-       bool have_5ghz;
-       bool no_nptb;                   /* SDIO hardware does not support non-power-of-2-blocksizes */
-       const struct resource *reset;   /* GPIO to RSTn signal */
-       const struct resource *powerup; /* GPIO to POWERUP signal */
-       int (*power_ctrl)(const struct cw1200_platform_data_sdio *pdata,
-                         bool enable); /* Control 3v3 / 1v8 supply */
-       int (*clk_ctrl)(const struct cw1200_platform_data_sdio *pdata,
-                       bool enable); /* Control CLK32K */
-       const u8 *macaddr;  /* if NULL, use cw1200_mac_template module parameter */
-       const char *sdd_file;  /* if NULL, will use default for detected hw type */
-};
-
-const void *cw1200_get_platform_data(void);
-
-#endif /* CW1200_PLAT_H_INCLUDED */
diff --git a/include/linux/platform_data/net-cw1200.h b/include/linux/platform_data/net-cw1200.h
new file mode 100644 (file)
index 0000000..c6fbc3c
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2011
+ *
+ * Author: Dmitry Tarnyagin <dmitry.tarnyagin@stericsson.com>
+ * License terms: GNU General Public License (GPL) version 2
+ */
+
+#ifndef CW1200_PLAT_H_INCLUDED
+#define CW1200_PLAT_H_INCLUDED
+
+struct cw1200_platform_data_spi {
+       u8 spi_bits_per_word;           /* REQUIRED */
+       u16 ref_clk;                    /* REQUIRED (in KHz) */
+
+       /* All others are optional */
+       bool have_5ghz;
+       int reset;                     /* GPIO to RSTn signal (0 disables) */
+       int powerup;                   /* GPIO to POWERUP signal (0 disables) */
+       int (*power_ctrl)(const struct cw1200_platform_data_spi *pdata,
+                         bool enable); /* Control 3v3 / 1v8 supply */
+       int (*clk_ctrl)(const struct cw1200_platform_data_spi *pdata,
+                       bool enable); /* Control CLK32K */
+       const u8 *macaddr;  /* if NULL, use cw1200_mac_template module parameter */
+       const char *sdd_file;  /* if NULL, will use default for detected hw type */
+};
+
+struct cw1200_platform_data_sdio {
+       u16 ref_clk;                    /* REQUIRED (in KHz) */
+
+       /* All others are optional */
+       bool have_5ghz;
+       bool no_nptb;       /* SDIO hardware does not support non-power-of-2-blocksizes */
+       int reset;          /* GPIO to RSTn signal (0 disables) */
+       int powerup;        /* GPIO to POWERUP signal (0 disables) */
+       int irq;            /* IRQ line or 0 to use SDIO IRQ */
+       int (*power_ctrl)(const struct cw1200_platform_data_sdio *pdata,
+                         bool enable); /* Control 3v3 / 1v8 supply */
+       int (*clk_ctrl)(const struct cw1200_platform_data_sdio *pdata,
+                       bool enable); /* Control CLK32K */
+       const u8 *macaddr;  /* if NULL, use cw1200_mac_template module parameter */
+       const char *sdd_file;  /* if NULL, will use default for detected hw type */
+};
+
+
+/* An example of SPI support in your board setup file:
+
+   static struct cw1200_platform_data_spi cw1200_platform_data = {
+       .ref_clk = 38400,
+       .spi_bits_per_word = 16,
+       .reset = GPIO_RF_RESET,
+       .powerup = GPIO_RF_POWERUP,
+       .macaddr = wifi_mac_addr,
+       .sdd_file = "sdd_sagrad_1091_1098.bin",
+  };
+  static struct spi_board_info myboard_spi_devices[] __initdata = {
+       {
+               .modalias = "cw1200_wlan_spi",
+               .max_speed_hz = 52000000,
+               .bus_num = 0,
+               .irq = WIFI_IRQ,
+               .platform_data = &cw1200_platform_data,
+               .chip_select = 0,
+       },
+  };
+
+ */
+
+/* An example of SDIO support in your board setup file:
+
+  static struct cw1200_platform_data_sdio my_cw1200_platform_data = {
+       .ref_clk = 38400,
+       .have_5ghz = false,
+       .sdd_file = "sdd_myplatform.bin",
+  };
+  cw1200_sdio_set_platform_data(&my_cw1200_platform_data);
+
+ */
+
+void __init cw1200_sdio_set_platform_data(struct cw1200_platform_data_sdio *pdata);
+
+#endif /* CW1200_PLAT_H_INCLUDED */
index b3b076a..6dd1959 100644 (file)
@@ -961,6 +961,7 @@ struct station_info {
  * @MONITOR_FLAG_CONTROL: pass control frames
  * @MONITOR_FLAG_OTHER_BSS: disable BSSID filtering
  * @MONITOR_FLAG_COOK_FRAMES: report frames after processing
+ * @MONITOR_FLAG_ACTIVE: active monitor, ACKs frames on its MAC address
  */
 enum monitor_flags {
        MONITOR_FLAG_FCSFAIL            = 1<<NL80211_MNTR_FLAG_FCSFAIL,
@@ -968,6 +969,7 @@ enum monitor_flags {
        MONITOR_FLAG_CONTROL            = 1<<NL80211_MNTR_FLAG_CONTROL,
        MONITOR_FLAG_OTHER_BSS          = 1<<NL80211_MNTR_FLAG_OTHER_BSS,
        MONITOR_FLAG_COOK_FRAMES        = 1<<NL80211_MNTR_FLAG_COOK_FRAMES,
+       MONITOR_FLAG_ACTIVE             = 1<<NL80211_MNTR_FLAG_ACTIVE,
 };
 
 /**
@@ -2867,7 +2869,6 @@ struct cfg80211_cached_keys;
  * @mgmt_registrations_lock: lock for the list
  * @mtx: mutex used to lock data in this struct, may be used by drivers
  *     and some API functions require it held
- * @cleanup_work: work struct used for cleanup that can't be done directly
  * @beacon_interval: beacon interval used on this device for transmitting
  *     beacons, 0 when not valid
  * @address: The address for this device, valid only if @netdev is %NULL
index 32b060e..5920715 100644 (file)
@@ -2428,6 +2428,8 @@ enum nl80211_survey_info {
  * @NL80211_MNTR_FLAG_OTHER_BSS: disable BSSID filtering
  * @NL80211_MNTR_FLAG_COOK_FRAMES: report frames after processing.
  *     overrides all other flags.
+ * @NL80211_MNTR_FLAG_ACTIVE: use the configured MAC address
+ *     and ACK incoming unicast packets.
  *
  * @__NL80211_MNTR_FLAG_AFTER_LAST: internal use
  * @NL80211_MNTR_FLAG_MAX: highest possible monitor flag
@@ -2439,6 +2441,7 @@ enum nl80211_mntr_flags {
        NL80211_MNTR_FLAG_CONTROL,
        NL80211_MNTR_FLAG_OTHER_BSS,
        NL80211_MNTR_FLAG_COOK_FRAMES,
+       NL80211_MNTR_FLAG_ACTIVE,
 
        /* keep last */
        __NL80211_MNTR_FLAG_AFTER_LAST,
@@ -3595,6 +3598,7 @@ enum nl80211_feature_flags {
        NL80211_FEATURE_ADVERTISE_CHAN_LIMITS           = 1 << 14,
        NL80211_FEATURE_FULL_AP_CLIENT_STATE            = 1 << 15,
        NL80211_FEATURE_USERSPACE_MPM                   = 1 << 16,
+       NL80211_FEATURE_ACTIVE_MONITOR                  = 1 << 17,
 };
 
 /**
index 232edf7..3062210 100644 (file)
@@ -73,16 +73,19 @@ static int ieee80211_change_iface(struct wiphy *wiphy,
                struct ieee80211_local *local = sdata->local;
 
                if (ieee80211_sdata_running(sdata)) {
+                       u32 mask = MONITOR_FLAG_COOK_FRAMES |
+                                  MONITOR_FLAG_ACTIVE;
+
                        /*
-                        * Prohibit MONITOR_FLAG_COOK_FRAMES to be
-                        * changed while the interface is up.
+                        * Prohibit MONITOR_FLAG_COOK_FRAMES and
+                        * MONITOR_FLAG_ACTIVE to be changed while the
+                        * interface is up.
                         * Else we would need to add a lot of cruft
                         * to update everything:
                         *      cooked_mntrs, monitor and all fif_* counters
                         *      reconfigure hardware
                         */
-                       if ((*flags & MONITOR_FLAG_COOK_FRAMES) !=
-                           (sdata->u.mntr_flags & MONITOR_FLAG_COOK_FRAMES))
+                       if ((*flags & mask) != (sdata->u.mntr_flags & mask))
                                return -EBUSY;
 
                        ieee80211_adjust_monitor_flags(sdata, -1);
@@ -2375,7 +2378,9 @@ static int ieee80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
        local->dynamic_ps_forced_timeout = timeout;
 
        /* no change, but if automatic follow powersave */
+       sdata_lock(sdata);
        __ieee80211_request_smps(sdata, sdata->u.mgd.req_smps);
+       sdata_unlock(sdata);
 
        if (local->hw.flags & IEEE80211_HW_SUPPORTS_DYNAMIC_PS)
                ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS);
index 169664c..b931c96 100644 (file)
@@ -146,7 +146,8 @@ static inline int drv_add_interface(struct ieee80211_local *local,
 
        if (WARN_ON(sdata->vif.type == NL80211_IFTYPE_AP_VLAN ||
                    (sdata->vif.type == NL80211_IFTYPE_MONITOR &&
-                    !(local->hw.flags & IEEE80211_HW_WANT_MONITOR_VIF))))
+                    !(local->hw.flags & IEEE80211_HW_WANT_MONITOR_VIF) &&
+                    !(sdata->u.mntr_flags & MONITOR_FLAG_ACTIVE))))
                return -EINVAL;
 
        trace_drv_add_interface(local, sdata);
index ceef644..7cabaf2 100644 (file)
@@ -159,7 +159,8 @@ static int ieee80211_change_mtu(struct net_device *dev, int new_mtu)
        return 0;
 }
 
-static int ieee80211_verify_mac(struct ieee80211_local *local, u8 *addr)
+static int ieee80211_verify_mac(struct ieee80211_local *local, u8 *addr,
+                               bool check_dup)
 {
        struct ieee80211_sub_if_data *sdata;
        u64 new, mask, tmp;
@@ -179,10 +180,13 @@ static int ieee80211_verify_mac(struct ieee80211_local *local, u8 *addr)
                ((u64)m[2] << 3*8) | ((u64)m[3] << 2*8) |
                ((u64)m[4] << 1*8) | ((u64)m[5] << 0*8);
 
+       if (!check_dup)
+               return ret;
 
        mutex_lock(&local->iflist_mtx);
        list_for_each_entry(sdata, &local->interfaces, list) {
-               if (sdata->vif.type == NL80211_IFTYPE_MONITOR)
+               if (sdata->vif.type == NL80211_IFTYPE_MONITOR &&
+                   !(sdata->u.mntr_flags & MONITOR_FLAG_ACTIVE))
                        continue;
 
                m = sdata->vif.addr;
@@ -204,12 +208,17 @@ static int ieee80211_change_mac(struct net_device *dev, void *addr)
 {
        struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
        struct sockaddr *sa = addr;
+       bool check_dup = true;
        int ret;
 
        if (ieee80211_sdata_running(sdata))
                return -EBUSY;
 
-       ret = ieee80211_verify_mac(sdata->local, sa->sa_data);
+       if (sdata->vif.type == NL80211_IFTYPE_MONITOR &&
+           !(sdata->u.mntr_flags & MONITOR_FLAG_ACTIVE))
+               check_dup = false;
+
+       ret = ieee80211_verify_mac(sdata->local, sa->sa_data, check_dup);
        if (ret)
                return ret;
 
@@ -541,7 +550,11 @@ int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up)
                        break;
                }
 
-               if (local->monitors == 0 && local->open_count == 0) {
+               if (sdata->u.mntr_flags & MONITOR_FLAG_ACTIVE) {
+                       res = drv_add_interface(local, sdata);
+                       if (res)
+                               goto err_stop;
+               } else if (local->monitors == 0 && local->open_count == 0) {
                        res = ieee80211_add_virtual_monitor(local);
                        if (res)
                                goto err_stop;
@@ -919,7 +932,11 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
                mutex_lock(&local->mtx);
                ieee80211_recalc_idle(local);
                mutex_unlock(&local->mtx);
-               break;
+
+               if (!(sdata->u.mntr_flags & MONITOR_FLAG_ACTIVE))
+                       break;
+
+               /* fall through */
        default:
                if (going_down)
                        drv_remove_interface(local, sdata);
@@ -1068,7 +1085,7 @@ static const struct net_device_ops ieee80211_monitorif_ops = {
        .ndo_start_xmit         = ieee80211_monitor_start_xmit,
        .ndo_set_rx_mode        = ieee80211_set_multicast_list,
        .ndo_change_mtu         = ieee80211_change_mtu,
-       .ndo_set_mac_address    = eth_mac_addr,
+       .ndo_set_mac_address    = ieee80211_change_mac,
        .ndo_select_queue       = ieee80211_monitor_select_queue,
 };
 
index 9972e07..34be933 100644 (file)
@@ -398,13 +398,14 @@ ieee80211_tx_h_multicast_ps_buf(struct ieee80211_tx_data *tx)
        if (ieee80211_has_order(hdr->frame_control))
                return TX_CONTINUE;
 
+       if (tx->local->hw.flags & IEEE80211_HW_QUEUE_CONTROL)
+               info->hw_queue = tx->sdata->vif.cab_queue;
+
        /* no stations in PS mode */
        if (!atomic_read(&ps->num_sta_ps))
                return TX_CONTINUE;
 
        info->flags |= IEEE80211_TX_CTL_SEND_AFTER_DTIM;
-       if (tx->local->hw.flags & IEEE80211_HW_QUEUE_CONTROL)
-               info->hw_queue = tx->sdata->vif.cab_queue;
 
        /* device releases frame after DTIM beacon */
        if (!(tx->local->hw.flags & IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING))
index 2a8d759..89a8377 100644 (file)
@@ -560,6 +560,9 @@ void ieee80211_iterate_active_interfaces(
        list_for_each_entry(sdata, &local->interfaces, list) {
                switch (sdata->vif.type) {
                case NL80211_IFTYPE_MONITOR:
+                       if (!(sdata->u.mntr_flags & MONITOR_FLAG_ACTIVE))
+                               continue;
+                       break;
                case NL80211_IFTYPE_AP_VLAN:
                        continue;
                default:
@@ -598,6 +601,9 @@ void ieee80211_iterate_active_interfaces_atomic(
        list_for_each_entry_rcu(sdata, &local->interfaces, list) {
                switch (sdata->vif.type) {
                case NL80211_IFTYPE_MONITOR:
+                       if (!(sdata->u.mntr_flags & MONITOR_FLAG_ACTIVE))
+                               continue;
+                       break;
                case NL80211_IFTYPE_AP_VLAN:
                        continue;
                default:
index fb6abcb..31d265f 100644 (file)
@@ -2227,6 +2227,7 @@ static const struct nla_policy mntr_flags_policy[NL80211_MNTR_FLAG_MAX + 1] = {
        [NL80211_MNTR_FLAG_CONTROL] = { .type = NLA_FLAG },
        [NL80211_MNTR_FLAG_OTHER_BSS] = { .type = NLA_FLAG },
        [NL80211_MNTR_FLAG_COOK_FRAMES] = { .type = NLA_FLAG },
+       [NL80211_MNTR_FLAG_ACTIVE] = { .type = NLA_FLAG },
 };
 
 static int parse_monitor_flags(struct nlattr *nla, u32 *mntrflags)
@@ -2338,6 +2339,10 @@ static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info)
                change = true;
        }
 
+       if (flags && (*flags & NL80211_MNTR_FLAG_ACTIVE) &&
+           !(rdev->wiphy.features & NL80211_FEATURE_ACTIVE_MONITOR))
+               return -EOPNOTSUPP;
+
        if (change)
                err = cfg80211_change_iface(rdev, dev, ntype, flags, &params);
        else
@@ -2395,6 +2400,11 @@ static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info)
        err = parse_monitor_flags(type == NL80211_IFTYPE_MONITOR ?
                                  info->attrs[NL80211_ATTR_MNTR_FLAGS] : NULL,
                                  &flags);
+
+       if (!err && (flags & NL80211_MNTR_FLAG_ACTIVE) &&
+           !(rdev->wiphy.features & NL80211_FEATURE_ACTIVE_MONITOR))
+               return -EOPNOTSUPP;
+
        wdev = rdev_add_virtual_intf(rdev,
                                nla_data(info->attrs[NL80211_ATTR_IFNAME]),
                                type, err ? NULL : &flags, &params);