Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wirel...
[pandora-kernel.git] / drivers / net / wireless / ath / ath5k / base.c
index 09ae4ef..dbc45e0 100644 (file)
@@ -61,6 +61,9 @@
 #include "debug.h"
 #include "ani.h"
 
 #include "debug.h"
 #include "ani.h"
 
+#define CREATE_TRACE_POINTS
+#include "trace.h"
+
 int ath5k_modparam_nohwcrypt;
 module_param_named(nohwcrypt, ath5k_modparam_nohwcrypt, bool, S_IRUGO);
 MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption.");
 int ath5k_modparam_nohwcrypt;
 module_param_named(nohwcrypt, ath5k_modparam_nohwcrypt, bool, S_IRUGO);
 MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption.");
@@ -241,74 +244,69 @@ static int ath5k_reg_notifier(struct wiphy *wiphy, struct regulatory_request *re
 * Channel/mode setup *
 \********************/
 
 * Channel/mode setup *
 \********************/
 
-/*
- * Convert IEEE channel number to MHz frequency.
- */
-static inline short
-ath5k_ieee2mhz(short chan)
-{
-       if (chan <= 14 || chan >= 27)
-               return ieee80211chan2mhz(chan);
-       else
-               return 2212 + chan * 20;
-}
-
 /*
  * Returns true for the channel numbers used without all_channels modparam.
  */
 /*
  * Returns true for the channel numbers used without all_channels modparam.
  */
-static bool ath5k_is_standard_channel(short chan)
+static bool ath5k_is_standard_channel(short chan, enum ieee80211_band band)
 {
 {
-       return ((chan <= 14) ||
-               /* UNII 1,2 */
-               ((chan & 3) == 0 && chan >= 36 && chan <= 64) ||
+       if (band == IEEE80211_BAND_2GHZ && chan <= 14)
+               return true;
+
+       return  /* UNII 1,2 */
+               (((chan & 3) == 0 && chan >= 36 && chan <= 64) ||
                /* midband */
                ((chan & 3) == 0 && chan >= 100 && chan <= 140) ||
                /* UNII-3 */
                /* midband */
                ((chan & 3) == 0 && chan >= 100 && chan <= 140) ||
                /* UNII-3 */
-               ((chan & 3) == 1 && chan >= 149 && chan <= 165));
+               ((chan & 3) == 1 && chan >= 149 && chan <= 165) ||
+               /* 802.11j 5.030-5.080 GHz (20MHz) */
+               (chan == 8 || chan == 12 || chan == 16) ||
+               /* 802.11j 4.9GHz (20MHz) */
+               (chan == 184 || chan == 188 || chan == 192 || chan == 196));
 }
 
 static unsigned int
 }
 
 static unsigned int
-ath5k_copy_channels(struct ath5k_hw *ah,
-               struct ieee80211_channel *channels,
-               unsigned int mode,
-               unsigned int max)
+ath5k_setup_channels(struct ath5k_hw *ah, struct ieee80211_channel *channels,
+               unsigned int mode, unsigned int max)
 {
 {
-       unsigned int i, count, size, chfreq, freq, ch;
-
-       if (!test_bit(mode, ah->ah_modes))
-               return 0;
+       unsigned int count, size, chfreq, freq, ch;
+       enum ieee80211_band band;
 
        switch (mode) {
        case AR5K_MODE_11A:
                /* 1..220, but 2GHz frequencies are filtered by check_channel */
 
        switch (mode) {
        case AR5K_MODE_11A:
                /* 1..220, but 2GHz frequencies are filtered by check_channel */
-               size = 220 ;
+               size = 220;
                chfreq = CHANNEL_5GHZ;
                chfreq = CHANNEL_5GHZ;
+               band = IEEE80211_BAND_5GHZ;
                break;
        case AR5K_MODE_11B:
        case AR5K_MODE_11G:
                size = 26;
                chfreq = CHANNEL_2GHZ;
                break;
        case AR5K_MODE_11B:
        case AR5K_MODE_11G:
                size = 26;
                chfreq = CHANNEL_2GHZ;
+               band = IEEE80211_BAND_2GHZ;
                break;
        default:
                ATH5K_WARN(ah->ah_sc, "bad mode, not copying channels\n");
                return 0;
        }
 
                break;
        default:
                ATH5K_WARN(ah->ah_sc, "bad mode, not copying channels\n");
                return 0;
        }
 
-       for (i = 0, count = 0; i < size && max > 0; i++) {
-               ch = i + 1 ;
-               freq = ath5k_ieee2mhz(ch);
+       count = 0;
+       for (ch = 1; ch <= size && count < max; ch++) {
+               freq = ieee80211_channel_to_frequency(ch, band);
+
+               if (freq == 0) /* mapping failed - not a standard channel */
+                       continue;
 
                /* Check if channel is supported by the chipset */
                if (!ath5k_channel_ok(ah, freq, chfreq))
                        continue;
 
 
                /* Check if channel is supported by the chipset */
                if (!ath5k_channel_ok(ah, freq, chfreq))
                        continue;
 
-               if (!modparam_all_channels && !ath5k_is_standard_channel(ch))
+               if (!modparam_all_channels &&
+                   !ath5k_is_standard_channel(ch, band))
                        continue;
 
                /* Write channel info and increment counter */
                channels[count].center_freq = freq;
                        continue;
 
                /* Write channel info and increment counter */
                channels[count].center_freq = freq;
-               channels[count].band = (chfreq == CHANNEL_2GHZ) ?
-                       IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ;
+               channels[count].band = band;
                switch (mode) {
                case AR5K_MODE_11A:
                case AR5K_MODE_11G:
                switch (mode) {
                case AR5K_MODE_11A:
                case AR5K_MODE_11G:
@@ -319,7 +317,6 @@ ath5k_copy_channels(struct ath5k_hw *ah,
                }
 
                count++;
                }
 
                count++;
-               max--;
        }
 
        return count;
        }
 
        return count;
@@ -364,7 +361,7 @@ ath5k_setup_bands(struct ieee80211_hw *hw)
                sband->n_bitrates = 12;
 
                sband->channels = sc->channels;
                sband->n_bitrates = 12;
 
                sband->channels = sc->channels;
-               sband->n_channels = ath5k_copy_channels(ah, sband->channels,
+               sband->n_channels = ath5k_setup_channels(ah, sband->channels,
                                        AR5K_MODE_11G, max_c);
 
                hw->wiphy->bands[IEEE80211_BAND_2GHZ] = sband;
                                        AR5K_MODE_11G, max_c);
 
                hw->wiphy->bands[IEEE80211_BAND_2GHZ] = sband;
@@ -390,7 +387,7 @@ ath5k_setup_bands(struct ieee80211_hw *hw)
                }
 
                sband->channels = sc->channels;
                }
 
                sband->channels = sc->channels;
-               sband->n_channels = ath5k_copy_channels(ah, sband->channels,
+               sband->n_channels = ath5k_setup_channels(ah, sband->channels,
                                        AR5K_MODE_11B, max_c);
 
                hw->wiphy->bands[IEEE80211_BAND_2GHZ] = sband;
                                        AR5K_MODE_11B, max_c);
 
                hw->wiphy->bands[IEEE80211_BAND_2GHZ] = sband;
@@ -410,7 +407,7 @@ ath5k_setup_bands(struct ieee80211_hw *hw)
                sband->n_bitrates = 8;
 
                sband->channels = &sc->channels[count_c];
                sband->n_bitrates = 8;
 
                sband->channels = &sc->channels[count_c];
-               sband->n_channels = ath5k_copy_channels(ah, sband->channels,
+               sband->n_channels = ath5k_setup_channels(ah, sband->channels,
                                        AR5K_MODE_11A, max_c);
 
                hw->wiphy->bands[IEEE80211_BAND_5GHZ] = sband;
                                        AR5K_MODE_11A, max_c);
 
                hw->wiphy->bands[IEEE80211_BAND_5GHZ] = sband;
@@ -445,18 +442,6 @@ ath5k_chan_set(struct ath5k_softc *sc, struct ieee80211_channel *chan)
        return ath5k_reset(sc, chan, true);
 }
 
        return ath5k_reset(sc, chan, true);
 }
 
