Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/btrfs...
[pandora-kernel.git] / drivers / net / wireless / ath / ath9k / init.c
index 79aec98..45c585a 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008-2009 Atheros Communications Inc.
+ * Copyright (c) 2008-2011 Atheros Communications Inc.
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -15,6 +15,7 @@
  */
 
 #include <linux/slab.h>
+#include <linux/ath9k_platform.h>
 
 #include "ath9k.h"
 
@@ -195,10 +196,27 @@ static unsigned int ath9k_ioread32(void *hw_priv, u32 reg_offset)
        return val;
 }
 
-static const struct ath_ops ath9k_common_ops = {
-       .read = ath9k_ioread32,
-       .write = ath9k_iowrite32,
-};
+static unsigned int ath9k_reg_rmw(void *hw_priv, u32 reg_offset, u32 set, u32 clr)
+{
+       struct ath_hw *ah = (struct ath_hw *) hw_priv;
+       struct ath_common *common = ath9k_hw_common(ah);
+       struct ath_softc *sc = (struct ath_softc *) common->priv;
+       unsigned long uninitialized_var(flags);
+       u32 val;
+
+       if (ah->config.serialize_regmode == SER_REG_MODE_ON)
+               spin_lock_irqsave(&sc->sc_serial_rw, flags);
+
+       val = ioread32(sc->mem + reg_offset);
+       val &= ~clr;
+       val |= set;
+       iowrite32(val, sc->mem + reg_offset);
+
+       if (ah->config.serialize_regmode == SER_REG_MODE_ON)
+               spin_unlock_irqrestore(&sc->sc_serial_rw, flags);
+
+       return val;
+}
 
 /**************************/
 /*     Initialization     */
@@ -389,13 +407,7 @@ void ath9k_init_crypto(struct ath_softc *sc)
        int i = 0;
 
        /* Get the hardware key cache size. */
-       common->keymax = sc->sc_ah->caps.keycache_size;
-       if (common->keymax > ATH_KEYMAX) {
-               ath_dbg(common, ATH_DBG_ANY,
-                       "Warning, using only %u entries in %u key cache\n",
-                       ATH_KEYMAX, common->keymax);
-               common->keymax = ATH_KEYMAX;
-       }
+       common->keymax = AR_KEYTABLE_SIZE;
 
        /*
         * Reset the key cache since some parts do not
@@ -537,6 +549,7 @@ static void ath9k_init_misc(struct ath_softc *sc)
 static int ath9k_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid,
                            const struct ath_bus_ops *bus_ops)
 {
+       struct ath9k_platform_data *pdata = sc->dev->platform_data;
        struct ath_hw *ah = NULL;
        struct ath_common *common;
        int ret = 0, i;
@@ -549,13 +562,23 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid,
        ah->hw = sc->hw;
        ah->hw_version.devid = devid;
        ah->hw_version.subsysid = subsysid;
+       ah->reg_ops.read = ath9k_ioread32;
+       ah->reg_ops.write = ath9k_iowrite32;
+       ah->reg_ops.rmw = ath9k_reg_rmw;
        sc->sc_ah = ah;
 
-       if (!sc->dev->platform_data)
+       if (!pdata) {
                ah->ah_flags |= AH_USE_EEPROM;
+               sc->sc_ah->led_pin = -1;
+       } else {
+               sc->sc_ah->gpio_mask = pdata->gpio_mask;
+               sc->sc_ah->gpio_val = pdata->gpio_val;
+               sc->sc_ah->led_pin = pdata->led_pin;
+               ah->is_clk_25mhz = pdata->is_clk_25mhz;
+       }
 
        common = ath9k_hw_common(ah);
-       common->ops = &ath9k_common_ops;
+       common->ops = &ah->reg_ops;
        common->bus_ops = bus_ops;
        common->ah = ah;
        common->hw = sc->hw;
@@ -587,6 +610,9 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid,
        if (ret)
                goto err_hw;
 
+       if (pdata && pdata->macaddr)
+               memcpy(common->macaddr, pdata->macaddr, ETH_ALEN);
+
        ret = ath9k_init_queues(sc);
        if (ret)
                goto err_queues;
@@ -679,6 +705,8 @@ void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
        if (AR_SREV_5416(sc->sc_ah))
                hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
 
+       hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
+
        hw->queues = 4;
        hw->max_rates = 4;
        hw->channel_change_time = 5000;
@@ -773,6 +801,7 @@ int ath9k_init_device(u16 devid, struct ath_softc *sc, u16 subsysid,
 
        INIT_WORK(&sc->hw_check_work, ath_hw_check);
        INIT_WORK(&sc->paprd_work, ath_paprd_calibrate);
+       INIT_DELAYED_WORK(&sc->hw_pll_work, ath_hw_pll_work);
        sc->last_rssi = ATH_RSSI_DUMMY_MARKER;
 
        ath_init_leds(sc);