]> bbs.cooldavid.org Git - net-next-2.6.git/commitdiff
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wirel...
authorDavid S. Miller <davem@davemloft.net>
Tue, 16 Nov 2010 17:17:12 +0000 (09:17 -0800)
committerDavid S. Miller <davem@davemloft.net>
Tue, 16 Nov 2010 17:17:12 +0000 (09:17 -0800)
1  2 
drivers/net/wireless/ath/ath9k/ath9k.h
drivers/net/wireless/ath/ath9k/hw.c
drivers/net/wireless/ath/ath9k/hw.h
drivers/net/wireless/ath/ath9k/init.c
drivers/net/wireless/ath/ath9k/main.c
drivers/net/wireless/ath/ath9k/recv.c
drivers/net/wireless/ath/carl9170/usb.c
drivers/net/wireless/iwlwifi/iwl3945-base.c

index 170d44a35ccbd2ca06886be2be2ed8c1cd5dcf25,21433465bde4d326a8953252634a4b0456e68b1b..b3180935875de7aebb4ad43ab72be45e08991c01
@@@ -195,7 -195,6 +195,6 @@@ enum ATH_AGGR_STATUS 
  
  #define ATH_TXFIFO_DEPTH 8
  struct ath_txq {
-       int axq_class;
        u32 axq_qnum;
        u32 *axq_link;
        struct list_head axq_q;
        struct list_head txq_fifo_pending;
        u8 txq_headidx;
        u8 txq_tailidx;
+       int pending_frames;
  };
  
  struct ath_atx_ac {
+       struct ath_txq *txq;
        int sched;
-       int qnum;
        struct list_head list;
        struct list_head tid_q;
  };
@@@ -270,7 -270,6 +270,6 @@@ struct ath_node 
        struct ath_atx_ac ac[WME_NUM_AC];
        u16 maxampdu;
        u8 mpdudensity;
-       int last_rssi;
  };
  
  #define AGGR_CLEANUP         BIT(1)
@@@ -291,12 -290,11 +290,11 @@@ struct ath_tx_control 
  struct ath_tx {
        u16 seq_no;
        u32 txqsetup;
-       int hwq_map[WME_NUM_AC];
        spinlock_t txbuflock;
        struct list_head txbuf;
        struct ath_txq txq[ATH9K_NUM_TX_QUEUES];
        struct ath_descdma txdma;
-       int pending_frames[WME_NUM_AC];
+       struct ath_txq *txq_map[WME_NUM_AC];
  };
  
  struct ath_rx_edma {
@@@ -310,7 -308,6 +308,6 @@@ struct ath_rx 
        u8 rxotherant;
        u32 *rxlink;
        unsigned int rxfilter;
-       spinlock_t pcu_lock;
        spinlock_t rxbuflock;
        struct list_head rxbuf;
        struct ath_descdma rxdma;
@@@ -327,7 -324,6 +324,6 @@@ void ath_rx_cleanup(struct ath_softc *s
  int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp);
  struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype);
  void ath_tx_cleanupq(struct ath_softc *sc, struct ath_txq *txq);
- int ath_tx_setup(struct ath_softc *sc, int haltype);
  void ath_drain_all_txq(struct ath_softc *sc, bool retry_tx);
  void ath_draintxq(struct ath_softc *sc,
                     struct ath_txq *txq, bool retry_tx);
@@@ -600,9 -596,9 +596,9 @@@ struct ath_softc 
        struct ath_hw *sc_ah;
        void __iomem *mem;
        int irq;
-       spinlock_t sc_resetlock;
        spinlock_t sc_serial_rw;
        spinlock_t sc_pm_lock;
+       spinlock_t sc_pcu_lock;
        struct mutex mutex;
        struct work_struct paprd_work;
        struct work_struct hw_check_work;
@@@ -662,11 -658,11 +658,11 @@@ struct ath_wiphy 
        bool idle;
        int chan_idx;
        int chan_is_ht;
+       int last_rssi;
  };
  
  void ath9k_tasklet(unsigned long data);
  int ath_reset(struct ath_softc *sc, bool retry_tx);
- int ath_get_mac80211_qnum(u32 queue, struct ath_softc *sc);
  int ath_cabq_update(struct ath_softc *);
  
  static inline void ath_read_cachesize(struct ath_common *common, int *csz)
  }
  
  extern struct ieee80211_ops ath9k_ops;
 +extern struct pm_qos_request_list ath9k_pm_qos_req;
  extern int modparam_nohwcrypt;
  extern int led_blink;
  
index 6ebc68bca91f0a999614572b38f69452df49645d,e75d8e8cf4d2ddcf505bfdec8cc06ed4037372b2..5fb1bf33faa0922af81cc3c2fae5a181e70fe884
@@@ -484,7 -484,6 +484,7 @@@ static int ath9k_hw_post_init(struct at
                ath_print(ath9k_hw_common(ah), ATH_DBG_FATAL,
                          "Failed allocating banks for "
                          "external radio\n");
 +              ath9k_hw_rf_free_ext_banks(ah);
                return ecode;
        }
  
@@@ -953,12 -952,9 +953,12 @@@ static void ath9k_hw_set_operating_mode
                REG_SET_BIT(ah, AR_CFG, AR_CFG_AP_ADHOC_INDICATION);
                break;
        case NL80211_IFTYPE_STATION:
 -      case NL80211_IFTYPE_MONITOR:
                REG_WRITE(ah, AR_STA_ID1, val | AR_STA_ID1_KSRCH_MODE);
                break;
 +      default:
 +              if (ah->is_monitoring)
 +                      REG_WRITE(ah, AR_STA_ID1, val | AR_STA_ID1_KSRCH_MODE);
 +              break;
        }
  }
  
@@@ -1170,7 -1166,7 +1170,7 @@@ static bool ath9k_hw_channel_change(str
                             channel->max_antenna_gain * 2,
                             channel->max_power * 2,
                             min((u32) MAX_RATE_POWER,
-                            (u32) regulatory->power_limit));
+                            (u32) regulatory->power_limit), false);
  
        ath9k_hw_rfbus_done(ah);
  
