ath9k: use ieee80211_conf on ath9k_hw_iscal_supported()
[pandora-kernel.git] / drivers / net / wireless / ath9k / main.c
index 191eec5..7d9a263 100644 (file)
@@ -59,41 +59,42 @@ static void bus_read_cachesize(struct ath_softc *sc, int *csz)
                *csz = DEFAULT_CACHELINE >> 2;   /* Use the default size */
 }
 
-static void ath_setcurmode(struct ath_softc *sc, enum wireless_mode mode)
+static void ath_cache_conf_rate(struct ath_softc *sc,
+                               struct ieee80211_conf *conf)
 {
-       sc->cur_rate_table = sc->hw_rate_table[mode];
-       /*
-        * All protection frames are transmited at 2Mb/s for
-        * 11g, otherwise at 1Mb/s.
-        * XXX select protection rate index from rate table.
-        */
-       sc->sc_protrix = (mode == ATH9K_MODE_11G ? 1 : 0);
-}
-
-static enum wireless_mode ath_chan2mode(struct ath9k_channel *chan)
-{
-       if (chan->chanmode == CHANNEL_A)
-               return ATH9K_MODE_11A;
-       else if (chan->chanmode == CHANNEL_G)
-               return ATH9K_MODE_11G;
-       else if (chan->chanmode == CHANNEL_B)
-               return ATH9K_MODE_11B;
-       else if (chan->chanmode == CHANNEL_A_HT20)
-               return ATH9K_MODE_11NA_HT20;
-       else if (chan->chanmode == CHANNEL_G_HT20)
-               return ATH9K_MODE_11NG_HT20;
-       else if (chan->chanmode == CHANNEL_A_HT40PLUS)
-               return ATH9K_MODE_11NA_HT40PLUS;
-       else if (chan->chanmode == CHANNEL_A_HT40MINUS)
-               return ATH9K_MODE_11NA_HT40MINUS;
-       else if (chan->chanmode == CHANNEL_G_HT40PLUS)
-               return ATH9K_MODE_11NG_HT40PLUS;
-       else if (chan->chanmode == CHANNEL_G_HT40MINUS)
-               return ATH9K_MODE_11NG_HT40MINUS;
-
-       WARN_ON(1); /* should not get here */
-
-       return ATH9K_MODE_11B;
+       switch (conf->channel->band) {
+       case IEEE80211_BAND_2GHZ:
+               if (conf_is_ht20(conf))
+                       sc->cur_rate_table =
+                         sc->hw_rate_table[ATH9K_MODE_11NG_HT20];
+               else if (conf_is_ht40_minus(conf))
+                       sc->cur_rate_table =
+                         sc->hw_rate_table[ATH9K_MODE_11NG_HT40MINUS];
+               else if (conf_is_ht40_plus(conf))
+                       sc->cur_rate_table =
+                         sc->hw_rate_table[ATH9K_MODE_11NG_HT40PLUS];
+               else
+                       sc->cur_rate_table =
+                         sc->hw_rate_table[ATH9K_MODE_11G];
+               break;
+       case IEEE80211_BAND_5GHZ:
+               if (conf_is_ht20(conf))
+                       sc->cur_rate_table =
+                         sc->hw_rate_table[ATH9K_MODE_11NA_HT20];
+               else if (conf_is_ht40_minus(conf))
+                       sc->cur_rate_table =
+                         sc->hw_rate_table[ATH9K_MODE_11NA_HT40MINUS];
+               else if (conf_is_ht40_plus(conf))
+                       sc->cur_rate_table =
+                         sc->hw_rate_table[ATH9K_MODE_11NA_HT40PLUS];
+               else
+                       sc->cur_rate_table =
+                         sc->hw_rate_table[ATH9K_MODE_11A];
+               break;
+       default:
+               BUG_ON(1);
+               break;
+       }
 }
 
 static void ath_update_txpow(struct ath_softc *sc)
@@ -217,6 +218,7 @@ static int ath_setup_channels(struct ath_softc *sc)
                        chan_2ghz[a].band = IEEE80211_BAND_2GHZ;
                        chan_2ghz[a].center_freq = c->channel;
                        chan_2ghz[a].max_power = c->maxTxPower;
+                       c->chan = &chan_2ghz[a];
 
                        if (c->privFlags & CHANNEL_DISALLOW_ADHOC)
                                chan_2ghz[a].flags |= IEEE80211_CHAN_NO_IBSS;
