Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wirel...
[pandora-kernel.git] / drivers / net / wireless / ath / ath9k / init.c
index 14b8ab3..e5c1eea 100644 (file)
@@ -29,17 +29,27 @@ static unsigned int ath9k_debug = ATH_DBG_DEFAULT;
 module_param_named(debug, ath9k_debug, uint, 0);
 MODULE_PARM_DESC(debug, "Debugging mask");
 
-int modparam_nohwcrypt;
-module_param_named(nohwcrypt, modparam_nohwcrypt, int, 0444);
+int ath9k_modparam_nohwcrypt;
+module_param_named(nohwcrypt, ath9k_modparam_nohwcrypt, int, 0444);
 MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption");
 
 int led_blink;
 module_param_named(blink, led_blink, int, 0444);
 MODULE_PARM_DESC(blink, "Enable LED blink on activity");
 
+static int ath9k_btcoex_enable;
+module_param_named(btcoex_enable, ath9k_btcoex_enable, int, 0444);
+MODULE_PARM_DESC(btcoex_enable, "Enable wifi-BT coexistence");
+
+int ath9k_pm_qos_value = ATH9K_PM_QOS_DEFAULT_VALUE;
+module_param_named(pmqos, ath9k_pm_qos_value, int, S_IRUSR | S_IRGRP | S_IROTH);
+MODULE_PARM_DESC(pmqos, "User specified PM-QOS value");
+
+bool is_ath9k_unloaded;
 /* We use the hw_value as an index into our private channel structure */
 
 #define CHAN2G(_freq, _idx)  { \
+       .band = IEEE80211_BAND_2GHZ, \
        .center_freq = (_freq), \
        .hw_value = (_idx), \
        .max_power = 20, \