@@@ -1638,6 -1634,7 +1638,6 @@@ void ath9k_hw_beaconinit(struct ath_hw 
  
        switch (ah->opmode) {
        case NL80211_IFTYPE_STATION:
 -      case NL80211_IFTYPE_MONITOR:
                REG_WRITE(ah, AR_NEXT_TBTT_TIMER, TU_TO_USEC(next_beacon));
                REG_WRITE(ah, AR_NEXT_DMA_BEACON_ALERT, 0xffff);
                REG_WRITE(ah, AR_NEXT_SWBA, 0x7ffff);
                        AR_TBTT_TIMER_EN | AR_DBA_TIMER_EN | AR_SWBA_TIMER_EN;
                break;
        default:
 +              if (ah->is_monitoring) {
 +                      REG_WRITE(ah, AR_NEXT_TBTT_TIMER,
 +                                      TU_TO_USEC(next_beacon));
 +                      REG_WRITE(ah, AR_NEXT_DMA_BEACON_ALERT, 0xffff);
 +                      REG_WRITE(ah, AR_NEXT_SWBA, 0x7ffff);
 +                      flags |= AR_TBTT_TIMER_EN;
 +                      break;
 +              }
                ath_print(ath9k_hw_common(ah), ATH_DBG_BEACON,
                          "%s: unsupported opmode: %d\n",
                          __func__, ah->opmode);
@@@ -2176,7 -2165,7 +2176,7 @@@ bool ath9k_hw_disable(struct ath_hw *ah
  }
  EXPORT_SYMBOL(ath9k_hw_disable);
  
- void ath9k_hw_set_txpowerlimit(struct ath_hw *ah, u32 limit)
+ void ath9k_hw_set_txpowerlimit(struct ath_hw *ah, u32 limit, bool test)
  {
        struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
        struct ath9k_channel *chan = ah->curchan;
                                 channel->max_antenna_gain * 2,
                                 channel->max_power * 2,
                                 min((u32) MAX_RATE_POWER,
-                                (u32) regulatory->power_limit));
+                                (u32) regulatory->power_limit), test);
  }
  EXPORT_SYMBOL(ath9k_hw_set_txpowerlimit);
  
@@@ -2323,11 -2312,10 +2323,10 @@@ static u32 rightmost_index(struct ath_g
        return timer_table->gen_timer_index[b];
  }
  
- u32 ath9k_hw_gettsf32(struct ath_hw *ah)
static u32 ath9k_hw_gettsf32(struct ath_hw *ah)
  {
        return REG_READ(ah, AR_TSF_L32);
  }
