Merge branch 'for-upstream' of git://git.kernel.org/pub/scm/linux/kernel/git/bluetoot...
authorJohn W. Linville <linville@tuxdriver.com>
Mon, 4 Feb 2013 21:40:07 +0000 (16:40 -0500)
committerJohn W. Linville <linville@tuxdriver.com>
Mon, 4 Feb 2013 21:40:07 +0000 (16:40 -0500)
28 files changed:
drivers/bcma/driver_chipcommon_nflash.c
drivers/net/wireless/ath/ath9k/ar9003_calib.c
drivers/net/wireless/ath/ath9k/ar9003_phy.c
drivers/net/wireless/ath/ath9k/ath9k.h
drivers/net/wireless/ath/ath9k/beacon.c
drivers/net/wireless/ath/ath9k/debug.c
drivers/net/wireless/ath/ath9k/debug.h
drivers/net/wireless/ath/ath9k/htc_hst.c
drivers/net/wireless/ath/ath9k/hw.h
drivers/net/wireless/ath/ath9k/main.c
drivers/net/wireless/ath/ath9k/recv.c
drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
drivers/net/wireless/brcm80211/brcmsmac/main.c
drivers/net/wireless/iwlegacy/common.c
drivers/net/wireless/iwlwifi/dvm/tx.c
drivers/net/wireless/mwifiex/cfg80211.c
drivers/net/wireless/mwifiex/pcie.c
drivers/net/wireless/mwifiex/scan.c
drivers/net/wireless/mwifiex/sta_ioctl.c
drivers/net/wireless/rtlwifi/Kconfig
drivers/net/wireless/rtlwifi/usb.c
net/mac80211/cfg.c
net/mac80211/ieee80211_i.h
net/mac80211/mesh_hwmp.c
net/mac80211/offchannel.c
net/mac80211/scan.c
net/mac80211/tx.c
net/wireless/scan.c

index dbda91e4dff5189ccabbb710b7a2a11f0e099651..1f0b83e18f6827f5003669b4015c2a89b2d369c5 100644 (file)
@@ -21,7 +21,7 @@ int bcma_nflash_init(struct bcma_drv_cc *cc)
        struct bcma_bus *bus = cc->core->bus;
 
        if (bus->chipinfo.id != BCMA_CHIP_ID_BCM4706 &&
-           cc->core->id.rev != 0x38) {
+           cc->core->id.rev != 38) {
                bcma_err(bus, "NAND flash on unsupported board!\n");
                return -ENOTSUPP;
        }
index 8b0d8dcd76255239e7451b4a1258adca79ef8342..56317b0fb6b692f3f9ae20b8ba681ec18371788f 100644 (file)
@@ -976,6 +976,8 @@ static bool ar9003_hw_init_cal(struct ath_hw *ah,
                                          AR_PHY_CL_TAB_1,
                                          AR_PHY_CL_TAB_2 };
 
+       ar9003_hw_set_chain_masks(ah, ah->caps.rx_chainmask, ah->caps.tx_chainmask);
+
        if (rtt) {
                if (!ar9003_hw_rtt_restore(ah, chan))
                        run_rtt_cal = true;
index ce19c09fa8e84aec2877e2f14861b0284f4d958e..3afc24bde6d65d88a0d469abb0ef73d93856edcb 100644 (file)
@@ -586,32 +586,19 @@ static void ar9003_hw_init_bb(struct ath_hw *ah,
        ath9k_hw_synth_delay(ah, chan, synthDelay);
 }
 
-static void ar9003_hw_set_chain_masks(struct ath_hw *ah, u8 rx, u8 tx)
+void ar9003_hw_set_chain_masks(struct ath_hw *ah, u8 rx, u8 tx)
 {
-       switch (rx) {
-       case 0x5:
+       if (ah->caps.tx_chainmask == 5 || ah->caps.rx_chainmask == 5)
                REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP,
                            AR_PHY_SWAP_ALT_CHAIN);
-       case 0x3:
-       case 0x1:
-       case 0x2:
-       case 0x7:
-               REG_WRITE(ah, AR_PHY_RX_CHAINMASK, rx);
-               REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, rx);
-               break;
-       default:
-               break;
-       }
+
+       REG_WRITE(ah, AR_PHY_RX_CHAINMASK, rx);
+       REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, rx);
 
        if ((ah->caps.hw_caps & ATH9K_HW_CAP_APM) && (tx == 0x7))
-               REG_WRITE(ah, AR_SELFGEN_MASK, 0x3);
-       else
-               REG_WRITE(ah, AR_SELFGEN_MASK, tx);
+               tx = 3;
 
