]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
Merge branch 'for-linville' of git://git.kernel.org/pub/scm/linux/kernel/git/luca...
authorJohn W. Linville <linville@tuxdriver.com>
Tue, 18 Jun 2013 18:45:21 +0000 (14:45 -0400)
committerJohn W. Linville <linville@tuxdriver.com>
Tue, 18 Jun 2013 18:45:21 +0000 (14:45 -0400)
29 files changed:
drivers/bcma/core.c
drivers/bcma/driver_chipcommon_sflash.c
drivers/bluetooth/btmrvl_main.c
drivers/net/wireless/ath/ath9k/ani.c
drivers/net/wireless/ath/ath9k/ani.h
drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
drivers/net/wireless/brcm80211/brcmsmac/main.c
drivers/net/wireless/iwlegacy/3945-rs.c
drivers/net/wireless/iwlegacy/4965-rs.c
drivers/net/wireless/iwlwifi/dvm/rs.c
drivers/net/wireless/iwlwifi/dvm/rxon.c
drivers/net/wireless/iwlwifi/iwl-drv.c
drivers/net/wireless/iwlwifi/mvm/rs.c
drivers/net/wireless/iwlwifi/mvm/tx.c
drivers/net/wireless/iwlwifi/pcie/tx.c
drivers/net/wireless/mwifiex/cfg80211.c
drivers/net/wireless/mwifiex/main.c
drivers/net/wireless/mwifiex/sta_ioctl.c
drivers/net/wireless/rt2x00/rt2800lib.c
drivers/net/wireless/rtlwifi/rtl8192cu/sw.c
drivers/ssb/driver_chipcommon_sflash.c
include/linux/ssb/ssb_driver_mips.h
net/bluetooth/hci_core.c
net/bluetooth/l2cap_core.c
net/mac80211/cfg.c
net/mac80211/ieee80211_i.h
net/mac80211/mlme.c
net/mac80211/rate.c
net/mac80211/util.c

index 17b26ce7e051b1374b6be01f18f3dd1cad057e56..37a5ffe673d5da8c9ac6ee955d835d48b596ca7f 100644 (file)
@@ -9,6 +9,25 @@
 #include <linux/export.h>
 #include <linux/bcma/bcma.h>
 