- EXPORT_SYMBOL(ath9k_hw_gettsf32);
  
  struct ath_gen_timer *ath_gen_timer_alloc(struct ath_hw *ah,
                                          void (*trigger)(void *),
index d47d1b4b6002f2650cba8c80401cd52089800cc6,f821a28bcda3febf568eebaf177c39f547e74b99..e29c7122f466f3742e63e8d33ddf28e6861fdd6e
  #define PAPRD_GAIN_TABLE_ENTRIES    32
  #define PAPRD_TABLE_SZ              24
  
+ enum ath_hw_txq_subtype {
+       ATH_TXQ_AC_BE = 0,
+       ATH_TXQ_AC_BK = 1,
+       ATH_TXQ_AC_VI = 2,
+       ATH_TXQ_AC_VO = 3,
+ };
  enum ath_ini_subsys {
        ATH_INI_PRE = 0,
        ATH_INI_CORE,
@@@ -622,7 -629,6 +629,7 @@@ struct ath_hw 
  
        bool sw_mgmt_crypto;
        bool is_pciexpress;
 +      bool is_monitoring;
        bool need_an_top2_fixup;
        u16 tx_trig_level;
  
@@@ -819,12 -825,6 +826,6 @@@ static inline struct ath_hw_ops *ath9k_
        return &ah->ops;
  }
  
- static inline int sign_extend(int val, const int nbits)
- {
-       int order = BIT(nbits-1);
-       return (val ^ order) - order;
- }
  /* Initialization, Detach, Reset */
  const char *ath9k_hw_probe(u16 vendorid, u16 devid);
  void ath9k_hw_deinit(struct ath_hw *ah);
@@@ -861,7 -861,7 +862,7 @@@ u32 ath9k_hw_getrxfilter(struct ath_hw 
  void ath9k_hw_setrxfilter(struct ath_hw *ah, u32 bits);
  bool ath9k_hw_phy_disable(struct ath_hw *ah);
  bool ath9k_hw_disable(struct ath_hw *ah);
- void ath9k_hw_set_txpowerlimit(struct ath_hw *ah, u32 limit);
+ void ath9k_hw_set_txpowerlimit(struct ath_hw *ah, u32 limit, bool test);
  void ath9k_hw_setopmode(struct ath_hw *ah);
  void ath9k_hw_setmcastfilter(struct ath_hw *ah, u32 filter0, u32 filter1);
  void ath9k_hw_setbssidmask(struct ath_hw *ah);
@@@ -893,7 -893,6 +894,6 @@@ void ath9k_hw_gen_timer_stop(struct ath
  
  void ath_gen_timer_free(struct ath_hw *ah, struct ath_gen_timer *timer);
  void ath_gen_timer_isr(struct ath_hw *hw);
- u32 ath9k_hw_gettsf32(struct ath_hw *ah);
  
  void ath9k_hw_name(struct ath_hw *ah, char *hw_name, size_t len);
  
index 6a0d99eff404b77417856c7f1b7c035eb079359e,498f62180f1c591fee9d60d77236749fe391744c..d28e580bb4863d4483435b6600a9ac0fd15098a5
@@@ -15,7 -15,6 +15,7 @@@
   */
  
  #include <linux/slab.h>
 +#include <linux/pm_qos_params.h>
  
  #include "ath9k.h"
  
@@@ -180,8 -179,6 +180,8 @@@ static const struct ath_ops ath9k_commo
        .write = ath9k_iowrite32,
  };
  
 +struct pm_qos_request_list ath9k_pm_qos_req;
 +
  /**************************/
  /*     Initialization     */
  /**************************/
@@@ -398,7 -395,8 +398,8 @@@ static void ath9k_init_crypto(struct at
  
  static int ath9k_init_btcoex(struct ath_softc *sc)
  {
-       int r, qnum;
+       struct ath_txq *txq;
+       int r;
  
        switch (sc->sc_ah->btcoex_hw.scheme) {
        case ATH_BTCOEX_CFG_NONE:
                r = ath_init_btcoex_timer(sc);
                if (r)
                        return -1;
-               qnum = sc->tx.hwq_map[WME_AC_BE];
-               ath9k_hw_init_btcoex_hw(sc->sc_ah, qnum);
+               txq = sc->tx.txq_map[WME_AC_BE];
+               ath9k_hw_init_btcoex_hw(sc->sc_ah, txq->axq_qnum);
                sc->btcoex.bt_stomp_type = ATH_BTCOEX_STOMP_LOW;
                break;
        default:
  
  static int ath9k_init_queues(struct ath_softc *sc)
  {
-       struct ath_common *common = ath9k_hw_common(sc->sc_ah);
        int i = 0;
  
-       for (i = 0; i < ARRAY_SIZE(sc->tx.hwq_map); i++)
-               sc->tx.hwq_map[i] = -1;
        sc->beacon.beaconq = ath9k_hw_beaconq_setup(sc->sc_ah);
-       if (sc->beacon.beaconq == -1) {
-               ath_print(common, ATH_DBG_FATAL,
-                         "Unable to setup a beacon xmit queue\n");
-               goto err;
-       }
        sc->beacon.cabq = ath_txq_setup(sc, ATH9K_TX_QUEUE_CAB, 0);
-       if (sc->beacon.cabq == NULL) {
-               ath_print(common, ATH_DBG_FATAL,
-                         "Unable to setup CAB xmit queue\n");
-               goto err;
-       }
  
        sc->config.cabqReadytime = ATH_CABQ_READY_TIME;
        ath_cabq_update(sc);
  
-       if (!ath_tx_setup(sc, WME_AC_BK)) {
-               ath_print(common, ATH_DBG_FATAL,
-                         "Unable to setup xmit queue for BK traffic\n");
-               goto err;
-       }
-       if (!ath_tx_setup(sc, WME_AC_BE)) {
-               ath_print(common, ATH_DBG_FATAL,
-                         "Unable to setup xmit queue for BE traffic\n");
-               goto err;
-       }
-       if (!ath_tx_setup(sc, WME_AC_VI)) {
-               ath_print(common, ATH_DBG_FATAL,
-                         "Unable to setup xmit queue for VI traffic\n");
-               goto err;
-       }
-       if (!ath_tx_setup(sc, WME_AC_VO)) {
-               ath_print(common, ATH_DBG_FATAL,
-                         "Unable to setup xmit queue for VO traffic\n");
-               goto err;
-       }
+       for (i = 0; i < WME_NUM_AC; i++)
+               sc->tx.txq_map[i] = ath_txq_setup(sc, ATH9K_TX_QUEUE_DATA, i);
  
        return 0;
- err:
-       for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++)
-               if (ATH_TXQ_SETUP(sc, i))
-                       ath_tx_cleanupq(sc, &sc->tx.txq[i]);
-       return -EIO;
  }
  
  static int ath9k_init_channels_rates(struct ath_softc *sc)
@@@ -583,7 -540,6 +543,6 @@@ static int ath9k_init_softc(u16 devid, 
        spin_lock_init(&common->cc_lock);
  
        spin_lock_init(&sc->wiphy_lock);
-       spin_lock_init(&sc->sc_resetlock);
        spin_lock_init(&sc->sc_serial_rw);
        spin_lock_init(&sc->sc_pm_lock);
        mutex_init(&sc->mutex);
@@@ -645,6 -601,37 +604,37 @@@ err_hw
        return ret;
  }
  
+ static void ath9k_init_band_txpower(struct ath_softc *sc, int band)
+ {
+       struct ieee80211_supported_band *sband;
+       struct ieee80211_channel *chan;
+       struct ath_hw *ah = sc->sc_ah;
+       struct ath_regulatory *reg = ath9k_hw_regulatory(ah);
+       int i;
+       sband = &sc->sbands[band];
+       for (i = 0; i < sband->n_channels; i++) {
+               chan = &sband->channels[i];
+               ah->curchan = &ah->channels[chan->hw_value];
+               ath9k_cmn_update_ichannel(ah->curchan, chan, NL80211_CHAN_HT20);
+               ath9k_hw_set_txpowerlimit(ah, MAX_RATE_POWER, true);
+               chan->max_power = reg->max_power_level / 2;
+       }
+ }
+ static void ath9k_init_txpower_limits(struct ath_softc *sc)
+ {
+       struct ath_hw *ah = sc->sc_ah;
+       struct ath9k_channel *curchan = ah->curchan;
+       if (ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ)
+               ath9k_init_band_txpower(sc, IEEE80211_BAND_2GHZ);
+       if (ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ)
+               ath9k_init_band_txpower(sc, IEEE80211_BAND_5GHZ);
+       ah->curchan = curchan;
+ }
  void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
  {
        struct ath_common *common = ath9k_hw_common(sc->sc_ah);
@@@ -706,6 -693,7 +696,7 @@@ int ath9k_init_device(u16 devid, struc
                    const struct ath_bus_ops *bus_ops)
  {
        struct ieee80211_hw *hw = sc->hw;
+       struct ath_wiphy *aphy = hw->priv;
        struct ath_common *common;
        struct ath_hw *ah;
        int error = 0;
        if (error != 0)
                goto error_rx;
  
+       ath9k_init_txpower_limits(sc);
        /* Register with mac80211 */
        error = ieee80211_register_hw(hw);
        if (error)
        INIT_WORK(&sc->chan_work, ath9k_wiphy_chan_work);
        INIT_DELAYED_WORK(&sc->wiphy_work, ath9k_wiphy_work);
        sc->wiphy_scheduler_int = msecs_to_jiffies(500);
+       aphy->last_rssi = ATH_RSSI_DUMMY_MARKER;
  
        ath_init_leds(sc);
        ath_start_rfkill_poll(sc);
  
 +      pm_qos_add_request(&ath9k_pm_qos_req, PM_QOS_CPU_DMA_LATENCY,
 +                         PM_QOS_DEFAULT_VALUE);
 +
        return 0;
  
  error_world:
@@@ -817,8 -805,6 +811,8 @@@ void ath9k_deinit_device(struct ath_sof
  
        ath9k_ps_wakeup(sc);
  
 +      pm_qos_remove_request(&ath9k_pm_qos_req);
 +
        wiphy_rfkill_stop_polling(sc->hw->wiphy);
        ath_deinit_leds(sc);
  
index 25d3ef4c338e1eb45800b45fec112fc064c095af,df7c62d9bec40fd995c6df0b6b1920eb18604737..f8c811af312d415cebb8fc0da0d058fb854bef25
@@@ -15,7 -15,6 +15,7 @@@
   */
  
  #include <linux/nl80211.h>
 +#include <linux/pm_qos_params.h>
  #include "ath9k.h"
  #include "btcoex.h"
  
@@@ -24,7 -23,7 +24,7 @@@ static void ath_update_txpow(struct ath
        struct ath_hw *ah = sc->sc_ah;
  
        if (sc->curtxpow != sc->config.txpowlimit) {
-               ath9k_hw_set_txpowerlimit(ah, sc->config.txpowlimit);
+               ath9k_hw_set_txpowerlimit(ah, sc->config.txpowlimit, false);
                /* read back in case value is clamped */
                sc->curtxpow = ath9k_hw_regulatory(ah)->power_limit;
        }
@@@ -94,13 -93,11 +94,13 @@@ void ath9k_ps_wakeup(struct ath_softc *
  {
        struct ath_common *common = ath9k_hw_common(sc->sc_ah);
        unsigned long flags;
 +      enum ath9k_power_mode power_mode;
  
        spin_lock_irqsave(&sc->sc_pm_lock, flags);
        if (++sc->ps_usecount != 1)
                goto unlock;
  
 +      power_mode = sc->sc_ah->power_mode;
        ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_AWAKE);
  
        /*
         * useful data. Better clear them now so that they don't mess up
         * survey data results.
         */
 -      spin_lock(&common->cc_lock);
 -      ath_hw_cycle_counters_update(common);
 -      memset(&common->cc_survey, 0, sizeof(common->cc_survey));
 -      spin_unlock(&common->cc_lock);
 +      if (power_mode != ATH9K_PM_AWAKE) {
 +              spin_lock(&common->cc_lock);
 +              ath_hw_cycle_counters_update(common);
 +              memset(&common->cc_survey, 0, sizeof(common->cc_survey));
 +              spin_unlock(&common->cc_lock);
 +      }
  
   unlock:
        spin_unlock_irqrestore(&sc->sc_pm_lock, flags);
@@@ -235,6 -230,8 +235,8 @@@ int ath_set_channel(struct ath_softc *s
  
        ath9k_ps_wakeup(sc);
  
+       spin_lock_bh(&sc->sc_pcu_lock);
        /*
         * This is only performed if the channel settings have
         * actually changed.
         * hardware at the new frequency, and then re-enable
         * the relevant bits of the h/w.
         */
-       ath9k_hw_set_interrupts(ah, 0);
+       ath9k_hw_disable_interrupts(ah);
        ath_drain_all_txq(sc, false);
  
-       spin_lock_bh(&sc->rx.pcu_lock);
        stopped = ath_stoprecv(sc);
  
        /* XXX: do not flush receive queue here. We don't want
                  channel->center_freq, conf_is_ht40(conf),
                  fastcc);
  
-       spin_lock_bh(&sc->sc_resetlock);
        r = ath9k_hw_reset(ah, hchan, caldata, fastcc);
        if (r) {
                ath_print(common, ATH_DBG_FATAL,
                          "Unable to reset channel (%u MHz), "
                          "reset status %d\n",
                          channel->center_freq, r);
-               spin_unlock_bh(&sc->sc_resetlock);
-               spin_unlock_bh(&sc->rx.pcu_lock);
                goto ps_restore;
        }
-       spin_unlock_bh(&sc->sc_resetlock);
  
        if (ath_startrecv(sc) != 0) {
                ath_print(common, ATH_DBG_FATAL,
                          "Unable to restart recv logic\n");
                r = -EIO;
-               spin_unlock_bh(&sc->rx.pcu_lock);
                goto ps_restore;
        }
  
-       spin_unlock_bh(&sc->rx.pcu_lock);
        ath_update_txpow(sc);
        ath9k_hw_set_interrupts(ah, ah->imask);
  
        }
  
   ps_restore:
+       spin_unlock_bh(&sc->sc_pcu_lock);
        ath9k_ps_restore(sc);
        return r;
  }
@@@ -341,7 -330,7 +335,7 @@@ void ath_paprd_calibrate(struct work_st
        struct ath_tx_control txctl;
        struct ath9k_hw_cal_data *caldata = ah->caldata;
        struct ath_common *common = ath9k_hw_common(ah);
-       int qnum, ftype;
+       int ftype;
        int chain_ok = 0;
        int chain;
        int len = 1800;
        memcpy(hdr->addr3, hw->wiphy->perm_addr, ETH_ALEN);
  
        memset(&txctl, 0, sizeof(txctl));
-       qnum = sc->tx.hwq_map[WME_AC_BE];
-       txctl.txq = &sc->tx.txq[qnum];
+       txctl.txq = sc->tx.txq_map[WME_AC_BE];
  
        ath9k_ps_wakeup(sc);
        ar9003_paprd_init_table(ah);
@@@ -567,7 -555,6 +560,6 @@@ static void ath_node_attach(struct ath_
                an->maxampdu = 1 << (IEEE80211_HT_MAX_AMPDU_FACTOR +
                                     sta->ht_cap.ampdu_factor);
                an->mpdudensity = parse_mpdudensity(sta->ht_cap.ampdu_density);
-               an->last_rssi = ATH_RSSI_DUMMY_MARKER;
        }
  }
  
@@@ -615,6 -602,8 +607,8 @@@ void ath9k_tasklet(unsigned long data
                return;
        }
  
+       spin_lock_bh(&sc->sc_pcu_lock);
        if (!ath9k_hw_check_alive(ah))
                ieee80211_queue_work(sc->hw, &sc->hw_check_work);
  
                rxmask = (ATH9K_INT_RX | ATH9K_INT_RXEOL | ATH9K_INT_RXORN);
  
        if (status & rxmask) {
-               spin_lock_bh(&sc->rx.pcu_lock);
                /* Check for high priority Rx first */
                if ((ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) &&
                    (status & ATH9K_INT_RXHP))
                        ath_rx_tasklet(sc, 0, true);
  
                ath_rx_tasklet(sc, 0, false);
-               spin_unlock_bh(&sc->rx.pcu_lock);
        }
  
        if (status & ATH9K_INT_TX) {
                        ath_gen_timer_isr(sc->sc_ah);
  
        /* re-enable hardware interrupt */
-       ath9k_hw_set_interrupts(ah, ah->imask);
+       ath9k_hw_enable_interrupts(ah);
+       spin_unlock_bh(&sc->sc_pcu_lock);
        ath9k_ps_restore(sc);
  }
  
@@@ -757,7 -745,7 +750,7 @@@ irqreturn_t ath_isr(int irq, void *dev
                 * interrupt; otherwise it will continue to
                 * fire.
                 */
-               ath9k_hw_set_interrupts(ah, 0);
+               ath9k_hw_disable_interrupts(ah);
                /*
                 * Let the hal handle the event. We assume
                 * it will clear whatever condition caused
                spin_lock(&common->cc_lock);
                ath9k_hw_proc_mib_event(ah);
                spin_unlock(&common->cc_lock);
-               ath9k_hw_set_interrupts(ah, ah->imask);
+               ath9k_hw_enable_interrupts(ah);
        }
  
        if (!(ah->caps.hw_caps & ATH9K_HW_CAP_AUTOSLEEP))
@@@ -783,8 -771,8 +776,8 @@@ chip_reset
        ath_debug_stat_interrupt(sc, status);
  
        if (sched) {
-               /* turn off every interrupt except SWBA */
-               ath9k_hw_set_interrupts(ah, (ah->imask & ATH9K_INT_SWBA));
+               /* turn off every interrupt */
+               ath9k_hw_disable_interrupts(ah);
                tasklet_schedule(&sc->intr_tq);
        }
  
@@@ -836,9 -824,11 +829,11 @@@ static u32 ath_get_extchanmode(struct a
  }
  
  static void ath9k_bss_assoc_info(struct ath_softc *sc,
+                                struct ieee80211_hw *hw,
                                 struct ieee80211_vif *vif,
                                 struct ieee80211_bss_conf *bss_conf)
  {
+       struct ath_wiphy *aphy = hw->priv;
        struct ath_hw *ah = sc->sc_ah;
        struct ath_common *common = ath9k_hw_common(ah);
  
                ath_beacon_config(sc, vif);
  
                /* Reset rssi stats */
+               aphy->last_rssi = ATH_RSSI_DUMMY_MARKER;
                sc->sc_ah->stats.avgbrssi = ATH_RSSI_DUMMY_MARKER;
  
                sc->sc_flags |= SC_OP_ANI_RUN;
@@@ -883,13 -874,13 +879,13 @@@ void ath_radio_enable(struct ath_softc 
        int r;
  
        ath9k_ps_wakeup(sc);
+       spin_lock_bh(&sc->sc_pcu_lock);
        ath9k_hw_configpcipowersave(ah, 0, 0);
  
        if (!ah->curchan)
                ah->curchan = ath_get_curchannel(sc, sc->hw);
  
-       spin_lock_bh(&sc->rx.pcu_lock);
-       spin_lock_bh(&sc->sc_resetlock);
        r = ath9k_hw_reset(ah, ah->curchan, ah->caldata, false);
        if (r) {
                ath_print(common, ATH_DBG_FATAL,
                          "reset status %d\n",
                          channel->center_freq, r);
        }
-       spin_unlock_bh(&sc->sc_resetlock);
  
        ath_update_txpow(sc);
        if (ath_startrecv(sc) != 0) {
                ath_print(common, ATH_DBG_FATAL,
                          "Unable to restart recv logic\n");
-               spin_unlock_bh(&sc->rx.pcu_lock);
+               spin_unlock_bh(&sc->sc_pcu_lock);
                return;
        }
-       spin_unlock_bh(&sc->rx.pcu_lock);
        if (sc->sc_flags & SC_OP_BEACONS)
                ath_beacon_config(sc, NULL);    /* restart beacons */
  
        ath9k_hw_set_gpio(ah, ah->led_pin, 0);
  
        ieee80211_wake_queues(hw);
+       spin_unlock_bh(&sc->sc_pcu_lock);
        ath9k_ps_restore(sc);
  }
  
@@@ -930,6 -920,8 +925,8 @@@ void ath_radio_disable(struct ath_soft
        int r;
  
        ath9k_ps_wakeup(sc);
+       spin_lock_bh(&sc->sc_pcu_lock);
        ieee80211_stop_queues(hw);
  
        /*
        }
  
        /* Disable interrupts */
-       ath9k_hw_set_interrupts(ah, 0);
+       ath9k_hw_disable_interrupts(ah);
  
        ath_drain_all_txq(sc, false);   /* clear pending tx frames */
  
-       spin_lock_bh(&sc->rx.pcu_lock);
        ath_stoprecv(sc);               /* turn off frame recv */
        ath_flushrecv(sc);              /* flush recv queue */
  
        if (!ah->curchan)
                ah->curchan = ath_get_curchannel(sc, hw);
  
-       spin_lock_bh(&sc->sc_resetlock);
        r = ath9k_hw_reset(ah, ah->curchan, ah->caldata, false);
        if (r) {
                ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_FATAL,
                          "reset status %d\n",
                          channel->center_freq, r);
        }
-       spin_unlock_bh(&sc->sc_resetlock);
  
        ath9k_hw_phy_disable(ah);
  
-       spin_unlock_bh(&sc->rx.pcu_lock);
        ath9k_hw_configpcipowersave(ah, 1, 1);
+       spin_unlock_bh(&sc->sc_pcu_lock);
        ath9k_ps_restore(sc);
        ath9k_setpower(sc, ATH9K_PM_FULL_SLEEP);
  }
  
@@@ -983,29 -972,25 +977,25 @@@ int ath_reset(struct ath_softc *sc, boo
        /* Stop ANI */
        del_timer_sync(&common->ani.timer);
  
+       spin_lock_bh(&sc->sc_pcu_lock);
        ieee80211_stop_queues(hw);
  
-       ath9k_hw_set_interrupts(ah, 0);
+       ath9k_hw_disable_interrupts(ah);
        ath_drain_all_txq(sc, retry_tx);
  
-       spin_lock_bh(&sc->rx.pcu_lock);
        ath_stoprecv(sc);
        ath_flushrecv(sc);
  
-       spin_lock_bh(&sc->sc_resetlock);
        r = ath9k_hw_reset(ah, sc->sc_ah->curchan, ah->caldata, false);
        if (r)
                ath_print(common, ATH_DBG_FATAL,
                          "Unable to reset hardware; reset status %d\n", r);
-       spin_unlock_bh(&sc->sc_resetlock);
  
        if (ath_startrecv(sc) != 0)
                ath_print(common, ATH_DBG_FATAL,
                          "Unable to start recv logic\n");
  
-       spin_unlock_bh(&sc->rx.pcu_lock);
        /*
         * We may be doing a reset in response to a request
         * that changes the channel so update any state that
        }
  
        ieee80211_wake_queues(hw);
+       spin_unlock_bh(&sc->sc_pcu_lock);
  
        /* Start ANI */
        ath_start_ani(common);
        return r;
  }
  
- static int ath_get_hal_qnum(u16 queue, struct ath_softc *sc)
- {
-       int qnum;
-       switch (queue) {
-       case 0:
-               qnum = sc->tx.hwq_map[WME_AC_VO];
-               break;
-       case 1:
-               qnum = sc->tx.hwq_map[WME_AC_VI];
-               break;
-       case 2:
-               qnum = sc->tx.hwq_map[WME_AC_BE];
-               break;
-       case 3:
-               qnum = sc->tx.hwq_map[WME_AC_BK];
-               break;
-       default:
-               qnum = sc->tx.hwq_map[WME_AC_BE];
-               break;
-       }
-       return qnum;
- }
- int ath_get_mac80211_qnum(u32 queue, struct ath_softc *sc)
- {
-       int qnum;
-       switch (queue) {
-       case WME_AC_VO:
-               qnum = 0;
-               break;
-       case WME_AC_VI:
-               qnum = 1;
-               break;
-       case WME_AC_BE:
-               qnum = 2;
-               break;
-       case WME_AC_BK:
-               qnum = 3;
-               break;
-       default:
-               qnum = -1;
-               break;
-       }
-       return qnum;
- }
  /* XXX: Remove me once we don't depend on ath9k_channel for all
   * this redundant data */
  void ath9k_update_ichannel(struct ath_softc *sc, struct ieee80211_hw *hw,
@@@ -1168,19 -1104,16 +1109,16 @@@ static int ath9k_start(struct ieee80211
         * be followed by initialization of the appropriate bits
         * and then setup of the interrupt mask.
         */
-       spin_lock_bh(&sc->rx.pcu_lock);
-       spin_lock_bh(&sc->sc_resetlock);
+       spin_lock_bh(&sc->sc_pcu_lock);
        r = ath9k_hw_reset(ah, init_channel, ah->caldata, false);
        if (r) {
                ath_print(common, ATH_DBG_FATAL,
                          "Unable to reset hardware; reset status %d "
                          "(freq %u MHz)\n", r,
                          curchan->center_freq);
-               spin_unlock_bh(&sc->sc_resetlock);
-               spin_unlock_bh(&sc->rx.pcu_lock);
+               spin_unlock_bh(&sc->sc_pcu_lock);
                goto mutex_unlock;
        }
-       spin_unlock_bh(&sc->sc_resetlock);
  
        /*
         * This is needed only to setup initial state
                ath_print(common, ATH_DBG_FATAL,
                          "Unable to start recv logic\n");
                r = -EIO;
-               spin_unlock_bh(&sc->rx.pcu_lock);
+               spin_unlock_bh(&sc->sc_pcu_lock);
                goto mutex_unlock;
        }
-       spin_unlock_bh(&sc->rx.pcu_lock);
+       spin_unlock_bh(&sc->sc_pcu_lock);
  
        /* Setup our intr mask. */
        ah->imask = ATH9K_INT_TX | ATH9K_INT_RXEOL |
                ah->imask |= ATH9K_INT_CST;
  
        sc->sc_flags &= ~SC_OP_INVALID;
 +      sc->sc_ah->is_monitoring = false;
  
        /* Disable BMISS interrupt when we're not associated */
        ah->imask &= ~(ATH9K_INT_SWBA | ATH9K_INT_BMISS);
                        ath9k_btcoex_timer_resume(sc);
        }
  
 +      pm_qos_update_request(&ath9k_pm_qos_req, 55);
 +
  mutex_unlock:
        mutex_unlock(&sc->mutex);
  
@@@ -1262,7 -1192,6 +1200,6 @@@ static int ath9k_tx(struct ieee80211_h
        struct ath_tx_control txctl;
        int padpos, padsize;
        struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
-       int qnum;
  
        if (aphy->state != ATH_WIPHY_ACTIVE && aphy->state != ATH_WIPHY_SCAN) {
                ath_print(common, ATH_DBG_XMIT,
                memmove(skb->data, skb->data + padsize, padpos);
        }
  
-       qnum = ath_get_hal_qnum(skb_get_queue_mapping(skb), sc);
-       txctl.txq = &sc->tx.txq[qnum];
+       txctl.txq = sc->tx.txq_map[skb_get_queue_mapping(skb)];
  
        ath_print(common, ATH_DBG_XMIT, "transmitting packet, skb: %p\n", skb);
  
@@@ -1400,22 -1328,25 +1336,25 @@@ static void ath9k_stop(struct ieee80211
                        ath9k_btcoex_timer_pause(sc);
        }
  
+       spin_lock_bh(&sc->sc_pcu_lock);
        /* make sure h/w will not generate any interrupt
         * before setting the invalid flag. */
-       ath9k_hw_set_interrupts(ah, 0);
+       ath9k_hw_disable_interrupts(ah);
  
-       spin_lock_bh(&sc->rx.pcu_lock);
        if (!(sc->sc_flags & SC_OP_INVALID)) {
                ath_drain_all_txq(sc, false);
                ath_stoprecv(sc);
                ath9k_hw_phy_disable(ah);
        } else
                sc->rx.rxlink = NULL;
-       spin_unlock_bh(&sc->rx.pcu_lock);
  
        /* disable HAL and put h/w to sleep */
        ath9k_hw_disable(ah);
        ath9k_hw_configpcipowersave(ah, 1, 1);
+       spin_unlock_bh(&sc->sc_pcu_lock);
        ath9k_ps_restore(sc);
  
        /* Finally, put the chip in FULL SLEEP mode */
  
        sc->sc_flags |= SC_OP_INVALID;
  
 +      pm_qos_update_request(&ath9k_pm_qos_req, PM_QOS_DEFAULT_VALUE);
 +
        mutex_unlock(&sc->mutex);
  
        ath_print(common, ATH_DBG_CONFIG, "Driver halt\n");
@@@ -1503,7 -1432,8 +1442,7 @@@ static int ath9k_add_interface(struct i
        ath9k_hw_set_interrupts(ah, ah->imask);
  
        if (vif->type == NL80211_IFTYPE_AP    ||
 -          vif->type == NL80211_IFTYPE_ADHOC ||
 -          vif->type == NL80211_IFTYPE_MONITOR) {
 +          vif->type == NL80211_IFTYPE_ADHOC) {
                sc->sc_flags |= SC_OP_ANI_RUN;
                ath_start_ani(common);
        }
@@@ -1653,12 -1583,8 +1592,12 @@@ static int ath9k_config(struct ieee8021
        if (changed & IEEE80211_CONF_CHANGE_MONITOR) {
                if (conf->flags & IEEE80211_CONF_MONITOR) {
                        ath_print(common, ATH_DBG_CONFIG,
 -                                "HW opmode set to Monitor mode\n");
 -                      sc->sc_ah->opmode = NL80211_IFTYPE_MONITOR;
 +                                "Monitor mode is enabled\n");
 +                      sc->sc_ah->is_monitoring = true;
 +              } else {
 +                      ath_print(common, ATH_DBG_CONFIG,
 +                                "Monitor mode is disabled\n");
 +                      sc->sc_ah->is_monitoring = false;
                }
        }
  
@@@ -1822,12 -1748,15 +1761,15 @@@ static int ath9k_conf_tx(struct ieee802
        struct ath_wiphy *aphy = hw->priv;
        struct ath_softc *sc = aphy->sc;
        struct ath_common *common = ath9k_hw_common(sc->sc_ah);
+       struct ath_txq *txq;
        struct ath9k_tx_queue_info qi;
-       int ret = 0, qnum;
+       int ret = 0;
  
        if (queue >= WME_NUM_AC)
                return 0;
  
+       txq = sc->tx.txq_map[queue];
        mutex_lock(&sc->mutex);
  
        memset(&qi, 0, sizeof(struct ath9k_tx_queue_info));
        qi.tqi_cwmin = params->cw_min;
        qi.tqi_cwmax = params->cw_max;
        qi.tqi_burstTime = params->txop;
-       qnum = ath_get_hal_qnum(queue, sc);
  
        ath_print(common, ATH_DBG_CONFIG,
                  "Configure tx [queue/halq] [%d/%d],  "
                  "aifs: %d, cw_min: %d, cw_max: %d, txop: %d\n",
-                 queue, qnum, params->aifs, params->cw_min,
+                 queue, txq->axq_qnum, params->aifs, params->cw_min,
                  params->cw_max, params->txop);
  
-       ret = ath_txq_update(sc, qnum, &qi);
+       ret = ath_txq_update(sc, txq->axq_qnum, &qi);
        if (ret)
                ath_print(common, ATH_DBG_FATAL, "TXQ Update failed\n");
  
        if (sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC)
-               if ((qnum == sc->tx.hwq_map[WME_AC_BE]) && !ret)
+               if (queue == WME_AC_BE && !ret)
                        ath_beaconq_config(sc);
  
        mutex_unlock(&sc->mutex);
@@@ -2011,7 -1939,7 +1952,7 @@@ static void ath9k_bss_info_changed(stru
        if (changed & BSS_CHANGED_ASSOC) {
                ath_print(common, ATH_DBG_CONFIG, "BSS Changed ASSOC %d\n",
                        bss_conf->assoc);
-               ath9k_bss_assoc_info(sc, vif, bss_conf);
+               ath9k_bss_assoc_info(sc, hw, vif, bss_conf);
        }
  
        mutex_unlock(&sc->mutex);
index c76ea53c20ce7dbe41863c00930853a59ccc6cf8,60300b225b6d693604744cbbc769da71ecf76f71..c5c80764a94a4f1a6b8e67a9b78e16fcb1ff303d
@@@ -317,7 -317,7 +317,7 @@@ int ath_rx_init(struct ath_softc *sc, i
        struct ath_buf *bf;
        int error = 0;
  
-       spin_lock_init(&sc->rx.pcu_lock);
+       spin_lock_init(&sc->sc_pcu_lock);
        sc->sc_flags &= ~SC_OP_RXFLUSH;
        spin_lock_init(&sc->rx.rxbuflock);
  
@@@ -441,7 -441,7 +441,7 @@@ u32 ath_calcrxfilter(struct ath_softc *
         */
        if (((sc->sc_ah->opmode != NL80211_IFTYPE_AP) &&
             (sc->rx.rxfilter & FIF_PROMISC_IN_BSS)) ||
 -          (sc->sc_ah->opmode == NL80211_IFTYPE_MONITOR))
 +          (sc->sc_ah->is_monitoring))
                rfilt |= ATH9K_RX_FILTER_PROM;
  
        if (sc->rx.rxfilter & FIF_CONTROL)
@@@ -528,6 -528,8 +528,8 @@@ bool ath_stoprecv(struct ath_softc *sc
                sc->rx.rxlink = NULL;
        spin_unlock_bh(&sc->rx.rxbuflock);
  
+       ATH_DBG_WARN(!stopped, "Could not stop RX, we could be "
+                    "confusing the DMA engine when we start RX up\n");
        return stopped;
  }
  
@@@ -897,7 -899,7 +899,7 @@@ static bool ath9k_rx_accept(struct ath_
                 * decryption and MIC failures. For monitor mode,
                 * we also ignore the CRC error.
                 */
 -              if (ah->opmode == NL80211_IFTYPE_MONITOR) {
 +              if (ah->is_monitoring) {
                        if (rx_stats->rs_status &
                            ~(ATH9K_RXERR_DECRYPT | ATH9K_RXERR_MIC |
                              ATH9K_RXERR_CRC))
@@@ -962,36 -964,23 +964,23 @@@ static void ath9k_process_rssi(struct a
                               struct ieee80211_hdr *hdr,
                               struct ath_rx_status *rx_stats)
  {
+       struct ath_wiphy *aphy = hw->priv;
        struct ath_hw *ah = common->ah;
-       struct ieee80211_sta *sta;
-       struct ath_node *an;
-       int last_rssi = ATH_RSSI_DUMMY_MARKER;
+       int last_rssi;
        __le16 fc;
  
+       if (ah->opmode != NL80211_IFTYPE_STATION)
+               return;
        fc = hdr->frame_control;
+       if (!ieee80211_is_beacon(fc) ||
+           compare_ether_addr(hdr->addr3, common->curbssid))
+               return;
  
-       rcu_read_lock();
-       /*
-        * XXX: use ieee80211_find_sta! This requires quite a bit of work
-        * under the current ath9k virtual wiphy implementation as we have
-        * no way of tying a vif to wiphy. Typically vifs are attached to
-        * at least one sdata of a wiphy on mac80211 but with ath9k virtual
-        * wiphy you'd have to iterate over every wiphy and each sdata.
-        */
-       if (is_multicast_ether_addr(hdr->addr1))
-               sta = ieee80211_find_sta_by_ifaddr(hw, hdr->addr2, NULL);
-       else
-               sta = ieee80211_find_sta_by_ifaddr(hw, hdr->addr2, hdr->addr1);
-       if (sta) {
-               an = (struct ath_node *) sta->drv_priv;
-               if (rx_stats->rs_rssi != ATH9K_RSSI_BAD &&
-                  !rx_stats->rs_moreaggr)
-                       ATH_RSSI_LPF(an->last_rssi, rx_stats->rs_rssi);
-               last_rssi = an->last_rssi;
-       }
-       rcu_read_unlock();
+       if (rx_stats->rs_rssi != ATH9K_RSSI_BAD && !rx_stats->rs_moreaggr)
+               ATH_RSSI_LPF(aphy->last_rssi, rx_stats->rs_rssi);
  
+       last_rssi = aphy->last_rssi;
        if (likely(last_rssi != ATH_RSSI_DUMMY_MARKER))
                rx_stats->rs_rssi = ATH_EP_RND(last_rssi,
                                              ATH_RSSI_EP_MULTIPLIER);
                rx_stats->rs_rssi = 0;
  
        /* Update Beacon RSSI, this is used by ANI. */
-       if (ieee80211_is_beacon(fc))
-               ah->stats.avgbrssi = rx_stats->rs_rssi;
+       ah->stats.avgbrssi = rx_stats->rs_rssi;
  }
  
  /*
index 3317039cd28fe5ae6b1e38ff0029bf345fd78d50,ddf5373ee689cff0f166cfffd8c744a4cf61dff4..82c5f1c5065096f3807392d3ab07fa64321ad4a8
@@@ -82,11 -82,9 +82,11 @@@ static struct usb_device_id carl9170_us
        { USB_DEVICE(0x07d1, 0x3c10) },
        /* D-Link DWA 160 A2 */
        { USB_DEVICE(0x07d1, 0x3a09) },
 +      /* D-Link DWA 130 D */
 +      { USB_DEVICE(0x07d1, 0x3a0f) },
        /* Netgear WNA1000 */
        { USB_DEVICE(0x0846, 0x9040) },
 -      /* Netgear WNDA3100 */
 +      /* Netgear WNDA3100 (v1) */
        { USB_DEVICE(0x0846, 0x9010) },
        /* Netgear WN111 v2 */
        { USB_DEVICE(0x0846, 0x9001), .driver_info = CARL9170_ONE_LED },
@@@ -433,7 -431,7 +433,7 @@@ static void carl9170_usb_rx_complete(st
                         * device.
                         */
  
-                       carl9170_restart(ar, CARL9170_RR_SLOW_SYSTEM);
+                       ieee80211_queue_work(ar->hw, &ar->ping_work);
                }
        } else {
                /*
index 7edf8c2fb8c7c6072294854281ba40f416f1423a,a55b4623e1c8066e86cc100663a551b89843b4f6..931c546367ea1901104dc4f2ced1ae57eb4c083c
@@@ -61,6 -61,7 +61,7 @@@
  #include "iwl-helpers.h"
  #include "iwl-dev.h"
  #include "iwl-spectrum.h"
+ #include "iwl-legacy.h"
  
  /*
   * module name, copyright, version, etc.
@@@ -3057,22 -3058,22 +3058,22 @@@ static void iwl3945_bg_rx_replenish(str
        mutex_unlock(&priv->mutex);
  }
  
- void iwl3945_post_associate(struct iwl_priv *priv, struct ieee80211_vif *vif)
+ void iwl3945_post_associate(struct iwl_priv *priv)
  {
        int rc = 0;
        struct ieee80211_conf *conf = NULL;
        struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
  
-       if (!vif || !priv->is_open)
+       if (!ctx->vif || !priv->is_open)
                return;
  
-       if (vif->type == NL80211_IFTYPE_AP) {
+       if (ctx->vif->type == NL80211_IFTYPE_AP) {
                IWL_ERR(priv, "%s Should not be called in AP mode\n", __func__);
                return;
        }
  
        IWL_DEBUG_ASSOC(priv, "Associated as %d to: %pM\n",
-                       vif->bss_conf.aid, ctx->active.bssid_addr);
+                       ctx->vif->bss_conf.aid, ctx->active.bssid_addr);
  
        if (test_bit(STATUS_EXIT_PENDING, &priv->status))
                return;
  
        ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK;
  
-       ctx->staging.assoc_id = cpu_to_le16(vif->bss_conf.aid);
+       ctx->staging.assoc_id = cpu_to_le16(ctx->vif->bss_conf.aid);
  
        IWL_DEBUG_ASSOC(priv, "assoc id %d beacon interval %d\n",
-                       vif->bss_conf.aid, vif->bss_conf.beacon_int);
+                       ctx->vif->bss_conf.aid, ctx->vif->bss_conf.beacon_int);
  
-       if (vif->bss_conf.use_short_preamble)
+       if (ctx->vif->bss_conf.use_short_preamble)
                ctx->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
        else
                ctx->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK;
  
        if (ctx->staging.flags & RXON_FLG_BAND_24G_MSK) {
-               if (vif->bss_conf.use_short_slot)
+               if (ctx->vif->bss_conf.use_short_slot)
                        ctx->staging.flags |= RXON_FLG_SHORT_SLOT_MSK;
                else
                        ctx->staging.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
  
        iwl3945_commit_rxon(priv, ctx);
  
-       switch (vif->type) {
+       switch (ctx->vif->type) {
        case NL80211_IFTYPE_STATION:
                iwl3945_rate_scale_init(priv->hw, IWL_AP_ID);
                break;
                break;
        default:
                IWL_ERR(priv, "%s Should not be called in %d mode\n",
-                       __func__, vif->type);
+                       __func__, ctx->vif->type);
                break;
        }
  }
@@@ -3234,9 -3235,10 +3235,10 @@@ static int iwl3945_mac_tx(struct ieee80
        return NETDEV_TX_OK;
  }
  
- void iwl3945_config_ap(struct iwl_priv *priv, struct ieee80211_vif *vif)
+ void iwl3945_config_ap(struct iwl_priv *priv)
  {
        struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
+       struct ieee80211_vif *vif = ctx->vif;
        int rc = 0;
  
        if (test_bit(STATUS_EXIT_PENDING, &priv->status))
@@@ -3407,9 -3409,9 +3409,9 @@@ static void iwl3945_configure_filter(st
        ctx->staging.filter_flags |= filter_or;
  
        /*
-        * Committing directly here breaks for some reason,
-        * but we'll eventually commit the filter flags
-        * change anyway.
+        * Not committing directly because hardware can perform a scan,
+        * but even if hw is ready, committing here breaks for some reason,
+        * we'll eventually commit the filter flags change anyway.
         */
  
        mutex_unlock(&priv->mutex);
@@@ -3824,18 -3826,19 +3826,19 @@@ static struct attribute_group iwl3945_a
        .attrs = iwl3945_sysfs_entries,
  };
  
- static struct ieee80211_ops iwl3945_hw_ops = {
+ struct ieee80211_ops iwl3945_hw_ops = {
        .tx = iwl3945_mac_tx,
        .start = iwl3945_mac_start,
        .stop = iwl3945_mac_stop,
        .add_interface = iwl_mac_add_interface,
        .remove_interface = iwl_mac_remove_interface,
-       .config = iwl_mac_config,
+       .change_interface = iwl_mac_change_interface,
+       .config = iwl_legacy_mac_config,
        .configure_filter = iwl3945_configure_filter,
        .set_key = iwl3945_mac_set_key,
        .conf_tx = iwl_mac_conf_tx,
-       .reset_tsf = iwl_mac_reset_tsf,
-       .bss_info_changed = iwl_bss_info_changed,
+       .reset_tsf = iwl_legacy_mac_reset_tsf,
+       .bss_info_changed = iwl_legacy_mac_bss_info_changed,
        .hw_scan = iwl_mac_hw_scan,
        .sta_add = iwl3945_mac_sta_add,
        .sta_remove = iwl_mac_sta_remove,
@@@ -3866,6 -3869,7 +3869,7 @@@ static int iwl3945_init_drv(struct iwl_
        priv->missed_beacon_threshold = IWL_MISSED_BEACON_THRESHOLD_DEF;
  
        priv->tx_power_user_lmt = IWL_DEFAULT_TX_POWER;
+       priv->tx_power_next = IWL_DEFAULT_TX_POWER;
  
        if (eeprom->version < EEPROM_3945_EEPROM_VERSION) {
                IWL_WARN(priv, "Unsupported EEPROM version: 0x%04X\n",
@@@ -3965,7 -3969,7 +3969,7 @@@ static int iwl3945_pci_probe(struct pci
  
        /* mac80211 allocates memory for this device instance, including
         *   space for this driver's private structure */
-       hw = iwl_alloc_all(cfg, &iwl3945_hw_ops);
+       hw = iwl_alloc_all(cfg);
        if (hw == NULL) {
                pr_err("Can not allocate network device\n");
                err = -ENOMEM;
         * "the hard way", rather than using device's scan.
         */
        if (iwl3945_mod_params.disable_hw_scan) {
 -              IWL_ERR(priv, "sw scan support is deprecated\n");
 +              dev_printk(KERN_DEBUG, &(pdev->dev),
 +                      "sw scan support is deprecated\n");
                iwl3945_hw_ops.hw_scan = NULL;
        }
  
  
        pci_enable_msi(priv->pci_dev);
  
-       err = request_irq(priv->pci_dev->irq, priv->cfg->ops->lib->isr,
+       err = request_irq(priv->pci_dev->irq, priv->cfg->ops->lib->isr_ops.isr,
                          IRQF_SHARED, DRV_NAME, priv);
        if (err) {
                IWL_ERR(priv, "Error allocating IRQ %d\n", priv->pci_dev->irq);
@@@ -4275,10 -4278,7 +4279,7 @@@ static struct pci_driver iwl3945_drive
        .id_table = iwl3945_hw_card_ids,
        .probe = iwl3945_pci_probe,
        .remove = __devexit_p(iwl3945_pci_remove),
- #ifdef CONFIG_PM
-       .suspend = iwl_pci_suspend,
-       .resume = iwl_pci_resume,
- #endif
+       .driver.pm = IWL_PM_OPS,
  };
  
  static int __init iwl3945_init(void)