-static void
-ath5k_setcurmode(struct ath5k_softc *sc, unsigned int mode)
-{
-       sc->curmode = mode;
-
-       if (mode == AR5K_MODE_11A) {
-               sc->curband = &sc->sbands[IEEE80211_BAND_5GHZ];
-       } else {
-               sc->curband = &sc->sbands[IEEE80211_BAND_2GHZ];
-       }
-}
-
 struct ath_vif_iter_data {
        const u8        *hw_macaddr;
        u8              mask[ETH_ALEN];
 struct ath_vif_iter_data {
        const u8        *hw_macaddr;
        u8              mask[ETH_ALEN];
@@ -569,7 +554,7 @@ ath5k_hw_to_driver_rix(struct ath5k_softc *sc, int hw_rix)
                        "hw_rix out of bounds: %x\n", hw_rix))
                return 0;
 
                        "hw_rix out of bounds: %x\n", hw_rix))
                return 0;
 
-       rix = sc->rate_idx[sc->curband->band][hw_rix];
+       rix = sc->rate_idx[sc->curchan->band][hw_rix];
        if (WARN(rix < 0, "invalid hw_rix: %x\n", hw_rix))
                rix = 0;
 
        if (WARN(rix < 0, "invalid hw_rix: %x\n", hw_rix))
                rix = 0;
 