@@ -232,6 +234,7 @@ static int ath_setup_channels(struct ath_softc *sc)
                        chan_5ghz[b].band = IEEE80211_BAND_5GHZ;
                        chan_5ghz[b].center_freq = c->channel;
                        chan_5ghz[b].max_power = c->maxTxPower;
+                       c->chan = &chan_5ghz[a];
 
                        if (c->privFlags & CHANNEL_DISALLOW_ADHOC)
                                chan_5ghz[b].flags |= IEEE80211_CHAN_NO_IBSS;
@@ -258,6 +261,9 @@ static int ath_set_channel(struct ath_softc *sc, struct ath9k_channel *hchan)
 {
        struct ath_hal *ah = sc->sc_ah;
        bool fastcc = true, stopped;
+       struct ieee80211_hw *hw = sc->hw;
+       struct ieee80211_channel *channel = hw->conf.channel;
+       int r;
 
        if (sc->sc_flags & SC_OP_INVALID)
                return -EIO;
@@ -266,7 +272,6 @@ static int ath_set_channel(struct ath_softc *sc, struct ath9k_channel *hchan)
            hchan->channelFlags != sc->sc_ah->ah_curchan->channelFlags ||
            (sc->sc_flags & SC_OP_CHAINMASK_UPDATE) ||
            (sc->sc_flags & SC_OP_FULL_RESET)) {
-               int status;
                /*
                 * This is only performed if the channel settings have
                 * actually changed.
@@ -288,22 +293,20 @@ static int ath_set_channel(struct ath_softc *sc, struct ath9k_channel *hchan)
                        fastcc = false;
 
                DPRINTF(sc, ATH_DBG_CONFIG,
-                       "(%u MHz) -> (%u MHz), cflags:%x, chanwidth: %d\n",
+                       "(%u MHz) -> (%u MHz), chanwidth: %d\n",
                        sc->sc_ah->ah_curchan->channel,
-                       hchan->channel, hchan->channelFlags, sc->tx_chan_width);
+                       channel->center_freq, sc->tx_chan_width);
 
                spin_lock_bh(&sc->sc_resetlock);
-               if (!ath9k_hw_reset(ah, hchan, sc->tx_chan_width,
-                                   sc->sc_tx_chainmask, sc->sc_rx_chainmask,
-                                   sc->sc_ht_extprotspacing, fastcc, &status)) {
+
+               r = ath9k_hw_reset(ah, hchan, fastcc);
+               if (r) {
                        DPRINTF(sc, ATH_DBG_FATAL,
-                               "Unable to reset channel %u (%uMhz) "
-                               "flags 0x%x hal status %u\n",
-                               ath9k_hw_mhz2ieee(ah, hchan->channel,
-                                                 hchan->channelFlags),
-                               hchan->channel, hchan->channelFlags, status);
+                               "Unable to reset channel (%u Mhz) "
+                               "reset status %u\n",
+                               channel->center_freq, r);
                        spin_unlock_bh(&sc->sc_resetlock);
-                       return -EIO;
+                       return r;
                }
                spin_unlock_bh(&sc->sc_resetlock);
 
@@ -316,7 +319,7 @@ static int ath_set_channel(struct ath_softc *sc, struct ath9k_channel *hchan)
                        return -EIO;
                }
 
-               ath_setcurmode(sc, ath_chan2mode(hchan));
+               ath_cache_conf_rate(sc, &hw->conf);
                ath_update_txpow(sc);
                ath9k_hw_set_interrupts(ah, sc->sc_imask);
        }
@@ -369,8 +372,7 @@ static void ath_ani_calibrate(unsigned long data)
        } else {
                if ((timestamp - sc->sc_ani.sc_resetcal_timer) >=
                    ATH_RESTART_CALINTERVAL) {
-                       ath9k_hw_reset_calvalid(ah, ah->ah_curchan,
-                                               &sc->sc_ani.sc_caldone);
+                       sc->sc_ani.sc_caldone = ath9k_hw_reset_calvalid(ah);
                        if (sc->sc_ani.sc_caldone)
                                sc->sc_ani.sc_resetcal_timer = timestamp;
                }
@@ -1067,23 +1069,18 @@ fail:
 static void ath_radio_enable(struct ath_softc *sc)
 {
        struct ath_hal *ah = sc->sc_ah;
-       int status;
+       struct ieee80211_channel *channel = sc->hw->conf.channel;
+       int r;
 
        spin_lock_bh(&sc->sc_resetlock);
-       if (!ath9k_hw_reset(ah, ah->ah_curchan,
-                           sc->tx_chan_width,
-                           sc->sc_tx_chainmask,
-                           sc->sc_rx_chainmask,
-                           sc->sc_ht_extprotspacing,
-                           false, &status)) {
+
+       r = ath9k_hw_reset(ah, ah->ah_curchan, false);
+
+       if (r) {
                DPRINTF(sc, ATH_DBG_FATAL,
-                       "Unable to reset channel %u (%uMhz) "
-                       "flags 0x%x hal status %u\n",
-                       ath9k_hw_mhz2ieee(ah,
-                                         ah->ah_curchan->channel,
-                                         ah->ah_curchan->channelFlags),
-                       ah->ah_curchan->channel,
-                       ah->ah_curchan->channelFlags, status);
+                       "Unable to reset channel %u (%uMhz) ",
+                       "reset status %u\n",
+                       channel->center_freq, r);
        }
        spin_unlock_bh(&sc->sc_resetlock);
 
@@ -1111,8 +1108,8 @@ static void ath_radio_enable(struct ath_softc *sc)
 static void ath_radio_disable(struct ath_softc *sc)
 {
        struct ath_hal *ah = sc->sc_ah;
-       int status;
-
+       struct ieee80211_channel *channel = sc->hw->conf.channel;
+       int r;
 
        ieee80211_stop_queues(sc->hw);
 
@@ -1128,20 +1125,12 @@ static void ath_radio_disable(struct ath_softc *sc)
        ath_flushrecv(sc);              /* flush recv queue */
 
        spin_lock_bh(&sc->sc_resetlock);
-       if (!ath9k_hw_reset(ah, ah->ah_curchan,
-                           sc->tx_chan_width,
-                           sc->sc_tx_chainmask,
-                           sc->sc_rx_chainmask,
-                           sc->sc_ht_extprotspacing,
-                           false, &status)) {
+       r = ath9k_hw_reset(ah, ah->ah_curchan, false);
+       if (r) {
                DPRINTF(sc, ATH_DBG_FATAL,
                        "Unable to reset channel %u (%uMhz) "
-                       "flags 0x%x hal status %u\n",
-                       ath9k_hw_mhz2ieee(ah,
-                               ah->ah_curchan->channel,
-                               ah->ah_curchan->channelFlags),
-                       ah->ah_curchan->channel,
-                       ah->ah_curchan->channelFlags, status);
+                       "reset status %u\n",
+                       channel->center_freq, r);
        }
        spin_unlock_bh(&sc->sc_resetlock);
 
@@ -1619,8 +1608,8 @@ detach:
 int ath_reset(struct ath_softc *sc, bool retry_tx)
 {
        struct ath_hal *ah = sc->sc_ah;
-       int status;
-       int error = 0;
+       struct ieee80211_hw *hw = sc->hw;
+       int r;
 
        ath9k_hw_set_interrupts(ah, 0);
        ath_draintxq(sc, retry_tx);
@@ -1628,14 +1617,10 @@ int ath_reset(struct ath_softc *sc, bool retry_tx)
        ath_flushrecv(sc);
 
        spin_lock_bh(&sc->sc_resetlock);
-       if (!ath9k_hw_reset(ah, sc->sc_ah->ah_curchan,
-                           sc->tx_chan_width,
-                           sc->sc_tx_chainmask, sc->sc_rx_chainmask,
-                           sc->sc_ht_extprotspacing, false, &status)) {
+       r = ath9k_hw_reset(ah, sc->sc_ah->ah_curchan, false);
+       if (r)
                DPRINTF(sc, ATH_DBG_FATAL,
-                       "Unable to reset hardware; hal status %u\n", status);
-               error = -EIO;
-       }
+                       "Unable to reset hardware; reset status %u\n", r);
        spin_unlock_bh(&sc->sc_resetlock);
 
        if (ath_startrecv(sc) != 0)
@@ -1646,7 +1631,7 @@ int ath_reset(struct ath_softc *sc, bool retry_tx)
         * that changes the channel so update any state that
         * might change as a result.
         */
-       ath_setcurmode(sc, ath_chan2mode(sc->sc_ah->ah_curchan));
+       ath_cache_conf_rate(sc, &hw->conf);
 
        ath_update_txpow(sc);
 
@@ -1666,7 +1651,7 @@ int ath_reset(struct ath_softc *sc, bool retry_tx)
                }
        }
 
