]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - drivers/net/wireless/ath5k/base.c
mac80211: let drivers wake but not start queues
[karo-tx-linux.git] / drivers / net / wireless / ath5k / base.c
index b5c0a0d7a81c6980590fcad12f1a4ebc843df2cc..3f16ad66bdb51478de991d73e18a8ac44194b9fe 100644 (file)
 #include "reg.h"
 #include "debug.h"
 
-/* unaligned little endian access */
-#define LE_READ_2(_p) (le16_to_cpu(get_unaligned((__le16 *)(_p))))
-#define LE_READ_4(_p) (le32_to_cpu(get_unaligned((__le32 *)(_p))))
-
 enum {
        ATH_LED_TX,
        ATH_LED_RX,
@@ -126,6 +122,7 @@ static struct ath5k_srev_name srev_names[] = {
        { "5414",       AR5K_VERSION_VER,       AR5K_SREV_VER_AR5414 },
        { "5416",       AR5K_VERSION_VER,       AR5K_SREV_VER_AR5416 },
        { "5418",       AR5K_VERSION_VER,       AR5K_SREV_VER_AR5418 },
+       { "2425",       AR5K_VERSION_VER,       AR5K_SREV_VER_AR2425 },
        { "xxxxx",      AR5K_VERSION_VER,       AR5K_SREV_UNKNOWN },
        { "5110",       AR5K_VERSION_RAD,       AR5K_SREV_RAD_5110 },
        { "5111",       AR5K_VERSION_RAD,       AR5K_SREV_RAD_5111 },
@@ -461,13 +458,11 @@ ath5k_pci_probe(struct pci_dev *pdev,
 
        /* Initialize driver private data */
        SET_IEEE80211_DEV(hw, &pdev->dev);
-       hw->flags = IEEE80211_HW_RX_INCLUDES_FCS;
+       hw->flags = IEEE80211_HW_RX_INCLUDES_FCS |
+                   IEEE80211_HW_SIGNAL_DBM |
+                   IEEE80211_HW_NOISE_DBM;
        hw->extra_tx_headroom = 2;
        hw->channel_change_time = 5000;
-       /* these names are misleading */
-       hw->max_rssi = -110; /* signal in dBm */
-       hw->max_noise = -110; /* noise in dBm */
-       hw->max_signal = 100; /* we will provide a percentage based on rssi */
        sc = hw->priv;
        sc->hw = hw;
        sc->pdev = pdev;
@@ -1322,7 +1317,7 @@ ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf,
        pktlen = skb->len;
 
        if (!(ctl->flags & IEEE80211_TXCTL_DO_NOT_ENCRYPT)) {
-               keyidx = ctl->key_idx;
+               keyidx = ctl->hw_key->hw_key_idx;
                pktlen += ctl->icv_len;
        }
 
@@ -1338,7 +1333,7 @@ ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf,
 
        spin_lock_bh(&txq->lock);
        list_add_tail(&bf->list, &txq->q);
-       sc->tx_stats.data[txq->qnum].len++;
+       sc->tx_stats[txq->qnum].len++;
        if (txq->link == NULL) /* is this first packet? */
                ath5k_hw_put_tx_buf(ah, txq->qnum, bf->daddr);
        else /* no, so only link it */
@@ -1569,7 +1564,7 @@ ath5k_txq_drainq(struct ath5k_softc *sc, struct ath5k_txq *txq)
                ath5k_txbuf_free(sc, bf);
 
                spin_lock_bh(&sc->txbuflock);
-               sc->tx_stats.data[txq->qnum].len--;
+               sc->tx_stats[txq->qnum].len--;
                list_move_tail(&bf->list, &sc->txbuf);
                sc->txbuf_len++;
                spin_unlock_bh(&sc->txbuflock);
@@ -1604,7 +1599,7 @@ ath5k_txq_cleanup(struct ath5k_softc *sc)
                                        sc->txqs[i].link);
                        }
        }
-       ieee80211_start_queues(sc->hw); /* XXX move to callers */
+       ieee80211_wake_queues(sc->hw); /* XXX move to callers */
 
        for (i = 0; i < ARRAY_SIZE(sc->txqs); i++)
                if (sc->txqs[i].setup)
