ath9k: Remove redundant HT macros
[pandora-kernel.git] / drivers / net / wireless / ath / ath9k / recv.c
index 5014a19..61edfab 100644 (file)
@@ -145,6 +145,10 @@ static int ath_rx_prepare(struct sk_buff *skb, struct ath_desc *ds,
        u8 ratecode;
        __le16 fc;
        struct ieee80211_hw *hw;
+       struct ieee80211_sta *sta;
+       struct ath_node *an;
+       int last_rssi = ATH_RSSI_DUMMY_MARKER;
+
 
        hdr = (struct ieee80211_hdr *)skb->data;
        fc = hdr->frame_control;
@@ -229,17 +233,57 @@ static int ath_rx_prepare(struct sk_buff *skb, struct ath_desc *ds,
                }
        }
 
+       rcu_read_lock();
+       sta = ieee80211_find_sta(sc->hw, hdr->addr2);
+       if (sta) {
+               an = (struct ath_node *) sta->drv_priv;
+               if (ds->ds_rxstat.rs_rssi != ATH9K_RSSI_BAD &&
+                  !ds->ds_rxstat.rs_moreaggr)
+                       ATH_RSSI_LPF(an->last_rssi, ds->ds_rxstat.rs_rssi);
+               last_rssi = an->last_rssi;
+       }
+       rcu_read_unlock();
+
+       if (likely(last_rssi != ATH_RSSI_DUMMY_MARKER))
+               ds->ds_rxstat.rs_rssi = ATH_EP_RND(last_rssi,
+                                       ATH_RSSI_EP_MULTIPLIER);
+       if (ds->ds_rxstat.rs_rssi < 0)
+               ds->ds_rxstat.rs_rssi = 0;
+       else if (ds->ds_rxstat.rs_rssi > 127)
+               ds->ds_rxstat.rs_rssi = 127;
+
        rx_status->mactime = ath_extend_tsf(sc, ds->ds_rxstat.rs_tstamp);
        rx_status->band = hw->conf.channel->band;
        rx_status->freq = hw->conf.channel->center_freq;
        rx_status->noise = sc->ani.noise_floor;
-       rx_status->signal = rx_status->noise + ds->ds_rxstat.rs_rssi;
+       rx_status->signal = ATH_DEFAULT_NOISE_FLOOR + ds->ds_rxstat.rs_rssi;
        rx_status->antenna = ds->ds_rxstat.rs_antenna;
 
-       /* at 45 you will be able to use MCS 15 reliably. A more elaborate
-        * scheme can be used here but it requires tables of SNR/throughput for
-        * each possible mode used. */
-       rx_status->qual =  ds->ds_rxstat.rs_rssi * 100 / 45;
+       /*
+        * Theory for reporting quality:
+        *
+        * At a hardware RSSI of 45 you will be able to use MCS 7  reliably.
+        * At a hardware RSSI of 45 you will be able to use MCS 15 reliably.
+        * At a hardware RSSI of 35 you should be able use 54 Mbps reliably.
+        *
+        * MCS 7  is the highets MCS index usable by a 1-stream device.
+        * MCS 15 is the highest MCS index usable by a 2-stream device.
+        *
+        * All ath9k devices are either 1-stream or 2-stream.
+        *
+        * How many bars you see is derived from the qual reporting.
+        *
+        * A more elaborate scheme can be used here but it requires tables
+        * of SNR/throughput for each possible mode used. For the MCS table
+        * you can refer to the wireless wiki:
+        *
+        * http://wireless.kernel.org/en/developers/Documentation/ieee80211/802.11n
+        *
+        */
+       if (conf_is_ht(&hw->conf))
+               rx_status->qual =  ds->ds_rxstat.rs_rssi * 100 / 45;
+       else
+               rx_status->qual =  ds->ds_rxstat.rs_rssi * 100 / 35;
 
        /* rssi can be more than 45 though, anything above that
         * should be considered at 100% */
@@ -505,11 +549,6 @@ static bool ath_beacon_dtim_pending_cab(struct sk_buff *skb)
        return false;
 }
 