@@ -1379,7 +1364,7 @@ ath5k_receive_frame(struct ath5k_softc *sc, struct sk_buff *skb,
        rxs->flag |= RX_FLAG_TSFT;
 
        rxs->freq = sc->curchan->center_freq;
        rxs->flag |= RX_FLAG_TSFT;
 
        rxs->freq = sc->curchan->center_freq;
-       rxs->band = sc->curband->band;
+       rxs->band = sc->curchan->band;
 
        rxs->signal = sc->ah->ah_noise_floor + rs->rs_rssi;
 
 
        rxs->signal = sc->ah->ah_noise_floor + rs->rs_rssi;
 
@@ -1394,10 +1379,10 @@ ath5k_receive_frame(struct ath5k_softc *sc, struct sk_buff *skb,
        rxs->flag |= ath5k_rx_decrypted(sc, skb, rs);
 
        if (rxs->rate_idx >= 0 && rs->rs_rate ==
        rxs->flag |= ath5k_rx_decrypted(sc, skb, rs);
 
        if (rxs->rate_idx >= 0 && rs->rs_rate ==
-           sc->curband->bitrates[rxs->rate_idx].hw_value_short)
+           sc->sbands[sc->curchan->band].bitrates[rxs->rate_idx].hw_value_short)
                rxs->flag |= RX_FLAG_SHORTPRE;
 
                rxs->flag |= RX_FLAG_SHORTPRE;
 
-       ath5k_debug_dump_skb(sc, skb, "RX  ", 0);
+       trace_ath5k_rx(sc, skb);
 
        ath5k_update_beacon_rssi(sc, skb, rs->rs_rssi);
 
 
        ath5k_update_beacon_rssi(sc, skb, rs->rs_rssi);
 
@@ -1542,7 +1527,7 @@ ath5k_tx_queue(struct ieee80211_hw *hw, struct sk_buff *skb,
        unsigned long flags;
        int padsize;
 
        unsigned long flags;
        int padsize;
 
-       ath5k_debug_dump_skb(sc, skb, "TX  ", 1);
+       trace_ath5k_tx(sc, skb, txq);
 
        /*
         * The hardware expects the header padded to 4 byte boundaries.
 
        /*
         * The hardware expects the header padded to 4 byte boundaries.
@@ -1591,7 +1576,7 @@ drop_packet:
 
 static void
 ath5k_tx_frame_completed(struct ath5k_softc *sc, struct sk_buff *skb,
 
 static void
 ath5k_tx_frame_completed(struct ath5k_softc *sc, struct sk_buff *skb,
-                        struct ath5k_tx_status *ts)
+                        struct ath5k_txq *txq, struct ath5k_tx_status *ts)
 {
        struct ieee80211_tx_info *info;
        int i;
 {
        struct ieee80211_tx_info *info;
        int i;
@@ -1643,6 +1628,7 @@ ath5k_tx_frame_completed(struct ath5k_softc *sc, struct sk_buff *skb,
        else
                sc->stats.antenna_tx[0]++; /* invalid */
 
        else
                sc->stats.antenna_tx[0]++; /* invalid */
 
+       trace_ath5k_tx_complete(sc, skb, txq, ts);
        ieee80211_tx_status(sc->hw, skb);
 }
 
        ieee80211_tx_status(sc->hw, skb);
 }
 
@@ -1679,7 +1665,7 @@ ath5k_tx_processq(struct ath5k_softc *sc, struct ath5k_txq *txq)
 
                        dma_unmap_single(sc->dev, bf->skbaddr, skb->len,
                                        DMA_TO_DEVICE);
 
                        dma_unmap_single(sc->dev, bf->skbaddr, skb->len,
                                        DMA_TO_DEVICE);
-                       ath5k_tx_frame_completed(sc, skb, &ts);
+                       ath5k_tx_frame_completed(sc, skb, txq, &ts);
                }
 
                /*
                }
 
                /*
@@ -1821,8 +1807,6 @@ ath5k_beacon_update(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
                goto out;
        }
 
                goto out;
        }
 
-       ath5k_debug_dump_skb(sc, skb, "BC  ", 1);
-
        ath5k_txbuf_free_skb(sc, avf->bbuf);
        avf->bbuf->skb = skb;
        ret = ath5k_beacon_setup(sc, avf->bbuf);
        ath5k_txbuf_free_skb(sc, avf->bbuf);
        avf->bbuf->skb = skb;
        ret = ath5k_beacon_setup(sc, avf->bbuf);
@@ -1917,6 +1901,8 @@ ath5k_beacon_send(struct ath5k_softc *sc)
                        sc->opmode == NL80211_IFTYPE_MESH_POINT)
                ath5k_beacon_update(sc->hw, vif);
 
                        sc->opmode == NL80211_IFTYPE_MESH_POINT)
                ath5k_beacon_update(sc->hw, vif);
 
+       trace_ath5k_tx(sc, bf->skb, &sc->txqs[sc->bhalq]);
+
        ath5k_hw_set_txdp(ah, sc->bhalq, bf->daddr);
        ath5k_hw_start_tx_dma(ah, sc->bhalq);
        ATH5K_DBG(sc, ATH5K_DEBUG_BEACON, "TXDP[%u] = %llx (%p)\n",
        ath5k_hw_set_txdp(ah, sc->bhalq, bf->daddr);
        ath5k_hw_start_tx_dma(ah, sc->bhalq);
        ATH5K_DBG(sc, ATH5K_DEBUG_BEACON, "TXDP[%u] = %llx (%p)\n",
@@ -2417,7 +2403,8 @@ ath5k_init_softc(struct ath5k_softc *sc, const struct ath_bus_ops *bus_ops)
        /* set up multi-rate retry capabilities */
        if (sc->ah->ah_version == AR5K_AR5212) {
                hw->max_rates = 4;
        /* set up multi-rate retry capabilities */
        if (sc->ah->ah_version == AR5K_AR5212) {
                hw->max_rates = 4;
-               hw->max_rate_tries = 11;
+               hw->max_rate_tries = max(AR5K_INIT_RETRY_SHORT,
+                                        AR5K_INIT_RETRY_LONG);
        }
 
        hw->vif_data_size = sizeof(struct ath5k_vif);
        }
 
        hw->vif_data_size = sizeof(struct ath5k_vif);