@@ -1739,8 +1734,10 @@ ath5k_check_ibss_tsf(struct ath5k_softc *sc, struct sk_buff *skb,
 
                ATH5K_DBG_UNLIMIT(sc, ATH5K_DEBUG_BEACON,
                        "beacon %llx mactime %llx (diff %lld) tsf now %llx\n",
-                       bc_tstamp, rxs->mactime,
-                       (rxs->mactime - bc_tstamp), tsf);
+                       (unsigned long long)bc_tstamp,
+                       (unsigned long long)rxs->mactime,
+                       (unsigned long long)(rxs->mactime - bc_tstamp),
+                       (unsigned long long)tsf);
 
                /*
                 * Sometimes the HW will give us a wrong tstamp in the rx
@@ -1756,7 +1753,8 @@ ath5k_check_ibss_tsf(struct ath5k_softc *sc, struct sk_buff *skb,
                if (bc_tstamp > rxs->mactime) {
                        ATH5K_DBG_UNLIMIT(sc, ATH5K_DEBUG_BEACON,
                                "fixing mactime from %llx to %llx\n",
-                               rxs->mactime, tsf);
+                               (unsigned long long)rxs->mactime,
+                               (unsigned long long)tsf);
                        rxs->mactime = tsf;
                }
 
@@ -1787,6 +1785,8 @@ ath5k_tasklet_rx(unsigned long data)
 
        spin_lock(&sc->rxbuflock);
        do {
+               rxs.flag = 0;
+
                if (unlikely(list_empty(&sc->rxbuf))) {
                        ATH5K_WARN(sc, "empty rx buf pool\n");
                        break;
@@ -1893,20 +1893,9 @@ accept:
                rxs.freq = sc->curchan->center_freq;
                rxs.band = sc->curband->band;
 
-               /*
-                * signal quality:
-                * the names here are misleading and the usage of these
-                * values by iwconfig makes it even worse
-                */
-               /* noise floor in dBm, from the last noise calibration */
                rxs.noise = sc->ah->ah_noise_floor;
-               /* signal level in dBm */
-               rxs.ssi = rxs.noise + rs.rs_rssi;
-               /*
-                * "signal" is actually displayed as Link Quality by iwconfig
-                * we provide a percentage based on rssi (assuming max rssi 64)
-                */
-               rxs.signal = rs.rs_rssi * 100 / 64;
+               rxs.signal = rxs.noise + rs.rs_rssi;
+               rxs.qual = rs.rs_rssi * 100 / 64;
 
                rxs.antenna = rs.rs_antenna;
                rxs.rate_idx = ath5k_hw_to_driver_rix(sc, rs.rs_rate);
@@ -1979,10 +1968,10 @@ ath5k_tx_processq(struct ath5k_softc *sc, struct ath5k_txq *txq)
                }
 
                ieee80211_tx_status(sc->hw, skb, &txs);
-               sc->tx_stats.data[txq->qnum].count++;
+               sc->tx_stats[txq->qnum].count++;
 
                spin_lock(&sc->txbuflock);
-               sc->tx_stats.data[txq->qnum].len--;
+               sc->tx_stats[txq->qnum].len--;
                list_move_tail(&bf->list, &sc->txbuf);
                sc->txbuf_len++;
                spin_unlock(&sc->txbuflock);
@@ -2338,7 +2327,8 @@ ath5k_init(struct ath5k_softc *sc)
         * Enable interrupts.
         */
        sc->imask = AR5K_INT_RX | AR5K_INT_TX | AR5K_INT_RXEOL |
-               AR5K_INT_RXORN | AR5K_INT_FATAL | AR5K_INT_GLOBAL;
+               AR5K_INT_RXORN | AR5K_INT_FATAL | AR5K_INT_GLOBAL |
+               AR5K_INT_MIB;
 
        ath5k_hw_set_intr(sc->ah, sc->imask);
        /* Set ack to be sent at low bit-rates */
@@ -2518,7 +2508,11 @@ ath5k_intr(int irq, void *dev_id)
                        if (status & AR5K_INT_BMISS) {
                        }
                        if (status & AR5K_INT_MIB) {
-                               /* TODO */
+                               /*
+                                * These stats are also used for ANI i think
+                                * so how about updating them more often ?
+                                */
+                               ath5k_hw_update_mib_counters(ah, &sc->ll_stats);
                        }
                }
        } while (ath5k_hw_is_intr_pending(ah) && counter-- > 0);
@@ -2900,9 +2894,9 @@ static void ath5k_configure_filter(struct ieee80211_hw *hw,
                        if (!mclist)
                                break;
                        /* calculate XOR of eight 6-bit values */
-                       val = LE_READ_4(mclist->dmi_addr + 0);
+                       val = get_unaligned_le32(mclist->dmi_addr + 0);
                        pos = (val >> 18) ^ (val >> 12) ^ (val >> 6) ^ val;
-                       val = LE_READ_4(mclist->dmi_addr + 3);
+                       val = get_unaligned_le32(mclist->dmi_addr + 3);
                        pos ^= (val >> 18) ^ (val >> 12) ^ (val >> 6) ^ val;
                        pos &= 0x3f;
                        mfilt[pos / 32] |= (1 << (pos % 32));
@@ -3011,6 +3005,10 @@ ath5k_get_stats(struct ieee80211_hw *hw,
                struct ieee80211_low_level_stats *stats)
 {
        struct ath5k_softc *sc = hw->priv;
+       struct ath5k_hw *ah = sc->ah;
+
+       /* Force update */
+       ath5k_hw_update_mib_counters(ah, &sc->ll_stats);
 
        memcpy(stats, &sc->ll_stats, sizeof(sc->ll_stats));