-static void ath_rx_ps_back_to_sleep(struct ath_softc *sc)
-{
-       sc->sc_flags &= ~(SC_OP_WAIT_FOR_BEACON | SC_OP_WAIT_FOR_CAB);
-}
-
 static void ath_rx_ps_beacon(struct ath_softc *sc, struct sk_buff *skb)
 {
        struct ieee80211_mgmt *mgmt;
@@ -521,6 +560,8 @@ static void ath_rx_ps_beacon(struct ath_softc *sc, struct sk_buff *skb)
        if (memcmp(sc->curbssid, mgmt->bssid, ETH_ALEN) != 0)
                return; /* not from our current AP */
 
+       sc->sc_flags &= ~SC_OP_WAIT_FOR_BEACON;
+
        if (sc->sc_flags & SC_OP_BEACON_SYNC) {
                sc->sc_flags &= ~SC_OP_BEACON_SYNC;
                DPRINTF(sc, ATH_DBG_PS, "Reconfigure Beacon timers based on "
@@ -528,22 +569,17 @@ static void ath_rx_ps_beacon(struct ath_softc *sc, struct sk_buff *skb)
                ath_beacon_config(sc, NULL);
        }
 
-       if (!(sc->hw->conf.flags & IEEE80211_CONF_PS)) {
-               /* We are not in PS mode anymore; remain awake */
-               DPRINTF(sc, ATH_DBG_PS, "Not in PS mode anymore, remain "
-                       "awake\n");
-               sc->sc_flags &= ~(SC_OP_WAIT_FOR_BEACON | SC_OP_WAIT_FOR_CAB);
-               return;
-       }
-
        if (ath_beacon_dtim_pending_cab(skb)) {
                /*
                 * Remain awake waiting for buffered broadcast/multicast
-                * frames.
+                * frames. If the last broadcast/multicast frame is not
+                * received properly, the next beacon frame will work as
+                * a backup trigger for returning into NETWORK SLEEP state,
+                * so we are waiting for it as well.
                 */
                DPRINTF(sc, ATH_DBG_PS, "Received DTIM beacon indicating "
                        "buffered broadcast/multicast frame(s)\n");
-               sc->sc_flags |= SC_OP_WAIT_FOR_CAB;
+               sc->sc_flags |= SC_OP_WAIT_FOR_CAB | SC_OP_WAIT_FOR_BEACON;
                return;
        }
 
@@ -553,11 +589,9 @@ static void ath_rx_ps_beacon(struct ath_softc *sc, struct sk_buff *skb)
                 * fails to send a frame indicating that all CAB frames have
                 * been delivered.
                 */
+               sc->sc_flags &= ~SC_OP_WAIT_FOR_CAB;
                DPRINTF(sc, ATH_DBG_PS, "PS wait for CAB frames timed out\n");
        }
-
-       /* No more broadcast/multicast frames to be received at this point. */
-       ath_rx_ps_back_to_sleep(sc);
 }
 
 static void ath_rx_ps(struct ath_softc *sc, struct sk_buff *skb)
@@ -575,13 +609,13 @@ static void ath_rx_ps(struct ath_softc *sc, struct sk_buff *skb)
                  ieee80211_is_action(hdr->frame_control)) &&
                 is_multicast_ether_addr(hdr->addr1) &&
                 !ieee80211_has_moredata(hdr->frame_control)) {
-               DPRINTF(sc, ATH_DBG_PS, "All PS CAB frames received, back to "
-                       "sleep\n");
                /*
                 * No more broadcast/multicast frames to be received at this
                 * point.
                 */
-               ath_rx_ps_back_to_sleep(sc);
+               sc->sc_flags &= ~SC_OP_WAIT_FOR_CAB;
+               DPRINTF(sc, ATH_DBG_PS, "All PS CAB frames received, back to "
+                       "sleep\n");
        } else if ((sc->sc_flags & SC_OP_WAIT_FOR_PSPOLL_DATA) &&
                   !is_multicast_ether_addr(hdr->addr1) &&
                   !ieee80211_has_morefrags(hdr->frame_control)) {
@@ -616,13 +650,18 @@ static void ath_rx_send_to_mac80211(struct ath_softc *sc, struct sk_buff *skb,
                        if (aphy == NULL)
                                continue;
                        nskb = skb_copy(skb, GFP_ATOMIC);
-                       if (nskb)
-                               __ieee80211_rx(aphy->hw, nskb, rx_status);
+                       if (nskb) {
+                               memcpy(IEEE80211_SKB_RXCB(nskb), rx_status,
+                                       sizeof(*rx_status));
+                               ieee80211_rx(aphy->hw, nskb);
+                       }
                }
-               __ieee80211_rx(sc->hw, skb, rx_status);
+               memcpy(IEEE80211_SKB_RXCB(skb), rx_status, sizeof(*rx_status));
+               ieee80211_rx(sc->hw, skb);
        } else {
                /* Deliver unicast frames based on receiver address */
-               __ieee80211_rx(ath_get_virt_hw(sc, hdr), skb, rx_status);
+               memcpy(IEEE80211_SKB_RXCB(skb), rx_status, sizeof(*rx_status));
+               ieee80211_rx(ath_get_virt_hw(sc, hdr), skb);
        }
 }
 
@@ -817,6 +856,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
                }
 
                if (unlikely(sc->sc_flags & (SC_OP_WAIT_FOR_BEACON |
+                                            SC_OP_WAIT_FOR_CAB |
                                             SC_OP_WAIT_FOR_PSPOLL_DATA)))
                        ath_rx_ps(sc, skb);