-       return error;
+       return r;
 }
 
 /*
@@ -1849,7 +1834,7 @@ static int ath9k_start(struct ieee80211_hw *hw)
        struct ath_softc *sc = hw->priv;
        struct ieee80211_channel *curchan = hw->conf.channel;
        struct ath9k_channel *init_channel;
-       int error = 0, pos, status;
+       int r, pos;
 
        DPRINTF(sc, ATH_DBG_CONFIG, "Starting driver with "
                "initial channel: %d MHz\n", curchan->center_freq);
@@ -1859,8 +1844,7 @@ static int ath9k_start(struct ieee80211_hw *hw)
        pos = ath_get_channel(sc, curchan);
        if (pos == -1) {
                DPRINTF(sc, ATH_DBG_FATAL, "Invalid channel: %d\n", curchan->center_freq);
-               error = -EINVAL;
-               goto error;
+               return -EINVAL;
        }
 
        sc->tx_chan_width = ATH9K_HT_MACMODE_20;
@@ -1879,17 +1863,14 @@ static int ath9k_start(struct ieee80211_hw *hw)
         * and then setup of the interrupt mask.
         */
        spin_lock_bh(&sc->sc_resetlock);
-       if (!ath9k_hw_reset(sc->sc_ah, init_channel,
-                           sc->tx_chan_width,
-                           sc->sc_tx_chainmask, sc->sc_rx_chainmask,
-                           sc->sc_ht_extprotspacing, false, &status)) {
+       r = ath9k_hw_reset(sc->sc_ah, init_channel, false);
+       if (r) {
                DPRINTF(sc, ATH_DBG_FATAL,
-                       "Unable to reset hardware; hal status %u "
-                       "(freq %u flags 0x%x)\n", status,
-                       init_channel->channel, init_channel->channelFlags);
-               error = -EIO;
+                       "Unable to reset hardware; reset status %u "
+                       "(freq %u MHz)\n", r,
+                       curchan->center_freq);
                spin_unlock_bh(&sc->sc_resetlock);
-               goto error;
+               return r;
        }
        spin_unlock_bh(&sc->sc_resetlock);
 