-       if (tx == 0x5) {
-               REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP,
-                           AR_PHY_SWAP_ALT_CHAIN);
-       }
+       REG_WRITE(ah, AR_SELFGEN_MASK, tx);
 }
 
 /*
index 86e26a19efdac1923395543c1a50fb53a6cb8958..42794c546a4068ac91b47c1252153b9040362555 100644 (file)
@@ -317,7 +317,6 @@ struct ath_rx {
        u32 *rxlink;
        u32 num_pkts;
        unsigned int rxfilter;
-       spinlock_t rxbuflock;
        struct list_head rxbuf;
        struct ath_descdma rxdma;
        struct ath_buf *rx_bufptr;
@@ -328,7 +327,6 @@ struct ath_rx {
 
 int ath_startrecv(struct ath_softc *sc);
 bool ath_stoprecv(struct ath_softc *sc);
-void ath_flushrecv(struct ath_softc *sc);
 u32 ath_calcrxfilter(struct ath_softc *sc);
 int ath_rx_init(struct ath_softc *sc, int nbufs);
 void ath_rx_cleanup(struct ath_softc *sc);
@@ -646,7 +644,6 @@ void ath_ant_comb_update(struct ath_softc *sc);
 enum sc_op_flags {
        SC_OP_INVALID,
        SC_OP_BEACONS,
-       SC_OP_RXFLUSH,
        SC_OP_ANI_RUN,
        SC_OP_PRIM_STA_VIF,
        SC_OP_HW_RESET,
index 531fffd801a34eaa11b8d483aca51ac07e7a7fab..2ca355e94da65467e36595990423c80be1b897b6 100644 (file)
@@ -147,6 +147,7 @@ static struct ath_buf *ath9k_beacon_generate(struct ieee80211_hw *hw,
                                 skb->len, DMA_TO_DEVICE);
                dev_kfree_skb_any(skb);
                bf->bf_buf_addr = 0;
+               bf->bf_mpdu = NULL;
        }
 
        skb = ieee80211_beacon_get(hw, vif);
@@ -359,7 +360,6 @@ void ath9k_beacon_tasklet(unsigned long data)
                return;
 
        bf = ath9k_beacon_generate(sc->hw, vif);
-       WARN_ON(!bf);
 
        if (sc->beacon.bmisscnt != 0) {
                ath_dbg(common, BSTUCK, "resume beacon xmit after %u misses\n",
index 13ff9edc24015e5e2126fc4f6c7fde8dcb003c90..e585fc827c50b2e9d5ff2fe08afb15cd49cedba6 100644 (file)
@@ -861,7 +861,6 @@ static ssize_t read_file_recv(struct file *file, char __user *user_buf,
        RXS_ERR("RX-LENGTH-ERR", rx_len_err);
        RXS_ERR("RX-OOM-ERR", rx_oom_err);
        RXS_ERR("RX-RATE-ERR", rx_rate_err);
-       RXS_ERR("RX-DROP-RXFLUSH", rx_drop_rxflush);
        RXS_ERR("RX-TOO-MANY-FRAGS", rx_too_many_frags_err);
 
        PHY_ERR("UNDERRUN ERR", ATH9K_PHYERR_UNDERRUN);
index 375c3b46411eee6cd140dbc22e6e435fe0e32ad9..6df2ab62dcb706df5bef4a8afdf04593651f111a 100644 (file)
@@ -216,7 +216,6 @@ struct ath_tx_stats {
  * @rx_oom_err:  No. of frames dropped due to OOM issues.
  * @rx_rate_err:  No. of frames dropped due to rate errors.
  * @rx_too_many_frags_err:  Frames dropped due to too-many-frags received.
- * @rx_drop_rxflush: No. of frames dropped due to RX-FLUSH.
  * @rx_beacons:  No. of beacons received.
  * @rx_frags:  No. of rx-fragements received.
  */
@@ -235,7 +234,6 @@ struct ath_rx_stats {
        u32 rx_oom_err;
        u32 rx_rate_err;
        u32 rx_too_many_frags_err;
-       u32 rx_drop_rxflush;
        u32 rx_beacons;
        u32 rx_frags;
 };
index 4a9570dfba72605d2f492ddf51cde8e8e7db835b..aac4a406a5134727e49fef2999e563e39169d83f 100644 (file)
@@ -344,6 +344,8 @@ void ath9k_htc_txcompletion_cb(struct htc_target *htc_handle,
                        endpoint->ep_callbacks.tx(endpoint->ep_callbacks.priv,
                                                  skb, htc_hdr->endpoint_id,
                                                  txok);
+               } else {
+                       kfree_skb(skb);
                }
        }
 
index 7f1a8e91c908c2dea314a7171e1d1d59139e6c6a..9d26fc56ca56a6bf7d4e8ac0ed91366df0de50cd 100644 (file)
@@ -1066,6 +1066,7 @@ void ar9003_paprd_setup_gain_table(struct ath_hw *ah, int chain);
 int ar9003_paprd_init_table(struct ath_hw *ah);
 bool ar9003_paprd_is_done(struct ath_hw *ah);
 bool ar9003_is_paprd_enabled(struct ath_hw *ah);
+void ar9003_hw_set_chain_masks(struct ath_hw *ah, u8 rx, u8 tx);
 
 /* Hardware family op attach helpers */
 void ar5008_hw_attach_phy_ops(struct ath_hw *ah);
index be30a9af152884d8e073b7a3be5b79e6b3d5a8ee..dd91f8fdc01c3ea44c922bbbbd14bee2df4fd6db 100644 (file)
@@ -182,7 +182,7 @@ static void ath_restart_work(struct ath_softc *sc)
        ath_start_ani(sc);
 }
 
-static bool ath_prepare_reset(struct ath_softc *sc, bool retry_tx, bool flush)
+static bool ath_prepare_reset(struct ath_softc *sc, bool retry_tx)
 {
        struct ath_hw *ah = sc->sc_ah;
        bool ret = true;
@@ -202,14 +202,6 @@ static bool ath_prepare_reset(struct ath_softc *sc, bool retry_tx, bool flush)
        if (!ath_drain_all_txq(sc, retry_tx))
                ret = false;
 
-       if (!flush) {
-               if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)
-                       ath_rx_tasklet(sc, 1, true);
-               ath_rx_tasklet(sc, 1, false);
-       } else {
-               ath_flushrecv(sc);
-       }
-
        return ret;
 }
 
