Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wirel...
[safe/jmp/linux-2.6] / drivers / net / wireless / ath5k / base.c
index fa39f21..bd2c580 100644 (file)
@@ -239,6 +239,7 @@ static int ath5k_get_stats(struct ieee80211_hw *hw,
 static int ath5k_get_tx_stats(struct ieee80211_hw *hw,
                struct ieee80211_tx_queue_stats *stats);
 static u64 ath5k_get_tsf(struct ieee80211_hw *hw);
+static void ath5k_set_tsf(struct ieee80211_hw *hw, u64 tsf);
 static void ath5k_reset_tsf(struct ieee80211_hw *hw);
 static int ath5k_beacon_update(struct ath5k_softc *sc,
                struct sk_buff *skb);
@@ -261,6 +262,7 @@ static struct ieee80211_ops ath5k_hw_ops = {
        .conf_tx        = NULL,
        .get_tx_stats   = ath5k_get_tx_stats,
        .get_tsf        = ath5k_get_tsf,
+       .set_tsf        = ath5k_set_tsf,
        .reset_tsf      = ath5k_reset_tsf,
        .bss_info_changed = ath5k_bss_info_changed,
 };
@@ -1021,6 +1023,8 @@ ath5k_setup_bands(struct ieee80211_hw *hw)
  * it's done by reseting the chip.  To accomplish this we must
  * first cleanup any pending DMA, then restart stuff after a la
  * ath5k_init.
+ *
+ * Called with sc->lock.
  */
 static int
 ath5k_chan_set(struct ath5k_softc *sc, struct ieee80211_channel *chan)
@@ -2624,8 +2628,12 @@ ath5k_init_leds(struct ath5k_softc *sc)
                sc->led_pin = 1;
                sc->led_on = 1;  /* active high */
        }
-       /* Pin 3 on Foxconn chips used in Acer Aspire One (0x105b:e008) */
-       if (pdev->subsystem_vendor == PCI_VENDOR_ID_FOXCONN) {
+       /*
+        * Pin 3 on Foxconn chips used in Acer Aspire One (0x105b:e008) and
+        * in emachines notebooks with AMBIT subsystem.
+        */
+       if (pdev->subsystem_vendor == PCI_VENDOR_ID_FOXCONN ||
+           pdev->subsystem_vendor == PCI_VENDOR_ID_AMBIT) {
                __set_bit(ATH_STAT_LEDSOFT, sc->status);
                sc->led_pin = 3;
                sc->led_on = 0;  /* active low */
@@ -2849,11 +2857,17 @@ ath5k_config(struct ieee80211_hw *hw, u32 changed)
 {
        struct ath5k_softc *sc = hw->priv;
        struct ieee80211_conf *conf = &hw->conf;
+       int ret;
+
+       mutex_lock(&sc->lock);
 
        sc->bintval = conf->beacon_int;
        sc->power_level = conf->power_level;
 
-       return ath5k_chan_set(sc, conf->channel);
+       ret = ath5k_chan_set(sc, conf->channel);
+
+       mutex_unlock(&sc->lock);
+       return ret;
 }
 
 static int
@@ -3111,6 +3125,14 @@ ath5k_get_tsf(struct ieee80211_hw *hw)
 }
 
 static void
+ath5k_set_tsf(struct ieee80211_hw *hw, u64 tsf)
+{
+       struct ath5k_softc *sc = hw->priv;
+
+       ath5k_hw_set_tsf64(sc->ah, tsf);
+}
+
+static void
 ath5k_reset_tsf(struct ieee80211_hw *hw)
 {
        struct ath5k_softc *sc = hw->priv;