@@ -206,7 +216,9 @@ static void setup_ht_cap(struct ath_softc *sc,
        ht_info->ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
        ht_info->ampdu_density = IEEE80211_HT_MPDU_DENSITY_8;
 
-       if (AR_SREV_9300_20_OR_LATER(ah))
+       if (AR_SREV_9485(ah))
+               max_streams = 1;
+       else if (AR_SREV_9300_20_OR_LATER(ah))
                max_streams = 3;
        else
                max_streams = 2;
@@ -222,9 +234,9 @@ static void setup_ht_cap(struct ath_softc *sc,
        tx_streams = ath9k_cmn_count_streams(common->tx_chainmask, max_streams);
        rx_streams = ath9k_cmn_count_streams(common->rx_chainmask, max_streams);
 
-       ath_print(common, ATH_DBG_CONFIG,
-                 "TX streams %d, RX streams: %d\n",
-                 tx_streams, rx_streams);
+       ath_dbg(common, ATH_DBG_CONFIG,
+               "TX streams %d, RX streams: %d\n",
+               tx_streams, rx_streams);
 
        if (tx_streams != rx_streams) {
                ht_info->mcs.tx_params |= IEEE80211_HT_MCS_TX_RX_DIFF;
@@ -242,8 +254,7 @@ static int ath9k_reg_notifier(struct wiphy *wiphy,
                              struct regulatory_request *request)
 {
        struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
-       struct ath_wiphy *aphy = hw->priv;
-       struct ath_softc *sc = aphy->sc;
+       struct ath_softc *sc = hw->priv;
        struct ath_regulatory *reg = ath9k_hw_regulatory(sc->sc_ah);
 
        return ath_reg_notifier_apply(wiphy, request, reg);
@@ -267,8 +278,8 @@ int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd,
        struct ath_buf *bf;
        int i, bsize, error, desc_len;
 
-       ath_print(common, ATH_DBG_CONFIG, "%s DMA: %u buffers %u desc/buf\n",
-                 name, nbuf, ndesc);
+       ath_dbg(common, ATH_DBG_CONFIG, "%s DMA: %u buffers %u desc/buf\n",
+               name, nbuf, ndesc);
 
        INIT_LIST_HEAD(head);
 
@@ -279,8 +290,7 @@ int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd,
 
        /* ath_desc must be a multiple of DWORDs */
        if ((desc_len % 4) != 0) {
-               ath_print(common, ATH_DBG_FATAL,
-                         "ath_desc not DWORD aligned\n");
+               ath_err(common, "ath_desc not DWORD aligned\n");
                BUG_ON((desc_len % 4) != 0);
                error = -ENOMEM;
                goto fail;
@@ -314,9 +324,9 @@ int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd,
                goto fail;
        }
        ds = (u8 *) dd->dd_desc;
-       ath_print(common, ATH_DBG_CONFIG, "%s DMA map: %p (%u) -> %llx (%u)\n",
-                 name, ds, (u32) dd->dd_desc_len,
-                 ito64(dd->dd_desc_paddr), /*XXX*/(u32) dd->dd_desc_len);
+       ath_dbg(common, ATH_DBG_CONFIG, "%s DMA map: %p (%u) -> %llx (%u)\n",
+               name, ds, (u32) dd->dd_desc_len,
+               ito64(dd->dd_desc_paddr), /*XXX*/(u32) dd->dd_desc_len);
 
        /* allocate buffers */
        bsize = sizeof(struct ath_buf) * nbuf;
@@ -362,7 +372,7 @@ fail:
 #undef DS2PHYS
 }
 
-static void ath9k_init_crypto(struct ath_softc *sc)
+void ath9k_init_crypto(struct ath_softc *sc)
 {
        struct ath_common *common = ath9k_hw_common(sc->sc_ah);
        int i = 0;
@@ -370,9 +380,9 @@ static void ath9k_init_crypto(struct ath_softc *sc)
        /* Get the hardware key cache size. */
        common->keymax = sc->sc_ah->caps.keycache_size;
        if (common->keymax > ATH_KEYMAX) {
-               ath_print(common, ATH_DBG_ANY,
-                         "Warning, using only %u entries in %u key cache\n",
-                         ATH_KEYMAX, common->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;
        }
 
@@ -395,7 +405,8 @@ static void ath9k_init_crypto(struct ath_softc *sc)
 
 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:
@@ -408,8 +419,8 @@ static int ath9k_init_btcoex(struct ath_softc *sc)
                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:
@@ -422,59 +433,19 @@ static int ath9k_init_btcoex(struct ath_softc *sc)
 
 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;
+       for (i = 0; i < WME_NUM_AC; i++) {
+               sc->tx.txq_map[i] = ath_txq_setup(sc, ATH9K_TX_QUEUE_DATA, i);
+               sc->tx.txq_map[i]->mac80211_qnum = i;
        }
-       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;
-       }
-
        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)
@@ -545,10 +516,8 @@ static void ath9k_init_misc(struct ath_softc *sc)
 
        sc->beacon.slottime = ATH9K_SLOT_TIME_9;
 
-       for (i = 0; i < ARRAY_SIZE(sc->beacon.bslot); i++) {
+       for (i = 0; i < ARRAY_SIZE(sc->beacon.bslot); i++)
                sc->beacon.bslot[i] = NULL;
-               sc->beacon.bslot_aphy[i] = NULL;
-       }
 
        if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_ANT_DIV_COMB)
                sc->ant_comb.count = ATH_ANT_DIV_COMB_INIT_COUNT;
@@ -566,10 +535,14 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid,
        if (!ah)
                return -ENOMEM;
 
+       ah->hw = sc->hw;
        ah->hw_version.devid = devid;
        ah->hw_version.subsysid = subsysid;
        sc->sc_ah = ah;
 
+       if (!sc->dev->platform_data)
+               ah->ah_flags |= AH_USE_EEPROM;
+
        common = ath9k_hw_common(ah);
        common->ops = &ath9k_common_ops;
        common->bus_ops = bus_ops;
@@ -577,13 +550,16 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid,
        common->hw = sc->hw;
        common->priv = sc;
        common->debug_mask = ath9k_debug;
+       common->btcoex_enabled = ath9k_btcoex_enable == 1;
        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);
+#ifdef CONFIG_ATH9K_DEBUGFS
+       spin_lock_init(&sc->nodes_lock);
+       INIT_LIST_HEAD(&sc->nodes);
+#endif
        tasklet_init(&sc->intr_tq, ath9k_tasklet, (unsigned long)sc);
        tasklet_init(&sc->bcon_tasklet, ath_beacon_tasklet,
                     (unsigned long)sc);
@@ -600,13 +576,6 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid,
        if (ret)
                goto err_hw;
 
-       ret = ath9k_init_debug(ah);
-       if (ret) {
-               ath_print(common, ATH_DBG_FATAL,
-                         "Unable to create debugfs files\n");
-               goto err_debug;
-       }
-
        ret = ath9k_init_queues(sc);
        if (ret)
                goto err_queues;
@@ -629,12 +598,8 @@ err_btcoex:
                if (ATH_TXQ_SETUP(sc, i))
                        ath_tx_cleanupq(sc, &sc->tx.txq[i]);
 err_queues:
-       ath9k_exit_debug(ah);
-err_debug:
        ath9k_hw_deinit(ah);
 err_hw:
-       tasklet_kill(&sc->intr_tq);
-       tasklet_kill(&sc->bcon_tasklet);
 
        kfree(ah);
        sc->sc_ah = NULL;
@@ -642,6 +607,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);
@@ -657,7 +653,7 @@ void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
        if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT)
                 hw->flags |= IEEE80211_HW_AMPDU_AGGREGATION;
 