@@ -1909,8 +1890,7 @@ static int ath9k_start(struct ieee80211_hw *hw)
        if (ath_startrecv(sc) != 0) {
                DPRINTF(sc, ATH_DBG_FATAL,
                        "Unable to start recv logic\n");
-               error = -EIO;
-               goto error;
+               return -EIO;
        }
 
        /* Setup our intr mask. */
@@ -1943,7 +1923,7 @@ static int ath9k_start(struct ieee80211_hw *hw)
            !sc->sc_config.swBeaconProcess)
                sc->sc_imask |= ATH9K_INT_TIM;
 
-       ath_setcurmode(sc, ath_chan2mode(init_channel));
+       ath_cache_conf_rate(sc, &hw->conf);
 
        sc->sc_flags &= ~SC_OP_INVALID;
 
@@ -1954,11 +1934,9 @@ static int ath9k_start(struct ieee80211_hw *hw)
        ieee80211_wake_queues(sc->hw);
 
 #if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
-       error = ath_start_rfkill_poll(sc);
+       r = ath_start_rfkill_poll(sc);
 #endif
-
-error:
-       return error;
+       return r;
 }
 
 static int ath9k_tx(struct ieee80211_hw *hw,
@@ -2164,13 +2142,13 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
                                                    conf->ht.channel_type);
                }
 
+               ath_update_chainmask(sc, conf->ht.enabled);
+
                if (ath_set_channel(sc, &sc->sc_ah->ah_channels[pos]) < 0) {
                        DPRINTF(sc, ATH_DBG_FATAL, "Unable to set channel\n");
                        mutex_unlock(&sc->mutex);
                        return -EINVAL;
                }
-
-               ath_update_chainmask(sc, conf->ht.enabled);
        }
 
        if (changed & IEEE80211_CONF_CHANGE_POWER)