@@ -262,11 +254,11 @@ static int ath_reset_internal(struct ath_softc *sc, struct ath9k_channel *hchan,
        struct ath_common *common = ath9k_hw_common(ah);
        struct ath9k_hw_cal_data *caldata = NULL;
        bool fastcc = true;
-       bool flush = false;
        int r;
 
        __ath_cancel_work(sc);
 
+       tasklet_disable(&sc->intr_tq);
        spin_lock_bh(&sc->sc_pcu_lock);
 
        if (!(sc->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)) {
@@ -276,11 +268,10 @@ static int ath_reset_internal(struct ath_softc *sc, struct ath9k_channel *hchan,
 
        if (!hchan) {
                fastcc = false;
-               flush = true;
                hchan = ah->curchan;
        }
 
-       if (!ath_prepare_reset(sc, retry_tx, flush))
+       if (!ath_prepare_reset(sc, retry_tx))
                fastcc = false;
 
        ath_dbg(common, CONFIG, "Reset to %u MHz, HT40: %d fastcc: %d\n",
@@ -302,6 +293,8 @@ static int ath_reset_internal(struct ath_softc *sc, struct ath9k_channel *hchan,
 
 out:
        spin_unlock_bh(&sc->sc_pcu_lock);
+       tasklet_enable(&sc->intr_tq);
+
        return r;
 }
 
@@ -804,7 +797,7 @@ static void ath9k_stop(struct ieee80211_hw *hw)
                ath9k_hw_cfg_gpio_input(ah, ah->led_pin);
        }
 
-       ath_prepare_reset(sc, false, true);
+       ath_prepare_reset(sc, false);
 
        if (sc->rx.frag) {
                dev_kfree_skb_any(sc->rx.frag);
@@ -1833,6 +1826,9 @@ static u32 fill_chainmask(u32 cap, u32 new)
 
 static bool validate_antenna_mask(struct ath_hw *ah, u32 val)
 {
+       if (AR_SREV_9300_20_OR_LATER(ah))
+               return true;
+
        switch (val & 0x7) {
        case 0x1:
        case 0x3:
index d4df98a938bf4755d1af6238d41e5df0753970c6..90752f2469704bbbb2bf7cae86a1c2cb4029435a 100644 (file)
@@ -254,8 +254,6 @@ rx_init_fail:
 
 static void ath_edma_start_recv(struct ath_softc *sc)
 {
-       spin_lock_bh(&sc->rx.rxbuflock);
-
        ath9k_hw_rxena(sc->sc_ah);
 
        ath_rx_addbuffer_edma(sc, ATH9K_RX_QUEUE_HP,
@@ -267,8 +265,6 @@ static void ath_edma_start_recv(struct ath_softc *sc)
        ath_opmode_init(sc);
 
        ath9k_hw_startpcureceive(sc->sc_ah, !!(sc->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL));
-
-       spin_unlock_bh(&sc->rx.rxbuflock);
 }
 
 static void ath_edma_stop_recv(struct ath_softc *sc)
@@ -285,8 +281,6 @@ int ath_rx_init(struct ath_softc *sc, int nbufs)
        int error = 0;
 
        spin_lock_init(&sc->sc_pcu_lock);
-       spin_lock_init(&sc->rx.rxbuflock);
-       clear_bit(SC_OP_RXFLUSH, &sc->sc_flags);
 
        common->rx_bufsize = IEEE80211_MAX_MPDU_LEN / 2 +
                             sc->sc_ah->caps.rx_status_len;
@@ -447,7 +441,6 @@ int ath_startrecv(struct ath_softc *sc)
                return 0;
        }
 
-       spin_lock_bh(&sc->rx.rxbuflock);
        if (list_empty(&sc->rx.rxbuf))
                goto start_recv;
 
@@ -468,26 +461,31 @@ start_recv:
        ath_opmode_init(sc);
        ath9k_hw_startpcureceive(ah, !!(sc->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL));
 
-       spin_unlock_bh(&sc->rx.rxbuflock);
-
        return 0;
 }
 
+static void ath_flushrecv(struct ath_softc *sc)
+{
+       if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)
+               ath_rx_tasklet(sc, 1, true);
+       ath_rx_tasklet(sc, 1, false);
+}
+
 bool ath_stoprecv(struct ath_softc *sc)
 {
        struct ath_hw *ah = sc->sc_ah;
        bool stopped, reset = false;
 
-       spin_lock_bh(&sc->rx.rxbuflock);
        ath9k_hw_abortpcurecv(ah);
        ath9k_hw_setrxfilter(ah, 0);
        stopped = ath9k_hw_stopdmarecv(ah, &reset);
 
+       ath_flushrecv(sc);
+
        if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)
                ath_edma_stop_recv(sc);
        else
                sc->rx.rxlink = NULL;
-       spin_unlock_bh(&sc->rx.rxbuflock);
 
        if (!(ah->ah_flags & AH_UNPLUGGED) &&
            unlikely(!stopped)) {
@@ -499,15 +497,6 @@ bool ath_stoprecv(struct ath_softc *sc)
        return stopped && !reset;
 }
 
-void ath_flushrecv(struct ath_softc *sc)
-{
-       set_bit(SC_OP_RXFLUSH, &sc->sc_flags);
-       if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)
-               ath_rx_tasklet(sc, 1, true);
-       ath_rx_tasklet(sc, 1, false);
-       clear_bit(SC_OP_RXFLUSH, &sc->sc_flags);
-}
-
 static bool ath_beacon_dtim_pending_cab(struct sk_buff *skb)
 {
        /* Check whether the Beacon frame has DTIM indicating buffered bc/mc */
@@ -744,6 +733,7 @@ static struct ath_buf *ath_get_next_rx_buf(struct ath_softc *sc,
                        return NULL;
        }
 
+       list_del(&bf->list);
        if (!bf->bf_mpdu)
                return bf;
 
@@ -1059,16 +1049,12 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
                dma_type = DMA_FROM_DEVICE;
 
        qtype = hp ? ATH9K_RX_QUEUE_HP : ATH9K_RX_QUEUE_LP;
-       spin_lock_bh(&sc->rx.rxbuflock);
 
        tsf = ath9k_hw_gettsf64(ah);
        tsf_lower = tsf & 0xffffffff;
 
        do {
                bool decrypt_error = false;
-               /* If handling rx interrupt and flush is in progress => exit */
-               if (test_bit(SC_OP_RXFLUSH, &sc->sc_flags) && (flush == 0))
-                       break;
 
                memset(&rs, 0, sizeof(rs));
                if (edma)
@@ -1111,15 +1097,6 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
 
                ath_debug_stat_rx(sc, &rs);
 
-               /*
-                * If we're asked to flush receive queue, directly
-                * chain it back at the queue without processing it.
-                */
-               if (test_bit(SC_OP_RXFLUSH, &sc->sc_flags)) {
-                       RX_STAT_INC(rx_drop_rxflush);
-                       goto requeue_drop_frag;
-               }
-
                memset(rxs, 0, sizeof(struct ieee80211_rx_status));
 
                rxs->mactime = (tsf & ~0xffffffffULL) | rs.rs_tstamp;
@@ -1254,19 +1231,18 @@ requeue_drop_frag:
                        sc->rx.frag = NULL;
                }
 requeue:
+               list_add_tail(&bf->list, &sc->rx.rxbuf);
+               if (flush)
+                       continue;
+
                if (edma) {
-                       list_add_tail(&bf->list, &sc->rx.rxbuf);
                        ath_rx_edma_buf_link(sc, qtype);
                } else {
-                       list_move_tail(&bf->list, &sc->rx.rxbuf);
                        ath_rx_buf_link(sc, bf);
-                       if (!flush)
-                               ath9k_hw_rxena(ah);
+                       ath9k_hw_rxena(ah);
                }
        } while (1);
 
-       spin_unlock_bh(&sc->rx.rxbuflock);
-
        if (!(ah->imask & ATH9K_INT_RXEOL)) {
                ah->imask |= (ATH9K_INT_RXEOL | ATH9K_INT_RXORN);
                ath9k_hw_set_interrupts(ah);
index 1fbd8ecbe2ea293a28d6a65648fe011a2fff3fa6..0f71d1d4339dc38ccfdd89428fdc4a62bb5b7bd9 100644 (file)
@@ -1407,9 +1407,10 @@ void brcms_add_timer(struct brcms_timer *t, uint ms, int periodic)
 #endif
        t->ms = ms;
        t->periodic = (bool) periodic;
-       t->set = true;
-
-       atomic_inc(&t->wl->callbacks);
+       if (!t->set) {
+               t->set = true;
+               atomic_inc(&t->wl->callbacks);
+       }
 
        ieee80211_queue_delayed_work(hw, &t->dly_wrk, msecs_to_jiffies(ms));
 }
index 17594de4199ef58a30488e2c7579ec02c521d9ea..9f3d7e9f3bb5a7c04bb6445d65ee73936a244f2c 100644 (file)
@@ -1027,7 +1027,6 @@ brcms_c_dotxstatus(struct brcms_c_info *wlc, struct tx_status *txs)
 static bool
 brcms_b_txstatus(struct brcms_hardware *wlc_hw, bool bound, bool *fatal)
 {
-       bool morepending = false;
        struct bcma_device *core;
        struct tx_status txstatus, *txs;
        u32 s1, s2;
@@ -1041,23 +1040,20 @@ brcms_b_txstatus(struct brcms_hardware *wlc_hw, bool bound, bool *fatal)
        txs = &txstatus;
        core = wlc_hw->d11core;
        *fatal = false;
-       s1 = bcma_read32(core, D11REGOFFS(frmtxstatus));
-       while (!(*fatal)
-              && (s1 & TXS_V)) {
-               /* !give others some time to run! */
-               if (n >= max_tx_num) {
-                       morepending = true;
-                       break;
-               }
 
+       while (n < max_tx_num) {
+               s1 = bcma_read32(core, D11REGOFFS(frmtxstatus));
                if (s1 == 0xffffffff) {
                        brcms_err(core, "wl%d: %s: dead chip\n", wlc_hw->unit,
                                  __func__);
                        *fatal = true;
                        return false;
                }
-               s2 = bcma_read32(core, D11REGOFFS(frmtxstatus2));
+               /* only process when valid */
+               if (!(s1 & TXS_V))
+                       break;
 
+               s2 = bcma_read32(core, D11REGOFFS(frmtxstatus2));
                txs->status = s1 & TXS_STATUS_MASK;
                txs->frameid = (s1 & TXS_FID_MASK) >> TXS_FID_SHIFT;
                txs->sequence = s2 & TXS_SEQ_MASK;
@@ -1065,15 +1061,12 @@ brcms_b_txstatus(struct brcms_hardware *wlc_hw, bool bound, bool *fatal)
                txs->lasttxtime = 0;
 
                *fatal = brcms_c_dotxstatus(wlc_hw->wlc, txs);
-
-               s1 = bcma_read32(core, D11REGOFFS(frmtxstatus));
+               if (*fatal == true)
+                       return false;
                n++;
        }
 
-       if (*fatal)
-               return false;
-
-       return morepending;
+       return n >= max_tx_num;
 }
 
 static void brcms_c_tbtt(struct brcms_c_info *wlc)
index 7e16d10a7f140e4bc0a1414af1ec317f7284b9c6..90b8970eadf0fa7c296be194c2d18ef9266b1043 100644 (file)
@@ -3958,17 +3958,21 @@ il_connection_init_rx_config(struct il_priv *il)
 
        memset(&il->staging, 0, sizeof(il->staging));
 
-       if (!il->vif) {
+       switch (il->iw_mode) {
+       case NL80211_IFTYPE_UNSPECIFIED:
                il->staging.dev_type = RXON_DEV_TYPE_ESS;
-       } else if (il->vif->type == NL80211_IFTYPE_STATION) {
+               break;
+       case NL80211_IFTYPE_STATION:
                il->staging.dev_type = RXON_DEV_TYPE_ESS;
                il->staging.filter_flags = RXON_FILTER_ACCEPT_GRP_MSK;
-       } else if (il->vif->type == NL80211_IFTYPE_ADHOC) {
+               break;
+       case NL80211_IFTYPE_ADHOC:
                il->staging.dev_type = RXON_DEV_TYPE_IBSS;
                il->staging.flags = RXON_FLG_SHORT_PREAMBLE_MSK;
                il->staging.filter_flags =
                    RXON_FILTER_BCON_AWARE_MSK | RXON_FILTER_ACCEPT_GRP_MSK;
-       } else {
+               break;
+       default:
                IL_ERR("Unsupported interface type %d\n", il->vif->type);
                return;
        }
@@ -4550,8 +4554,7 @@ out:
 EXPORT_SYMBOL(il_mac_add_interface);
 
 static void
-il_teardown_interface(struct il_priv *il, struct ieee80211_vif *vif,
-                     bool mode_change)
+il_teardown_interface(struct il_priv *il, struct ieee80211_vif *vif)
 {
        lockdep_assert_held(&il->mutex);
 
@@ -4560,9 +4563,7 @@ il_teardown_interface(struct il_priv *il, struct ieee80211_vif *vif,
                il_force_scan_end(il);
        }
 
-       if (!mode_change)
-               il_set_mode(il);
-
+       il_set_mode(il);
 }
 
 void
@@ -4575,8 +4576,8 @@ il_mac_remove_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
 
        WARN_ON(il->vif != vif);
        il->vif = NULL;
-
-       il_teardown_interface(il, vif, false);
+       il->iw_mode = NL80211_IFTYPE_UNSPECIFIED;
+       il_teardown_interface(il, vif);
        memset(il->bssid, 0, ETH_ALEN);
 
        D_MAC80211("leave\n");
@@ -4685,18 +4686,10 @@ il_mac_change_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
        }
 
        /* success */
-       il_teardown_interface(il, vif, true);
        vif->type = newtype;
        vif->p2p = false;
-       err = il_set_mode(il);
-       WARN_ON(err);
-       /*
-        * We've switched internally, but submitting to the
-        * device may have failed for some reason. Mask this
-        * error, because otherwise mac80211 will not switch
-        * (and set the interface type back) and we'll be
-        * out of sync with it.
-        */
+       il->iw_mode = newtype;
+       il_teardown_interface(il, vif);
        err = 0;
 
 out:
index a790599fe2c219b63526a833c3db63ac09d84e84..279796419ea0ca036800483aad59321e881efbe5 100644 (file)
@@ -1079,6 +1079,8 @@ static void iwlagn_set_tx_status(struct iwl_priv *priv,
 {
        u16 status = le16_to_cpu(tx_resp->status.status);
 
+       info->flags &= ~IEEE80211_TX_CTL_AMPDU;
+
        info->status.rates[0].count = tx_resp->failure_frame + 1;
        info->flags |= iwl_tx_status_to_mac80211(status);
        iwlagn_hwrate_to_tx_control(priv, le32_to_cpu(tx_resp->rate_n_flags),
@@ -1151,6 +1153,13 @@ int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb,
                        next_reclaimed = ssn;
                }
 
+               if (tid != IWL_TID_NON_QOS) {
+                       priv->tid_data[sta_id][tid].next_reclaimed =
+                               next_reclaimed;
+                       IWL_DEBUG_TX_REPLY(priv, "Next reclaimed packet:%d\n",
+                                                 next_reclaimed);
+               }
+
                iwl_trans_reclaim(priv->trans, txq_id, ssn, &skbs);
 
                iwlagn_check_ratid_empty(priv, sta_id, tid);
@@ -1201,28 +1210,11 @@ int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb,
                        if (!is_agg)
                                iwlagn_non_agg_tx_status(priv, ctx, hdr->addr1);
 
-                       /*
-                        * W/A for FW bug - the seq_ctl isn't updated when the
-                        * queues are flushed. Fetch it from the packet itself
-                        */
-                       if (!is_agg && status == TX_STATUS_FAIL_FIFO_FLUSHED) {
-                               next_reclaimed = le16_to_cpu(hdr->seq_ctrl);
-                               next_reclaimed =
-                                       SEQ_TO_SN(next_reclaimed + 0x10);
-                       }
-
                        is_offchannel_skb =
                                (info->flags & IEEE80211_TX_CTL_TX_OFFCHAN);
                        freed++;
                }
 
-               if (tid != IWL_TID_NON_QOS) {
-                       priv->tid_data[sta_id][tid].next_reclaimed =
-                               next_reclaimed;
-                       IWL_DEBUG_TX_REPLY(priv, "Next reclaimed packet:%d\n",
-                                          next_reclaimed);
-               }
-
                WARN_ON(!is_agg && freed != 1);
 
                /*
index efe525be27dd3607f63c76e49d089d5f7e34d0d5..cdb11b3964e27dd68de20ac68ab8442772a070a1 100644 (file)
@@ -1459,7 +1459,7 @@ mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len, u8 *ssid,
        struct cfg80211_ssid req_ssid;
        int ret, auth_type = 0;
        struct cfg80211_bss *bss = NULL;
-       u8 is_scanning_required = 0, config_bands = 0;
+       u8 is_scanning_required = 0;
 
        memset(&req_ssid, 0, sizeof(struct cfg80211_ssid));
 
@@ -1478,19 +1478,6 @@ mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len, u8 *ssid,
        /* disconnect before try to associate */
        mwifiex_deauthenticate(priv, NULL);
 
-       if (channel) {
-               if (mode == NL80211_IFTYPE_STATION) {
-                       if (channel->band == IEEE80211_BAND_2GHZ)
-                               config_bands = BAND_B | BAND_G | BAND_GN;
-                       else
-                               config_bands = BAND_A | BAND_AN;
-
-                       if (!((config_bands | priv->adapter->fw_bands) &
-                             ~priv->adapter->fw_bands))
-                               priv->adapter->config_bands = config_bands;
-               }
-       }
-
        /* As this is new association, clear locally stored
         * keys and security related flags */
        priv->sec_info.wpa_enabled = false;
@@ -1707,7 +1694,7 @@ static int mwifiex_set_ibss_params(struct mwifiex_private *priv,
 
                if (cfg80211_get_chandef_type(&params->chandef) !=
                                                NL80211_CHAN_NO_HT)
-                       config_bands |= BAND_GN;
+                       config_bands |= BAND_G | BAND_GN;
        } else {
                if (cfg80211_get_chandef_type(&params->chandef) ==
                                                NL80211_CHAN_NO_HT)
index 13fbc4eb15952fe375be1e10c55518bb2b6b3836..b879e1338a54f5347a7a5f0b955b98a3f3566b66 100644 (file)
@@ -161,7 +161,7 @@ static int mwifiex_pcie_suspend(struct pci_dev *pdev, pm_message_t state)
 
        if (pdev) {
                card = (struct pcie_service_card *) pci_get_drvdata(pdev);
-               if (!card || card->adapter) {
+               if (!card || !card->adapter) {
                        pr_err("Card or adapter structure is not valid\n");
                        return 0;
                }
index 9189a32b7844b713815636d03517e7532da31f94..973a9d90e9ea06542fe6b7e9169c0de6d4922531 100644 (file)
@@ -1563,7 +1563,7 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv,
                dev_err(adapter->dev, "SCAN_RESP: too many AP returned (%d)\n",
                        scan_rsp->number_of_sets);
                ret = -1;
-               goto done;
+               goto check_next_scan;
        }
 
        bytes_left = le16_to_cpu(scan_rsp->bss_descript_size);
@@ -1634,7 +1634,8 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv,
                if (!beacon_size || beacon_size > bytes_left) {
                        bss_info += bytes_left;
                        bytes_left = 0;
-                       return -1;
+                       ret = -1;
+                       goto check_next_scan;
                }
 
                /* Initialize the current working beacon pointer for this BSS
@@ -1690,7 +1691,7 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv,
                                dev_err(priv->adapter->dev,
                                        "%s: bytes left < IE length\n",
                                        __func__);
-                               goto done;
+                               goto check_next_scan;
                        }
                        if (element_id == WLAN_EID_DS_PARAMS) {
                                channel = *(current_ptr + sizeof(struct ieee_types_header));
@@ -1753,6 +1754,7 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv,
                }
        }
 
+check_next_scan:
        spin_lock_irqsave(&adapter->scan_pending_q_lock, flags);
        if (list_empty(&adapter->scan_pending_q)) {
                spin_unlock_irqrestore(&adapter->scan_pending_q_lock, flags);
@@ -1813,7 +1815,6 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv,
                }
        }
 
-done:
        return ret;
 }
 
index 60e88b58039de129f060160f9e18baa49fde0a3d..f542bb8ccbc8d4ce6859e8fff1e45784183f8fbb 100644 (file)
@@ -283,6 +283,20 @@ int mwifiex_bss_start(struct mwifiex_private *priv, struct cfg80211_bss *bss,
                if (ret)
                        goto done;
 
+               if (bss_desc) {
+                       u8 config_bands = 0;
+
+                       if (mwifiex_band_to_radio_type((u8) bss_desc->bss_band)
+                           == HostCmd_SCAN_RADIO_TYPE_BG)
+                               config_bands = BAND_B | BAND_G | BAND_GN;
+                       else
+                               config_bands = BAND_A | BAND_AN;
+
+                       if (!((config_bands | adapter->fw_bands) &
+                             ~adapter->fw_bands))
+                               adapter->config_bands = config_bands;
+               }
+
                ret = mwifiex_check_network_compatibility(priv, bss_desc);
                if (ret)
                        goto done;
index 21b1bbb93a7e41452720a6f9ede17cba3951393e..b80bc4612581857455c2e076de835f66ac5be710 100644 (file)
@@ -57,12 +57,12 @@ config RTL8192CU
 
 config RTLWIFI
        tristate
-       depends on RTL8192CE || RTL8192CU || RTL8192SE || RTL8192DE
+       depends on RTL8192CE || RTL8192CU || RTL8192SE || RTL8192DE || RTL8723AE
        default m
 
 config RTLWIFI_DEBUG
        bool "Additional debugging output"
-       depends on RTL8192CE || RTL8192CU || RTL8192SE || RTL8192DE
+       depends on RTL8192CE || RTL8192CU || RTL8192SE || RTL8192DE || RTL8723AE
        default y
 
 config RTL8192C_COMMON
index f2ecdeb3a90d441ee809af029a1db1c8dab80f48..1535efda3d525a0dfafe54bb4442aacec4b00446 100644 (file)
@@ -542,8 +542,8 @@ static void _rtl_rx_pre_process(struct ieee80211_hw *hw, struct sk_buff *skb)
        WARN_ON(skb_queue_empty(&rx_queue));
        while (!skb_queue_empty(&rx_queue)) {
                _skb = skb_dequeue(&rx_queue);
-               _rtl_usb_rx_process_agg(hw, skb);
-               ieee80211_rx_irqsafe(hw, skb);
+               _rtl_usb_rx_process_agg(hw, _skb);
+               ieee80211_rx_irqsafe(hw, _skb);
        }
 }
 
index 47e0aca614b78462e876cbdb5cbd31695af630c5..516fbc96feff11831a9ad308541e6bdc16a7089d 100644 (file)
@@ -164,7 +164,17 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev,
                        sta = sta_info_get(sdata, mac_addr);
                else
                        sta = sta_info_get_bss(sdata, mac_addr);
-               if (!sta) {
+               /*
+                * The ASSOC test makes sure the driver is ready to
+                * receive the key. When wpa_supplicant has roamed
+                * using FT, it attempts to set the key before
+                * association has completed, this rejects that attempt
+                * so it will set the key again after assocation.
+                *
+                * TODO: accept the key if we have a station entry and
+                *       add it to the device after the station.
+                */
+               if (!sta || !test_sta_flag(sta, WLAN_STA_ASSOC)) {
                        ieee80211_key_free(sdata->local, key);
                        err = -ENOENT;
                        goto out_unlock;
index 8563b9a5cac325aa8ddb5fe817712462de2b6561..2ed065c095629403c42574872fec6a8b85819871 100644 (file)
@@ -1358,10 +1358,8 @@ int ieee80211_request_sched_scan_stop(struct ieee80211_sub_if_data *sdata);
 void ieee80211_sched_scan_stopped_work(struct work_struct *work);
 
 /* off-channel helpers */
-void ieee80211_offchannel_stop_vifs(struct ieee80211_local *local,
-                                   bool offchannel_ps_enable);
-void ieee80211_offchannel_return(struct ieee80211_local *local,
-                                bool offchannel_ps_disable);
+void ieee80211_offchannel_stop_vifs(struct ieee80211_local *local);
+void ieee80211_offchannel_return(struct ieee80211_local *local);
 void ieee80211_roc_setup(struct ieee80211_local *local);
 void ieee80211_start_next_roc(struct ieee80211_local *local);
 void ieee80211_roc_purge(struct ieee80211_sub_if_data *sdata);
index 47aeee2d8db160f6fa9eb62c32131bbd686acc29..2659e428b80c86cf367a75b034c8d89a856f28a1 100644 (file)
@@ -215,6 +215,7 @@ static void prepare_frame_for_deferred_tx(struct ieee80211_sub_if_data *sdata,
        skb->priority = 7;
 
        info->control.vif = &sdata->vif;
+       info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING;
        ieee80211_set_qos_hdr(sdata, skb);
 }
 
@@ -246,11 +247,13 @@ int mesh_path_error_tx(u8 ttl, u8 *target, __le32 target_sn,
                return -EAGAIN;
 
        skb = dev_alloc_skb(local->tx_headroom +
+                           IEEE80211_ENCRYPT_HEADROOM +
+                           IEEE80211_ENCRYPT_TAILROOM +
                            hdr_len +
                            2 + 15 /* PERR IE */);
        if (!skb)
                return -1;
-       skb_reserve(skb, local->tx_headroom);
+       skb_reserve(skb, local->tx_headroom + IEEE80211_ENCRYPT_HEADROOM);
        mgmt = (struct ieee80211_mgmt *) skb_put(skb, hdr_len);
        memset(mgmt, 0, hdr_len);
        mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
index a5379aea7d09d2410c70a3b467a1f336aa32dc43..a3ad4c3c80a34229801bdbdd1124201485a2f671 100644 (file)
@@ -102,8 +102,7 @@ static void ieee80211_offchannel_ps_disable(struct ieee80211_sub_if_data *sdata)
        ieee80211_sta_reset_conn_monitor(sdata);
 }
 
-void ieee80211_offchannel_stop_vifs(struct ieee80211_local *local,
-                                   bool offchannel_ps_enable)
+void ieee80211_offchannel_stop_vifs(struct ieee80211_local *local)
 {
        struct ieee80211_sub_if_data *sdata;
 
@@ -134,8 +133,7 @@ void ieee80211_offchannel_stop_vifs(struct ieee80211_local *local,
 
                if (sdata->vif.type != NL80211_IFTYPE_MONITOR) {
                        netif_tx_stop_all_queues(sdata->dev);
-                       if (offchannel_ps_enable &&
-                           (sdata->vif.type == NL80211_IFTYPE_STATION) &&
+                       if (sdata->vif.type == NL80211_IFTYPE_STATION &&
                            sdata->u.mgd.associated)
                                ieee80211_offchannel_ps_enable(sdata);
                }
@@ -143,8 +141,7 @@ void ieee80211_offchannel_stop_vifs(struct ieee80211_local *local,
        mutex_unlock(&local->iflist_mtx);
 }
 
-void ieee80211_offchannel_return(struct ieee80211_local *local,
-                                bool offchannel_ps_disable)
+void ieee80211_offchannel_return(struct ieee80211_local *local)
 {
        struct ieee80211_sub_if_data *sdata;
 
@@ -163,11 +160,9 @@ void ieee80211_offchannel_return(struct ieee80211_local *local,
                        continue;
 
                /* Tell AP we're back */
-               if (offchannel_ps_disable &&
-                   sdata->vif.type == NL80211_IFTYPE_STATION) {
-                       if (sdata->u.mgd.associated)
-                               ieee80211_offchannel_ps_disable(sdata);
-               }
+               if (sdata->vif.type == NL80211_IFTYPE_STATION &&
+                   sdata->u.mgd.associated)
+                       ieee80211_offchannel_ps_disable(sdata);
 
                if (sdata->vif.type != NL80211_IFTYPE_MONITOR) {
                        /*
@@ -385,7 +380,7 @@ void ieee80211_sw_roc_work(struct work_struct *work)
                        local->tmp_channel = NULL;
                        ieee80211_hw_config(local, 0);
 
-                       ieee80211_offchannel_return(local, true);
+                       ieee80211_offchannel_return(local);
                }
 
                ieee80211_recalc_idle(local);
index d59fc6818b1cc7c8d239e579166c04aa56461553..bf82e69d0601bf9210e817837b2af7725a9f7d87 100644 (file)
@@ -292,7 +292,7 @@ static void __ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted,
        if (!was_hw_scan) {
                ieee80211_configure_filter(local);
                drv_sw_scan_complete(local);
-               ieee80211_offchannel_return(local, true);
+               ieee80211_offchannel_return(local);
        }
 
        ieee80211_recalc_idle(local);
@@ -341,7 +341,7 @@ static int ieee80211_start_sw_scan(struct ieee80211_local *local)
        local->next_scan_state = SCAN_DECISION;
        local->scan_channel_idx = 0;
 
-       ieee80211_offchannel_stop_vifs(local, true);
+       ieee80211_offchannel_stop_vifs(local);
 
        ieee80211_configure_filter(local);
 
@@ -678,12 +678,8 @@ static void ieee80211_scan_state_suspend(struct ieee80211_local *local,
        local->scan_channel = NULL;
        ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);
 
-       /*
-        * Re-enable vifs and beaconing.  Leave PS
-        * in off-channel state..will put that back
-        * on-channel at the end of scanning.
-        */
-       ieee80211_offchannel_return(local, false);
+       /* disable PS */
+       ieee80211_offchannel_return(local);
 
        *next_delay = HZ / 5;
        /* afterwards, resume scan & go to next channel */
@@ -693,8 +689,7 @@ static void ieee80211_scan_state_suspend(struct ieee80211_local *local,
 static void ieee80211_scan_state_resume(struct ieee80211_local *local,
                                        unsigned long *next_delay)
 {
-       /* PS already is in off-channel mode */
-       ieee80211_offchannel_stop_vifs(local, false);
+       ieee80211_offchannel_stop_vifs(local);
 
        if (local->ops->flush) {
                drv_flush(local, false);
index e9eadc40c09cc20bce9ad37531ef45ae767f62e8..467c1d1b66f2f5615182abd689349027b88abe64 100644 (file)
@@ -1673,10 +1673,13 @@ netdev_tx_t ieee80211_monitor_start_xmit(struct sk_buff *skb,
                        chanctx_conf =
                                rcu_dereference(tmp_sdata->vif.chanctx_conf);
        }
-       if (!chanctx_conf)
-               goto fail_rcu;
 
-       chan = chanctx_conf->def.chan;
+       if (chanctx_conf)
+               chan = chanctx_conf->def.chan;
+       else if (!local->use_chanctx)
+               chan = local->_oper_channel;
+       else
+               goto fail_rcu;
 
        /*
         * Frame injection is not allowed if beaconing is not allowed
index 01592d7d4789e389fd565e7cf9fb194dc7ee7bb0..45f1618c8e239c2db21692cfa5358f460918b76d 100644 (file)
@@ -1358,7 +1358,7 @@ ieee80211_bss(struct wiphy *wiphy, struct iw_request_info *info,
                                                  &iwe, IW_EV_UINT_LEN);
        }
 
-       buf = kmalloc(30, GFP_ATOMIC);
+       buf = kmalloc(31, GFP_ATOMIC);
        if (buf) {
                memset(&iwe, 0, sizeof(iwe));
                iwe.cmd = IWEVCUSTOM;