ath9k: fix panic while cleaning up virtaul wifis
[pandora-kernel.git] / drivers / net / wireless / ath / ath9k / init.c
index 70e5aa4..243c177 100644 (file)
@@ -14,6 +14,8 @@
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
+#include <linux/slab.h>
+
 #include "ath9k.h"
 
 static char *dev_info = "ath9k";
@@ -31,6 +33,10 @@ int modparam_nohwcrypt;
 module_param_named(nohwcrypt, modparam_nohwcrypt, int, 0444);
 MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption");
 
+int led_blink = 1;
+module_param_named(blink, led_blink, int, 0444);
+MODULE_PARM_DESC(blink, "Enable LED blink on activity");
+
 /* We use the hw_value as an index into our private channel structure */
 
 #define CHAN2G(_freq, _idx)  { \
@@ -173,18 +179,6 @@ static const struct ath_ops ath9k_common_ops = {
        .write = ath9k_iowrite32,
 };
 
-static int count_streams(unsigned int chainmask, int max)
-{
-       int streams = 0;
-
-       do {
-               if (++streams == max)
-                       break;
-       } while ((chainmask = chainmask & (chainmask - 1)));
-
-       return streams;
-}
-
 /**************************/
 /*     Initialization     */
 /**************************/
@@ -206,6 +200,9 @@ static void setup_ht_cap(struct ath_softc *sc,
        if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_LDPC)
                ht_info->cap |= IEEE80211_HT_CAP_LDPC_CODING;
 
+       if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_SGI_20)
+               ht_info->cap |= IEEE80211_HT_CAP_SGI_20;
+
        ht_info->ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
        ht_info->ampdu_density = IEEE80211_HT_MPDU_DENSITY_8;
 
@@ -222,8 +219,8 @@ static void setup_ht_cap(struct ath_softc *sc,
 
        /* set up supported mcs set */
        memset(&ht_info->mcs, 0, sizeof(ht_info->mcs));
-       tx_streams = count_streams(common->tx_chainmask, max_streams);
-       rx_streams = count_streams(common->rx_chainmask, max_streams);
+       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",
@@ -306,7 +303,7 @@ int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd,
                        dd->dd_desc_len += dma_len;
 
                        ndesc_skipped = ATH_DESC_4KB_BOUND_NUM_SKIPPED(dma_len);
-               };
+               }
        }
 
        /* allocate descriptors */
@@ -386,36 +383,14 @@ static void ath9k_init_crypto(struct ath_softc *sc)
        for (i = 0; i < common->keymax; i++)
                ath9k_hw_keyreset(sc->sc_ah, (u16) i);
 
-       if (ath9k_hw_getcapability(sc->sc_ah, ATH9K_CAP_CIPHER,
-                                  ATH9K_CIPHER_TKIP, NULL)) {
-               /*
-                * Whether we should enable h/w TKIP MIC.
-                * XXX: if we don't support WME TKIP MIC, then we wouldn't
-                * report WMM capable, so it's always safe to turn on
-                * TKIP MIC in this case.
-                */
-               ath9k_hw_setcapability(sc->sc_ah, ATH9K_CAP_TKIP_MIC, 0, 1, NULL);
-       }
-
        /*
         * Check whether the separate key cache entries
         * are required to handle both tx+rx MIC keys.
         * With split mic keys the number of stations is limited
         * to 27 otherwise 59.
         */
-       if (ath9k_hw_getcapability(sc->sc_ah, ATH9K_CAP_CIPHER,
-                                  ATH9K_CIPHER_TKIP, NULL)
-           && ath9k_hw_getcapability(sc->sc_ah, ATH9K_CAP_CIPHER,
-                                     ATH9K_CIPHER_MIC, NULL)
-           && ath9k_hw_getcapability(sc->sc_ah, ATH9K_CAP_TKIP_SPLIT,
-                                     0, NULL))
+       if (!(sc->sc_ah->misc_mode & AR_PCU_MIC_NEW_LOC_ENA))
                common->splitmic = 1;
-
-       /* turn on mcast key search if possible */
-       if (!ath9k_hw_getcapability(sc->sc_ah, ATH9K_CAP_MCAST_KEYSRCH, 0, NULL))
-               (void)ath9k_hw_setcapability(sc->sc_ah, ATH9K_CAP_MCAST_KEYSRCH,
-                                            1, 1, NULL);
-
 }
 
 static int ath9k_init_btcoex(struct ath_softc *sc)
@@ -433,7 +408,7 @@ static int ath9k_init_btcoex(struct ath_softc *sc)
                r = ath_init_btcoex_timer(sc);
                if (r)
                        return -1;
-               qnum = ath_tx_get_qnum(sc, ATH9K_TX_QUEUE_DATA, ATH9K_WME_AC_BE);
+               qnum = sc->tx.hwq_map[WME_AC_BE];
                ath9k_hw_init_btcoex_hw(sc->sc_ah, qnum);
                sc->btcoex.bt_stomp_type = ATH_BTCOEX_STOMP_LOW;
                break;
@@ -470,23 +445,23 @@ static int ath9k_init_queues(struct ath_softc *sc)
        sc->config.cabqReadytime = ATH_CABQ_READY_TIME;
        ath_cabq_update(sc);
 
-       if (!ath_tx_setup(sc, ATH9K_WME_AC_BK)) {
+       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, ATH9K_WME_AC_BE)) {
+       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, ATH9K_WME_AC_VI)) {
+       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, ATH9K_WME_AC_VO)) {
+       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;
@@ -743,6 +718,8 @@ int ath9k_init_device(u16 devid, struct ath_softc *sc, u16 subsysid,
                        goto error_world;
        }
 
+       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);
@@ -810,12 +787,12 @@ void ath9k_deinit_device(struct ath_softc *sc)
                ieee80211_unregister_hw(aphy->hw);
                ieee80211_free_hw(aphy->hw);
        }
-       kfree(sc->sec_wiphy);
 
        ieee80211_unregister_hw(hw);
        ath_rx_cleanup(sc);
        ath_tx_cleanup(sc);
        ath9k_deinit_softc(sc);
+       kfree(sc->sec_wiphy);
 }
 
 void ath_descdma_cleanup(struct ath_softc *sc,