-       if (AR_SREV_9160_10_OR_LATER(sc->sc_ah) || modparam_nohwcrypt)
+       if (AR_SREV_9160_10_OR_LATER(sc->sc_ah) || ath9k_modparam_nohwcrypt)
                hw->flags |= IEEE80211_HW_MFP_CAPABLE;
 
        hw->wiphy->interface_modes =
@@ -737,11 +733,19 @@ int ath9k_init_device(u16 devid, struct ath_softc *sc, u16 subsysid,
        if (error != 0)
                goto error_rx;
 
+       ath9k_init_txpower_limits(sc);
+
        /* Register with mac80211 */
        error = ieee80211_register_hw(hw);
        if (error)
                goto error_register;
 
+       error = ath9k_init_debug(ah);
+       if (error) {
+               ath_err(common, "Unable to create debugfs files\n");
+               goto error_world;
+       }
+
        /* Handle world regulatory */
        if (!ath_is_world_regd(reg)) {
                error = regulatory_hint(hw->wiphy, reg->alpha2);
@@ -751,9 +755,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_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);
+       sc->last_rssi = ATH_RSSI_DUMMY_MARKER;
 
        ath_init_leds(sc);
        ath_start_rfkill_poll(sc);
@@ -799,12 +801,8 @@ static void ath9k_deinit_softc(struct ath_softc *sc)
                if (ATH_TXQ_SETUP(sc, i))
                        ath_tx_cleanupq(sc, &sc->tx.txq[i]);
 
-       ath9k_exit_debug(sc->sc_ah);
        ath9k_hw_deinit(sc->sc_ah);
 
-       tasklet_kill(&sc->intr_tq);
-       tasklet_kill(&sc->bcon_tasklet);
-
        kfree(sc->sc_ah);
        sc->sc_ah = NULL;
 }
@@ -812,28 +810,19 @@ static void ath9k_deinit_softc(struct ath_softc *sc)
 void ath9k_deinit_device(struct ath_softc *sc)
 {
        struct ieee80211_hw *hw = sc->hw;
-       int i = 0;
 
        ath9k_ps_wakeup(sc);
 
        wiphy_rfkill_stop_polling(sc->hw->wiphy);
        ath_deinit_leds(sc);
 
-       for (i = 0; i < sc->num_sec_wiphy; i++) {
-               struct ath_wiphy *aphy = sc->sec_wiphy[i];
-               if (aphy == NULL)
-                       continue;
-               sc->sec_wiphy[i] = NULL;
-               ieee80211_unregister_hw(aphy->hw);
-               ieee80211_free_hw(aphy->hw);
-       }
+       ath9k_ps_restore(sc);
 
        ieee80211_unregister_hw(hw);
        pm_qos_remove_request(&sc->pm_qos_req);
        ath_rx_cleanup(sc);
        ath_tx_cleanup(sc);
        ath9k_deinit_softc(sc);
-       kfree(sc->sec_wiphy);
 }
 
 void ath_descdma_cleanup(struct ath_softc *sc,
@@ -866,20 +855,12 @@ static int __init ath9k_init(void)
                goto err_out;
        }
 
-       error = ath9k_debug_create_root();
-       if (error) {
-               printk(KERN_ERR
-                       "ath9k: Unable to create debugfs root: %d\n",
-                       error);
-               goto err_rate_unregister;
-       }
-
        error = ath_pci_init();
        if (error < 0) {
                printk(KERN_ERR
                        "ath9k: No PCI devices found, driver not installed.\n");
                error = -ENODEV;
-               goto err_remove_root;
+               goto err_rate_unregister;
        }
 
        error = ath_ahb_init();
@@ -893,8 +874,6 @@ static int __init ath9k_init(void)
  err_pci_exit:
        ath_pci_exit();
 
- err_remove_root:
-       ath9k_debug_remove_root();
  err_rate_unregister:
        ath_rate_control_unregister();
  err_out:
@@ -904,9 +883,9 @@ module_init(ath9k_init);
 
 static void __exit ath9k_exit(void)
 {
+       is_ath9k_unloaded = true;
        ath_ahb_exit();
        ath_pci_exit();
-       ath9k_debug_remove_root();
        ath_rate_control_unregister();
        printk(KERN_INFO "%s: Driver unloaded\n", dev_info);
 }