@@ -2554,7 +2541,6 @@ ath5k_init_hw(struct ath5k_softc *sc)
         * and then setup of the interrupt mask.
         */
        sc->curchan = sc->hw->conf.channel;
         * and then setup of the interrupt mask.
         */
        sc->curchan = sc->hw->conf.channel;
-       sc->curband = &sc->sbands[sc->curchan->band];
        sc->imask = AR5K_INT_RXOK | AR5K_INT_RXERR | AR5K_INT_RXEOL |
                AR5K_INT_RXORN | AR5K_INT_TXDESC | AR5K_INT_TXEOL |
                AR5K_INT_FATAL | AR5K_INT_GLOBAL | AR5K_INT_MIB;
        sc->imask = AR5K_INT_RXOK | AR5K_INT_RXERR | AR5K_INT_RXEOL |
                AR5K_INT_RXORN | AR5K_INT_TXDESC | AR5K_INT_TXEOL |
                AR5K_INT_FATAL | AR5K_INT_GLOBAL | AR5K_INT_MIB;
@@ -2681,10 +2667,8 @@ ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan,
         * so we should also free any remaining
         * tx buffers */
        ath5k_drain_tx_buffs(sc);
         * so we should also free any remaining
         * tx buffers */
        ath5k_drain_tx_buffs(sc);
-       if (chan) {
+       if (chan)
                sc->curchan = chan;
                sc->curchan = chan;
-               sc->curband = &sc->sbands[chan->band];
-       }
        ret = ath5k_hw_reset(ah, sc->opmode, sc->curchan, chan != NULL,
                                                                skip_pcu);
        if (ret) {
        ret = ath5k_hw_reset(ah, sc->opmode, sc->curchan, chan != NULL,
                                                                skip_pcu);
        if (ret) {
@@ -2782,12 +2766,6 @@ ath5k_init(struct ieee80211_hw *hw)
                goto err;
        }
 
                goto err;
        }
 
-       /* NB: setup here so ath5k_rate_update is happy */
-       if (test_bit(AR5K_MODE_11A, ah->ah_modes))
-               ath5k_setcurmode(sc, AR5K_MODE_11A);
-       else
-               ath5k_setcurmode(sc, AR5K_MODE_11B);
-
        /*
         * Allocate tx+rx descriptors and populate the lists.
         */
        /*
         * Allocate tx+rx descriptors and populate the lists.
         */