+static bool bcma_core_wait_value(struct bcma_device *core, u16 reg, u32 mask,
+                                u32 value, int timeout)
+{
+       unsigned long deadline = jiffies + timeout;
+       u32 val;
+
+       do {
+               val = bcma_aread32(core, reg);
+               if ((val & mask) == value)
+                       return true;
+               cpu_relax();
+               udelay(10);
+       } while (!time_after_eq(jiffies, deadline));
+
+       bcma_warn(core->bus, "Timeout waiting for register 0x%04X!\n", reg);
+
+       return false;
+}
+
 bool bcma_core_is_enabled(struct bcma_device *core)
 {
        if ((bcma_aread32(core, BCMA_IOCTL) & (BCMA_IOCTL_CLK | BCMA_IOCTL_FGC))
@@ -25,13 +44,15 @@ void bcma_core_disable(struct bcma_device *core, u32 flags)
        if (bcma_aread32(core, BCMA_RESET_CTL) & BCMA_RESET_CTL_RESET)
                return;
 
-       bcma_awrite32(core, BCMA_IOCTL, flags);
-       bcma_aread32(core, BCMA_IOCTL);
-       udelay(10);
+       bcma_core_wait_value(core, BCMA_RESET_ST, ~0, 0, 300);
 
        bcma_awrite32(core, BCMA_RESET_CTL, BCMA_RESET_CTL_RESET);
        bcma_aread32(core, BCMA_RESET_CTL);
        udelay(1);
+
+       bcma_awrite32(core, BCMA_IOCTL, flags);
+       bcma_aread32(core, BCMA_IOCTL);
+       udelay(10);
 }
 EXPORT_SYMBOL_GPL(bcma_core_disable);
 
@@ -43,6 +64,7 @@ int bcma_core_enable(struct bcma_device *core, u32 flags)
        bcma_aread32(core, BCMA_IOCTL);
 
        bcma_awrite32(core, BCMA_RESET_CTL, 0);
+       bcma_aread32(core, BCMA_RESET_CTL);
        udelay(1);
 
        bcma_awrite32(core, BCMA_IOCTL, (BCMA_IOCTL_CLK | flags));
index e6ed4fe5dcedc50a758db62a5ca8a1d0c30d3b38..4d07cce9c5d97ad2d7d9733c90209bfcb5a094da 100644 (file)
@@ -30,7 +30,7 @@ struct bcma_sflash_tbl_e {
        u16 numblocks;
 };
 
-static struct bcma_sflash_tbl_e bcma_sflash_st_tbl[] = {
+static const struct bcma_sflash_tbl_e bcma_sflash_st_tbl[] = {
        { "M25P20", 0x11, 0x10000, 4, },
        { "M25P40", 0x12, 0x10000, 8, },
 
@@ -41,7 +41,7 @@ static struct bcma_sflash_tbl_e bcma_sflash_st_tbl[] = {
        { 0 },
 };
 
-static struct bcma_sflash_tbl_e bcma_sflash_sst_tbl[] = {
+static const struct bcma_sflash_tbl_e bcma_sflash_sst_tbl[] = {
        { "SST25WF512", 1, 0x1000, 16, },
        { "SST25VF512", 0x48, 0x1000, 16, },
        { "SST25WF010", 2, 0x1000, 32, },
@@ -59,7 +59,7 @@ static struct bcma_sflash_tbl_e bcma_sflash_sst_tbl[] = {
        { 0 },
 };
 
-static struct bcma_sflash_tbl_e bcma_sflash_at_tbl[] = {
+static const struct bcma_sflash_tbl_e bcma_sflash_at_tbl[] = {
        { "AT45DB011", 0xc, 256, 512, },
        { "AT45DB021", 0x14, 256, 1024, },
        { "AT45DB041", 0x1c, 256, 2048, },
@@ -89,7 +89,7 @@ int bcma_sflash_init(struct bcma_drv_cc *cc)
 {
        struct bcma_bus *bus = cc->core->bus;
        struct bcma_sflash *sflash = &cc->sflash;
-       struct bcma_sflash_tbl_e *e;
+       const struct bcma_sflash_tbl_e *e;
        u32 id, id2;
 
        switch (cc->capabilities & BCMA_CC_CAP_FLASHT) {
index 3a4343b3bd6d0dfeb0ef98370d4e23f89b39f996..9a9f51875df5ef7826cea976b6afefa0889e160b 100644 (file)
@@ -498,6 +498,10 @@ static int btmrvl_service_main_thread(void *data)
                add_wait_queue(&thread->wait_q, &wait);
 
                set_current_state(TASK_INTERRUPTIBLE);
+               if (kthread_should_stop()) {
+                       BT_DBG("main_thread: break from main thread");
+                       break;
+               }
 
                if (adapter->wakeup_tries ||
                                ((!adapter->int_count) &&
@@ -513,11 +517,6 @@ static int btmrvl_service_main_thread(void *data)
 
                BT_DBG("main_thread woke up");
 
-               if (kthread_should_stop()) {
-                       BT_DBG("main_thread: break from main thread");
-                       break;
-               }
-
                spin_lock_irqsave(&priv->driver_lock, flags);
                if (adapter->int_count) {
                        adapter->int_count = 0;
index a68beb19ce4d6e65aaab31f475be2dff51d6d20d..4994bea809eb00db15a8899ee5d2dd966002db4a 100644 (file)
@@ -186,6 +186,14 @@ static void ath9k_hw_set_ofdm_nil(struct ath_hw *ah, u8 immunityLevel,
                                     ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
                                     entry_ofdm->ofdm_weak_signal_on);
        }
+
+       if (aniState->ofdmNoiseImmunityLevel >= ATH9K_ANI_OFDM_DEF_LEVEL) {
+               ah->config.ofdm_trig_high = ATH9K_ANI_OFDM_TRIG_HIGH;
+               ah->config.ofdm_trig_low = ATH9K_ANI_OFDM_TRIG_LOW_ABOVE_INI;
+       } else {
+               ah->config.ofdm_trig_high = ATH9K_ANI_OFDM_TRIG_HIGH_BELOW_INI;
+               ah->config.ofdm_trig_low = ATH9K_ANI_OFDM_TRIG_LOW;
+       }
 }
 
 static void ath9k_hw_ani_ofdm_err_trigger(struct ath_hw *ah)
@@ -420,25 +428,12 @@ void ath9k_hw_ani_monitor(struct ath_hw *ah, struct ath9k_channel *chan)
                ofdmPhyErrRate, aniState->cckNoiseImmunityLevel,
                cckPhyErrRate, aniState->ofdmsTurn);
 
-       if (aniState->listenTime > 5 * ah->aniperiod) {
-               /*
-                * Check if we need to lower immunity if
-                * 5 ani_periods have passed.
-                */
-               if (ofdmPhyErrRate <= ah->config.ofdm_trig_low &&
-                   cckPhyErrRate <= ah->config.cck_trig_low) {
+       if (aniState->listenTime > ah->aniperiod) {
+               if (cckPhyErrRate < ah->config.cck_trig_low &&
+                   ofdmPhyErrRate < ah->config.ofdm_trig_low) {
                        ath9k_hw_ani_lower_immunity(ah);
                        aniState->ofdmsTurn = !aniState->ofdmsTurn;
-               }
-               ath9k_ani_restart(ah);
-       } else if (aniState->listenTime > ah->aniperiod) {
-               /*
-                * Check if immunity has to be raised,
-                * (either OFDM or CCK).
-                */
-               if (ofdmPhyErrRate > ah->config.ofdm_trig_high &&
-                   (cckPhyErrRate <= ah->config.cck_trig_high ||
-                    aniState->ofdmsTurn)) {
+               } else if (ofdmPhyErrRate > ah->config.ofdm_trig_high) {
                        ath9k_hw_ani_ofdm_err_trigger(ah);
                        aniState->ofdmsTurn = false;
                } else if (cckPhyErrRate > ah->config.cck_trig_high) {
index 77a06fd40287aae33ff95de948cb7ce5b330bc0c..b54a3fb0188391eba46a797f923a15b40fe34b66 100644 (file)
 #define BEACON_RSSI(ahp) (ahp->stats.avgbrssi)
 
 /* units are errors per second */
-#define ATH9K_ANI_OFDM_TRIG_HIGH          1000
+#define ATH9K_ANI_OFDM_TRIG_HIGH           3500
+#define ATH9K_ANI_OFDM_TRIG_HIGH_BELOW_INI 1000
+
 #define ATH9K_ANI_OFDM_TRIG_LOW           400
+#define ATH9K_ANI_OFDM_TRIG_LOW_ABOVE_INI 900
+
 #define ATH9K_ANI_CCK_TRIG_HIGH           600
 #define ATH9K_ANI_CCK_TRIG_LOW            300
 
index 9a00bc0a930422f47b749981b7270b774fcc83f6..eae23b910bce3d26a3eb386c4d6e4b0dcf52760d 100644 (file)
@@ -3576,7 +3576,7 @@ static void ar9003_hw_ant_ctrl_apply(struct ath_hw *ah, bool is2ghz)
                else
                        gpio = AR9300_EXT_LNA_CTL_GPIO_AR9485;
 
-               ath9k_hw_cfg_output(ah, AR9300_EXT_LNA_CTL_GPIO_AR9485,
+               ath9k_hw_cfg_output(ah, gpio,
                                    AR_GPIO_OUTPUT_MUX_AS_PCIE_ATTENTION_LED);
        }
 
index 28e7aeedd184c4cc942ec67259dc978ca542794e..9fd6f2fef11bfe546126c86ec857507d8fe8d9eb 100644 (file)
@@ -3074,21 +3074,8 @@ static void brcms_b_antsel_set(struct brcms_hardware *wlc_hw, u32 antsel_avail)
  */
 static bool brcms_c_ps_allowed(struct brcms_c_info *wlc)
 {
-       /* disallow PS when one of the following global conditions meets */
-       if (!wlc->pub->associated)
-               return false;
-
-       /* disallow PS when one of these meets when not scanning */
-       if (wlc->filter_flags & FIF_PROMISC_IN_BSS)
-               return false;
-
-       if (wlc->bsscfg->type == BRCMS_TYPE_AP)
-               return false;
-
-       if (wlc->bsscfg->type == BRCMS_TYPE_ADHOC)
-               return false;
-
-       return true;
+       /* not supporting PS so always return false for now */
+       return false;
 }
 
 static void brcms_c_statsupd(struct brcms_c_info *wlc)
index c9f197d9ca1eecddf8d6f651c4f8598950986502..fe31590a51b2d81b41b40b2f862c96c5b2e10980 100644 (file)
@@ -816,6 +816,7 @@ out:
                rs_sta->last_txrate_idx = idx;
                info->control.rates[0].idx = rs_sta->last_txrate_idx;
        }
+       info->control.rates[0].count = 1;
 
        D_RATE("leave: %d\n", idx);
 }
index 1fc0b227e120d5d74054be24356f07ef2852824f..ed3c42a63a4369678f2764049f0b7e257f535fb4 100644 (file)
@@ -2268,7 +2268,7 @@ il4965_rs_get_rate(void *il_r, struct ieee80211_sta *sta, void *il_sta,
                info->control.rates[0].flags = 0;
        }
        info->control.rates[0].idx = rate_idx;
-
+       info->control.rates[0].count = 1;
 }
 
 static void *
index 94314a8e102940f0cb72249babde0f3f95a5e3c1..8fe76dc4f373e8a0724e049a6fa320fc159c0382 100644 (file)
@@ -2799,7 +2799,7 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta, void *priv_sta,
                info->control.rates[0].flags = 0;
        }
        info->control.rates[0].idx = rate_idx;
-
+       info->control.rates[0].count = 1;
 }
 
 static void *rs_alloc_sta(void *priv_rate, struct ieee80211_sta *sta,
index 707446fa00bdbaa969bdd6f60f3e6dab3d8db3bd..cd1ad00191857e962f74a45c0bbcfe56e1591514 100644 (file)
@@ -1378,7 +1378,7 @@ static void iwlagn_chain_noise_reset(struct iwl_priv *priv)
        struct iwl_chain_noise_data *data = &priv->chain_noise_data;
        int ret;
 
-       if (!(priv->calib_disabled & IWL_CHAIN_NOISE_CALIB_DISABLED))
+       if (priv->calib_disabled & IWL_CHAIN_NOISE_CALIB_DISABLED)
                return;
 
        if ((data->state == IWL_CHAIN_NOISE_ALIVE) &&
index 4f886133639a100b0d5adba017e576ad238d54e9..2f690e578b5c75904b9df8a6beb3db7f4c6e2c9c 100644 (file)
@@ -1000,10 +1000,12 @@ static void iwl_req_fw_callback(const struct firmware *ucode_raw, void *context)
         */
        if (load_module) {
                err = request_module("%s", op->name);
+#ifdef CONFIG_IWLWIFI_OPMODE_MODULAR
                if (err)
                        IWL_ERR(drv,
                                "failed to load module %s (error %d), is dynamic loading enabled?\n",
                                op->name, err);
+#endif
        }
        return;
 
index d6beec765d65727ca1d523a47221319e9759208e..31587a318f8b1691ddf12508004379d85ffc80c1 100644 (file)
@@ -2652,6 +2652,7 @@ static void rs_get_rate(void *mvm_r, struct ieee80211_sta *sta, void *mvm_sta,
                info->control.rates[0].flags = 0;
        }
        info->control.rates[0].idx = rate_idx;
+       info->control.rates[0].count = 1;
 }
 
 static void *rs_alloc_sta(void *mvm_rate, struct ieee80211_sta *sta,
index 42df1fdc5cbd24ba6ff91ad1bcb9dcd4682d38b7..f0e96a927407d3ae1473481f5e7d3eeb894a5a2b 100644 (file)
@@ -180,7 +180,8 @@ static void iwl_mvm_set_tx_cmd_rate(struct iwl_mvm *mvm,
                tx_cmd->tx_flags |= cpu_to_le32(TX_CMD_FLG_STA_RATE);
                return;
        } else if (ieee80211_is_back_req(fc)) {
-               tx_cmd->tx_flags |= cpu_to_le32(TX_CMD_FLG_STA_RATE);
+               tx_cmd->tx_flags |=
+                       cpu_to_le32(TX_CMD_FLG_ACK | TX_CMD_FLG_BAR);
        }
 
        /* HT rate doesn't make sense for a non data frame */
index b8f3cb78382bd55eac2bf57dc8bc970d170a0b5b..c47c92165aba91d2e97631f1953bd4e480cabad7 100644 (file)
@@ -576,10 +576,16 @@ static void iwl_pcie_txq_unmap(struct iwl_trans *trans, int txq_id)
 
        spin_lock_bh(&txq->lock);
        while (q->write_ptr != q->read_ptr) {
+               IWL_DEBUG_TX_REPLY(trans, "Q %d Free %d\n",
+                                  txq_id, q->read_ptr);
                iwl_pcie_txq_free_tfd(trans, txq);
                q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd);
        }
+       txq->active = false;
        spin_unlock_bh(&txq->lock);
+
+       /* just in case - this queue may have been stopped */
+       iwl_wake_queue(trans, txq);
 }
 
 /*
@@ -927,6 +933,12 @@ void iwl_trans_pcie_reclaim(struct iwl_trans *trans, int txq_id, int ssn,
 
        spin_lock_bh(&txq->lock);
 
+       if (!txq->active) {
+               IWL_DEBUG_TX_QUEUES(trans, "Q %d inactive - ignoring idx %d\n",
+                                   txq_id, ssn);
+               goto out;
+       }
+
        if (txq->q.read_ptr == tfd_num)
                goto out;
 
@@ -1108,6 +1120,7 @@ void iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, int fifo,
                       (fifo << SCD_QUEUE_STTS_REG_POS_TXF) |
                       (1 << SCD_QUEUE_STTS_REG_POS_WSL) |
                       SCD_QUEUE_STTS_REG_MSK);
+       trans_pcie->txq[txq_id].active = true;
        IWL_DEBUG_TX_QUEUES(trans, "Activate queue %d on FIFO %d WrPtr: %d\n",
                            txq_id, fifo, ssn & 0xff);
 }
index 856aea25052ba1ee3ce78e5ebd073605a0c7e001..ef5fa890a28628666398f39624f83e1bfe6aa1f5 100644 (file)
@@ -20,6 +20,9 @@
 #include "cfg80211.h"
 #include "main.h"
 
+static char *reg_alpha2;
+module_param(reg_alpha2, charp, 0);
+
 static const struct ieee80211_iface_limit mwifiex_ap_sta_limits[] = {
        {
                .max = 2, .types = BIT(NL80211_IFTYPE_STATION),
@@ -2485,6 +2488,17 @@ static const struct wiphy_wowlan_support mwifiex_wowlan_support = {
 };
 #endif
 
+static bool mwifiex_is_valid_alpha2(const char *alpha2)
+{
+       if (!alpha2 || strlen(alpha2) != 2)
+               return false;
+
+       if (isalpha(alpha2[0]) && isalpha(alpha2[1]))
+               return true;
+
+       return false;
+}
+
 /*
  * This function registers the device with CFG802.11 subsystem.
  *
@@ -2537,6 +2551,7 @@ int mwifiex_register_cfg80211(struct mwifiex_adapter *adapter)
                        WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD |
                        WIPHY_FLAG_AP_UAPSD |
                        WIPHY_FLAG_CUSTOM_REGULATORY |
+                       WIPHY_FLAG_STRICT_REGULATORY |
                        WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
 
        wiphy_apply_custom_regulatory(wiphy, &mwifiex_world_regdom_custom);
@@ -2574,10 +2589,16 @@ int mwifiex_register_cfg80211(struct mwifiex_adapter *adapter)
                wiphy_free(wiphy);
                return ret;
        }
-       country_code = mwifiex_11d_code_2_region(priv->adapter->region_code);
-       if (country_code)
-               dev_info(adapter->dev,
-                        "ignoring F/W country code %2.2s\n", country_code);
+
+       if (reg_alpha2 && mwifiex_is_valid_alpha2(reg_alpha2)) {
+               wiphy_info(wiphy, "driver hint alpha2: %2.2s\n", reg_alpha2);
+               regulatory_hint(wiphy, reg_alpha2);
+       } else {
+               country_code = mwifiex_11d_code_2_region(adapter->region_code);
+               if (country_code)
+                       wiphy_info(wiphy, "ignoring F/W country code %2.2s\n",
+                                  country_code);
+       }
 
        adapter->wiphy = wiphy;
        return ret;
index 485871940d3cbfe71e133472d29557ad0ed95073..e15ab72fb03ddc1ad6eab8e54aded37de3143253 100644 (file)
@@ -669,9 +669,8 @@ static void mwifiex_set_multicast_list(struct net_device *dev)
                mcast_list.mode = MWIFIEX_ALL_MULTI_MODE;
        } else {
                mcast_list.mode = MWIFIEX_MULTICAST_MODE;
-               if (netdev_mc_count(dev))
-                       mcast_list.num_multicast_addr =
-                               mwifiex_copy_mcast_addr(&mcast_list, dev);
+               mcast_list.num_multicast_addr =
+                       mwifiex_copy_mcast_addr(&mcast_list, dev);
        }
        mwifiex_request_set_multicast_list(priv, &mcast_list);
 }
index 1a8a19dbd635df7b6b012533605cdde724c0d000..23aa910bc5d0c1691a5bf8354881083f98ecd138 100644 (file)
@@ -104,16 +104,14 @@ int mwifiex_request_set_multicast_list(struct mwifiex_private *priv,
                } else {
                        priv->curr_pkt_filter &=
                                ~HostCmd_ACT_MAC_ALL_MULTICAST_ENABLE;
-                       if (mcast_list->num_multicast_addr) {
-                               dev_dbg(priv->adapter->dev,
-                                       "info: Set multicast list=%d\n",
-                                      mcast_list->num_multicast_addr);
-                               /* Send multicast addresses to firmware */
-                               ret = mwifiex_send_cmd_async(priv,
-                                       HostCmd_CMD_MAC_MULTICAST_ADR,
-                                       HostCmd_ACT_GEN_SET, 0,
-                                       mcast_list);
-                       }
+                       dev_dbg(priv->adapter->dev,
+                               "info: Set multicast list=%d\n",
+                               mcast_list->num_multicast_addr);
+                       /* Send multicast addresses to firmware */
+                       ret = mwifiex_send_cmd_async(priv,
+                               HostCmd_CMD_MAC_MULTICAST_ADR,
+                               HostCmd_ACT_GEN_SET, 0,
+                               mcast_list);
                }
        }
        dev_dbg(priv->adapter->dev,
index ead3a3e746a2c811929157e9338150d30cc3601a..3aa30ddcbfea1095887b837dafbb3f03f2a912c5 100644 (file)
@@ -3027,19 +3027,26 @@ static void rt2800_config_txpower(struct rt2x00_dev *rt2x00dev,
         * TODO: we do not use +6 dBm option to do not increase power beyond
         * regulatory limit, however this could be utilized for devices with
         * CAPABILITY_POWER_LIMIT.
+        *
+        * TODO: add different temperature compensation code for RT3290 & RT5390
+        * to allow to use BBP_R1 for those chips.
         */
-       rt2800_bbp_read(rt2x00dev, 1, &r1);
-       if (delta <= -12) {
-               power_ctrl = 2;
-               delta += 12;
-       } else if (delta <= -6) {
-               power_ctrl = 1;
-               delta += 6;
-       } else {
-               power_ctrl = 0;
+       if (!rt2x00_rt(rt2x00dev, RT3290) &&
+           !rt2x00_rt(rt2x00dev, RT5390)) {
+               rt2800_bbp_read(rt2x00dev, 1, &r1);
+               if (delta <= -12) {
+                       power_ctrl = 2;
+                       delta += 12;
+               } else if (delta <= -6) {
+                       power_ctrl = 1;
+                       delta += 6;
+               } else {
+                       power_ctrl = 0;
+               }
+               rt2x00_set_field8(&r1, BBP1_TX_POWER_CTRL, power_ctrl);
+               rt2800_bbp_write(rt2x00dev, 1, r1);
        }
-       rt2x00_set_field8(&r1, BBP1_TX_POWER_CTRL, power_ctrl);
-       rt2800_bbp_write(rt2x00dev, 1, r1);
+
        offset = TX_PWR_CFG_0;
 
        for (i = 0; i < EEPROM_TXPOWER_BYRATE_SIZE; i += 2) {
index 826f085c29dd5d9155ff0ab1e4ea2a8b2832f70c..2bd5985262171bfdfa81de5494a4ef9640d72cc5 100644 (file)
@@ -359,6 +359,7 @@ static struct usb_device_id rtl8192c_usb_ids[] = {
        {RTL_USB_DEVICE(0x2001, 0x330a, rtl92cu_hal_cfg)}, /*D-Link-Alpha*/
        {RTL_USB_DEVICE(0x2019, 0xab2b, rtl92cu_hal_cfg)}, /*Planex -Abocom*/
        {RTL_USB_DEVICE(0x20f4, 0x624d, rtl92cu_hal_cfg)}, /*TRENDNet*/
+       {RTL_USB_DEVICE(0x2357, 0x0100, rtl92cu_hal_cfg)}, /*TP-Link WN8200ND*/
        {RTL_USB_DEVICE(0x7392, 0x7822, rtl92cu_hal_cfg)}, /*Edimax -Edimax*/
        {}
 };
index 720665ca2bb1f0332acd3367eab6bdcd88a3428e..205f1c499c463840b7feac961128bd72e2582aae 100644 (file)
@@ -16,7 +16,7 @@ struct ssb_sflash_tbl_e {
        u16 numblocks;
 };
 
-static struct ssb_sflash_tbl_e ssb_sflash_st_tbl[] = {
+static const struct ssb_sflash_tbl_e ssb_sflash_st_tbl[] = {
        { "M25P20", 0x11, 0x10000, 4, },
        { "M25P40", 0x12, 0x10000, 8, },
 
@@ -27,7 +27,7 @@ static struct ssb_sflash_tbl_e ssb_sflash_st_tbl[] = {
        { 0 },
 };
 
-static struct ssb_sflash_tbl_e ssb_sflash_sst_tbl[] = {
+static const struct ssb_sflash_tbl_e ssb_sflash_sst_tbl[] = {
        { "SST25WF512", 1, 0x1000, 16, },
        { "SST25VF512", 0x48, 0x1000, 16, },
        { "SST25WF010", 2, 0x1000, 32, },
@@ -45,7 +45,7 @@ static struct ssb_sflash_tbl_e ssb_sflash_sst_tbl[] = {
        { 0 },
 };
 
-static struct ssb_sflash_tbl_e ssb_sflash_at_tbl[] = {
+static const struct ssb_sflash_tbl_e ssb_sflash_at_tbl[] = {
        { "AT45DB011", 0xc, 256, 512, },
        { "AT45DB021", 0x14, 256, 1024, },
        { "AT45DB041", 0x1c, 256, 2048, },
@@ -73,7 +73,8 @@ static void ssb_sflash_cmd(struct ssb_chipcommon *cc, u32 opcode)
 /* Initialize serial flash access */
 int ssb_sflash_init(struct ssb_chipcommon *cc)
 {
-       struct ssb_sflash_tbl_e *e;
+       struct ssb_sflash *sflash = &cc->dev->bus->mipscore.sflash;
+       const struct ssb_sflash_tbl_e *e;
        u32 id, id2;
 
        switch (cc->capabilities & SSB_CHIPCO_CAP_FLASHT) {
@@ -131,6 +132,12 @@ int ssb_sflash_init(struct ssb_chipcommon *cc)
                return -ENOTSUPP;
        }
 
+       sflash->window = SSB_FLASH2;
+       sflash->blocksize = e->blocksize;
+       sflash->numblocks = e->numblocks;
+       sflash->size = sflash->blocksize * sflash->numblocks;
+       sflash->present = true;
+
        pr_info("Found %s serial flash (blocksize: 0x%X, blocks: %d)\n",
                e->name, e->blocksize, e->numblocks);
 
index afe79d40a99eaf36dd4eea67c5a0234a40eff683..6535e4718fdebeee689a1d214da4ca39f060f437 100644 (file)
@@ -20,6 +20,18 @@ struct ssb_pflash {
        u32 window_size;
 };
 
+#ifdef CONFIG_SSB_SFLASH
+struct ssb_sflash {
+       bool present;
+       u32 window;
+       u32 blocksize;
+       u16 numblocks;
+       u32 size;
+
+       void *priv;
+};
+#endif
+
 struct ssb_mipscore {
        struct ssb_device *dev;
 
@@ -27,6 +39,9 @@ struct ssb_mipscore {
        struct ssb_serial_port serial_ports[4];
 
        struct ssb_pflash pflash;
+#ifdef CONFIG_SSB_SFLASH
+       struct ssb_sflash sflash;
+#endif
 };
 
 extern void ssb_mipscore_init(struct ssb_mipscore *mcore);
index d817c932d634e6609081dbf8f492cf04463b867d..ace5e55fe5a32ed01fd8ca3c0c63c802632ac547 100644 (file)
@@ -341,7 +341,6 @@ static void hci_init1_req(struct hci_request *req, unsigned long opt)
 
 static void bredr_setup(struct hci_request *req)
 {
-       struct hci_cp_delete_stored_link_key cp;
        __le16 param;
        __u8 flt_type;
 
@@ -365,10 +364,6 @@ static void bredr_setup(struct hci_request *req)
        param = __constant_cpu_to_le16(0x7d00);
        hci_req_add(req, HCI_OP_WRITE_CA_TIMEOUT, 2, &param);
 
-       bacpy(&cp.bdaddr, BDADDR_ANY);
-       cp.delete_all = 0x01;
-       hci_req_add(req, HCI_OP_DELETE_STORED_LINK_KEY, sizeof(cp), &cp);
-
        /* Read page scan parameters */
        if (req->hdev->hci_ver > BLUETOOTH_VER_1_1) {
                hci_req_add(req, HCI_OP_READ_PAGE_SCAN_ACTIVITY, 0, NULL);
@@ -602,6 +597,16 @@ static void hci_init3_req(struct hci_request *req, unsigned long opt)
        struct hci_dev *hdev = req->hdev;
        u8 p;
 
+       /* Only send HCI_Delete_Stored_Link_Key if it is supported */
+       if (hdev->commands[6] & 0x80) {
+               struct hci_cp_delete_stored_link_key cp;
+
+               bacpy(&cp.bdaddr, BDADDR_ANY);
+               cp.delete_all = 0x01;
+               hci_req_add(req, HCI_OP_DELETE_STORED_LINK_KEY,
+                           sizeof(cp), &cp);
+       }
+
        if (hdev->commands[5] & 0x10)
                hci_setup_link_policy(req);
 
index 24bee07ee4ce1a54a86f5d5bd535b13bd1e42c02..4be6a264b47502a25fd21f2fdbb5c647e9b36f84 100644 (file)
@@ -2852,6 +2852,9 @@ static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn, u8 code,
        BT_DBG("conn %p, code 0x%2.2x, ident 0x%2.2x, len %u",
               conn, code, ident, dlen);
 
+       if (conn->mtu < L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE)
+               return NULL;
+
        len = L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE + dlen;
        count = min_t(unsigned int, conn->mtu, len);
 
index 64cf294c2b9680329f3925857305ca7843a6281b..082f270b59127a92acace0017d7b6973fbabf0a0 100644 (file)
@@ -1071,6 +1071,12 @@ static int ieee80211_stop_ap(struct wiphy *wiphy, struct net_device *dev)
        clear_bit(SDATA_STATE_OFFCHANNEL_BEACON_STOPPED, &sdata->state);
        ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON_ENABLED);
 
+       if (sdata->wdev.cac_started) {
+               cancel_delayed_work_sync(&sdata->dfs_cac_timer_work);
+               cfg80211_cac_event(sdata->dev, NL80211_RADAR_CAC_ABORTED,
+                                  GFP_KERNEL);
+       }
+
        drv_stop_ap(sdata->local, sdata);
 
        /* free all potentially still buffered bcast frames */
index 7a6f1a0207ec1dfc6fab981e8d23efd9f867b5b5..f97cd9d9105f7e21b2e98a6733711ecd3a785f38 100644 (file)
@@ -1513,10 +1513,11 @@ static inline void ieee80211_tx_skb(struct ieee80211_sub_if_data *sdata,
        ieee80211_tx_skb_tid(sdata, skb, 7);
 }
 
-u32 ieee802_11_parse_elems_crc(u8 *start, size_t len, bool action,
+u32 ieee802_11_parse_elems_crc(const u8 *start, size_t len, bool action,
                               struct ieee802_11_elems *elems,
                               u64 filter, u32 crc);
-static inline void ieee802_11_parse_elems(u8 *start, size_t len, bool action,
+static inline void ieee802_11_parse_elems(const u8 *start, size_t len,
+                                         bool action,
                                          struct ieee802_11_elems *elems)
 {
        ieee802_11_parse_elems_crc(start, len, action, elems, 0, 0);
index ad9bb9e10cbb04947cb3bcac1aa4c9674d2a186b..9e49f557fa5c2b1a6c9d57444e491c532560bca7 100644 (file)
@@ -2492,8 +2492,11 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata,
        u16 capab_info, aid;
        struct ieee802_11_elems elems;
        struct ieee80211_bss_conf *bss_conf = &sdata->vif.bss_conf;
+       const struct cfg80211_bss_ies *bss_ies = NULL;
+       struct ieee80211_mgd_assoc_data *assoc_data = ifmgd->assoc_data;
        u32 changed = 0;
        int err;
+       bool ret;
 
        /* AssocResp and ReassocResp have identical structure */
 
@@ -2524,6 +2527,69 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata,
 
        ifmgd->aid = aid;
 
+       /*
+        * Some APs are erroneously not including some information in their
+        * (re)association response frames. Try to recover by using the data
+        * from the beacon or probe response. This seems to afflict mobile
+        * 2G/3G/4G wifi routers, reported models include the "Onda PN51T",
+        * "Vodafone PocketWiFi 2", "ZTE MF60" and a similar T-Mobile device.
+        */
+       if ((assoc_data->wmm && !elems.wmm_param) ||
+           (!(ifmgd->flags & IEEE80211_STA_DISABLE_HT) &&
+            (!elems.ht_cap_elem || !elems.ht_operation)) ||
+           (!(ifmgd->flags & IEEE80211_STA_DISABLE_VHT) &&
+            (!elems.vht_cap_elem || !elems.vht_operation))) {
+               const struct cfg80211_bss_ies *ies;
+               struct ieee802_11_elems bss_elems;
+
+               rcu_read_lock();
+               ies = rcu_dereference(cbss->ies);
+               if (ies)
+                       bss_ies = kmemdup(ies, sizeof(*ies) + ies->len,
+                                         GFP_ATOMIC);
+               rcu_read_unlock();
+               if (!bss_ies)
+                       return false;
+
+               ieee802_11_parse_elems(bss_ies->data, bss_ies->len,
+                                      false, &bss_elems);
+               if (assoc_data->wmm &&
+                   !elems.wmm_param && bss_elems.wmm_param) {
+                       elems.wmm_param = bss_elems.wmm_param;
+                       sdata_info(sdata,
+                                  "AP bug: WMM param missing from AssocResp\n");
+               }
+
+               /*
+                * Also check if we requested HT/VHT, otherwise the AP doesn't
+                * have to include the IEs in the (re)association response.
+                */
+               if (!elems.ht_cap_elem && bss_elems.ht_cap_elem &&
+                   !(ifmgd->flags & IEEE80211_STA_DISABLE_HT)) {
+                       elems.ht_cap_elem = bss_elems.ht_cap_elem;
+                       sdata_info(sdata,
+                                  "AP bug: HT capability missing from AssocResp\n");
+               }
+               if (!elems.ht_operation && bss_elems.ht_operation &&
+                   !(ifmgd->flags & IEEE80211_STA_DISABLE_HT)) {
+                       elems.ht_operation = bss_elems.ht_operation;
+                       sdata_info(sdata,
+                                  "AP bug: HT operation missing from AssocResp\n");
+               }
+               if (!elems.vht_cap_elem && bss_elems.vht_cap_elem &&
+                   !(ifmgd->flags & IEEE80211_STA_DISABLE_VHT)) {
+                       elems.vht_cap_elem = bss_elems.vht_cap_elem;
+                       sdata_info(sdata,
+                                  "AP bug: VHT capa missing from AssocResp\n");
+               }
+               if (!elems.vht_operation && bss_elems.vht_operation &&
+                   !(ifmgd->flags & IEEE80211_STA_DISABLE_VHT)) {
+                       elems.vht_operation = bss_elems.vht_operation;
+                       sdata_info(sdata,
+                                  "AP bug: VHT operation missing from AssocResp\n");
+               }
+       }
+
        /*
         * We previously checked these in the beacon/probe response, so
         * they should be present here. This is just a safety net.
@@ -2531,15 +2597,17 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata,
        if (!(ifmgd->flags & IEEE80211_STA_DISABLE_HT) &&
            (!elems.wmm_param || !elems.ht_cap_elem || !elems.ht_operation)) {
                sdata_info(sdata,
-                          "HT AP is missing WMM params or HT capability/operation in AssocResp\n");
-               return false;
+                          "HT AP is missing WMM params or HT capability/operation\n");
+               ret = false;
+               goto out;
        }
 
        if (!(ifmgd->flags & IEEE80211_STA_DISABLE_VHT) &&
            (!elems.vht_cap_elem || !elems.vht_operation)) {
                sdata_info(sdata,
-                          "VHT AP is missing VHT capability/operation in AssocResp\n");
-               return false;
+                          "VHT AP is missing VHT capability/operation\n");
+               ret = false;
+               goto out;
        }
 
        mutex_lock(&sdata->local->sta_mtx);
@@ -2550,7 +2618,8 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata,
        sta = sta_info_get(sdata, cbss->bssid);
        if (WARN_ON(!sta)) {
                mutex_unlock(&sdata->local->sta_mtx);
-               return false;
+               ret = false;
+               goto out;
        }
 
        sband = local->hw.wiphy->bands[ieee80211_get_sdata_band(sdata)];
@@ -2603,7 +2672,8 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata,
                           sta->sta.addr);
                WARN_ON(__sta_info_destroy(sta));
                mutex_unlock(&sdata->local->sta_mtx);
-               return false;
+               ret = false;
+               goto out;
        }
 
        mutex_unlock(&sdata->local->sta_mtx);
@@ -2643,7 +2713,10 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata,
        ieee80211_sta_rx_notify(sdata, (struct ieee80211_hdr *)mgmt);
        ieee80211_sta_reset_beacon_monitor(sdata);
 
-       return true;
+       ret = true;
+ out:
+       kfree(bss_ies);
+       return ret;
 }
 
 static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
index d3f414fe67e0beb9592e87d344a6b3a5c0fed66b..a02bef35b134e28e6d5ad8d6da38c505c309e756 100644 (file)
@@ -615,7 +615,7 @@ static void rate_control_apply_mask(struct ieee80211_sub_if_data *sdata,
                if (rates[i].idx < 0)
                        break;
 
-               rate_idx_match_mask(&rates[i], sband, mask, chan_width,
+               rate_idx_match_mask(&rates[i], sband, chan_width, mask,
                                    mcs_mask);
        }
 }
index 5a6c1351d1d33c639ad85424d9c16d73f661997c..22654452a56157b44835f97efacdf2e8960ee5bc 100644 (file)
@@ -667,12 +667,12 @@ void ieee80211_queue_delayed_work(struct ieee80211_hw *hw,
 }
 EXPORT_SYMBOL(ieee80211_queue_delayed_work);
 
-u32 ieee802_11_parse_elems_crc(u8 *start, size_t len, bool action,
+u32 ieee802_11_parse_elems_crc(const u8 *start, size_t len, bool action,
                               struct ieee802_11_elems *elems,
                               u64 filter, u32 crc)
 {
        size_t left = len;
-       u8 *pos = start;
+       const u8 *pos = start;
        bool calc_crc = filter != 0;
        DECLARE_BITMAP(seen_elems, 256);
        const u8 *ie;