aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath/ath9k/recv.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/ath/ath9k/recv.c')
-rw-r--r--drivers/net/wireless/ath/ath9k/recv.c92
1 files changed, 64 insertions, 28 deletions
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c
index cece1c4c6bda..61edfab20ffc 100644
--- a/drivers/net/wireless/ath/ath9k/recv.c
+++ b/drivers/net/wireless/ath/ath9k/recv.c
@@ -145,6 +145,10 @@ static int ath_rx_prepare(struct sk_buff *skb, struct ath_desc *ds,
145 u8 ratecode; 145 u8 ratecode;
146 __le16 fc; 146 __le16 fc;
147 struct ieee80211_hw *hw; 147 struct ieee80211_hw *hw;
148 struct ieee80211_sta *sta;
149 struct ath_node *an;
150 int last_rssi = ATH_RSSI_DUMMY_MARKER;
151
148 152
149 hdr = (struct ieee80211_hdr *)skb->data; 153 hdr = (struct ieee80211_hdr *)skb->data;
150 fc = hdr->frame_control; 154 fc = hdr->frame_control;
@@ -229,17 +233,57 @@ static int ath_rx_prepare(struct sk_buff *skb, struct ath_desc *ds,
229 } 233 }
230 } 234 }
231 235
236 rcu_read_lock();
237 sta = ieee80211_find_sta(sc->hw, hdr->addr2);
238 if (sta) {
239 an = (struct ath_node *) sta->drv_priv;
240 if (ds->ds_rxstat.rs_rssi != ATH9K_RSSI_BAD &&
241 !ds->ds_rxstat.rs_moreaggr)
242 ATH_RSSI_LPF(an->last_rssi, ds->ds_rxstat.rs_rssi);
243 last_rssi = an->last_rssi;
244 }
245 rcu_read_unlock();
246
247 if (likely(last_rssi != ATH_RSSI_DUMMY_MARKER))
248 ds->ds_rxstat.rs_rssi = ATH_EP_RND(last_rssi,
249 ATH_RSSI_EP_MULTIPLIER);
250 if (ds->ds_rxstat.rs_rssi < 0)
251 ds->ds_rxstat.rs_rssi = 0;
252 else if (ds->ds_rxstat.rs_rssi > 127)
253 ds->ds_rxstat.rs_rssi = 127;
254
232 rx_status->mactime = ath_extend_tsf(sc, ds->ds_rxstat.rs_tstamp); 255 rx_status->mactime = ath_extend_tsf(sc, ds->ds_rxstat.rs_tstamp);
233 rx_status->band = hw->conf.channel->band; 256 rx_status->band = hw->conf.channel->band;
234 rx_status->freq = hw->conf.channel->center_freq; 257 rx_status->freq = hw->conf.channel->center_freq;
235 rx_status->noise = sc->ani.noise_floor; 258 rx_status->noise = sc->ani.noise_floor;
236 rx_status->signal = rx_status->noise + ds->ds_rxstat.rs_rssi; 259 rx_status->signal = ATH_DEFAULT_NOISE_FLOOR + ds->ds_rxstat.rs_rssi;
237 rx_status->antenna = ds->ds_rxstat.rs_antenna; 260 rx_status->antenna = ds->ds_rxstat.rs_antenna;
238 261
239 /* at 45 you will be able to use MCS 15 reliably. A more elaborate 262 /*
240 * scheme can be used here but it requires tables of SNR/throughput for 263 * Theory for reporting quality:
241 * each possible mode used. */ 264 *
242 rx_status->qual = ds->ds_rxstat.rs_rssi * 100 / 45; 265 * At a hardware RSSI of 45 you will be able to use MCS 7 reliably.
266 * At a hardware RSSI of 45 you will be able to use MCS 15 reliably.
267 * At a hardware RSSI of 35 you should be able use 54 Mbps reliably.
268 *
269 * MCS 7 is the highets MCS index usable by a 1-stream device.
270 * MCS 15 is the highest MCS index usable by a 2-stream device.
271 *
272 * All ath9k devices are either 1-stream or 2-stream.
273 *
274 * How many bars you see is derived from the qual reporting.
275 *
276 * A more elaborate scheme can be used here but it requires tables
277 * of SNR/throughput for each possible mode used. For the MCS table
278 * you can refer to the wireless wiki:
279 *
280 * http://wireless.kernel.org/en/developers/Documentation/ieee80211/802.11n
281 *
282 */
283 if (conf_is_ht(&hw->conf))
284 rx_status->qual = ds->ds_rxstat.rs_rssi * 100 / 45;
285 else
286 rx_status->qual = ds->ds_rxstat.rs_rssi * 100 / 35;
243 287
244 /* rssi can be more than 45 though, anything above that 288 /* rssi can be more than 45 though, anything above that
245 * should be considered at 100% */ 289 * should be considered at 100% */
@@ -505,11 +549,6 @@ static bool ath_beacon_dtim_pending_cab(struct sk_buff *skb)
505 return false; 549 return false;
506} 550}
507 551
508static void ath_rx_ps_back_to_sleep(struct ath_softc *sc)
509{
510 sc->sc_flags &= ~(SC_OP_WAIT_FOR_BEACON | SC_OP_WAIT_FOR_CAB);
511}
512
513static void ath_rx_ps_beacon(struct ath_softc *sc, struct sk_buff *skb) 552static void ath_rx_ps_beacon(struct ath_softc *sc, struct sk_buff *skb)
514{ 553{
515 struct ieee80211_mgmt *mgmt; 554 struct ieee80211_mgmt *mgmt;
@@ -521,6 +560,8 @@ static void ath_rx_ps_beacon(struct ath_softc *sc, struct sk_buff *skb)
521 if (memcmp(sc->curbssid, mgmt->bssid, ETH_ALEN) != 0) 560 if (memcmp(sc->curbssid, mgmt->bssid, ETH_ALEN) != 0)
522 return; /* not from our current AP */ 561 return; /* not from our current AP */
523 562
563 sc->sc_flags &= ~SC_OP_WAIT_FOR_BEACON;
564
524 if (sc->sc_flags & SC_OP_BEACON_SYNC) { 565 if (sc->sc_flags & SC_OP_BEACON_SYNC) {
525 sc->sc_flags &= ~SC_OP_BEACON_SYNC; 566 sc->sc_flags &= ~SC_OP_BEACON_SYNC;
526 DPRINTF(sc, ATH_DBG_PS, "Reconfigure Beacon timers based on " 567 DPRINTF(sc, ATH_DBG_PS, "Reconfigure Beacon timers based on "
@@ -528,14 +569,6 @@ static void ath_rx_ps_beacon(struct ath_softc *sc, struct sk_buff *skb)
528 ath_beacon_config(sc, NULL); 569 ath_beacon_config(sc, NULL);
529 } 570 }
530 571
531 if (!(sc->hw->conf.flags & IEEE80211_CONF_PS)) {
532 /* We are not in PS mode anymore; remain awake */
533 DPRINTF(sc, ATH_DBG_PS, "Not in PS mode anymore, remain "
534 "awake\n");
535 sc->sc_flags &= ~(SC_OP_WAIT_FOR_BEACON | SC_OP_WAIT_FOR_CAB);
536 return;
537 }
538
539 if (ath_beacon_dtim_pending_cab(skb)) { 572 if (ath_beacon_dtim_pending_cab(skb)) {
540 /* 573 /*
541 * Remain awake waiting for buffered broadcast/multicast 574 * Remain awake waiting for buffered broadcast/multicast
@@ -556,11 +589,9 @@ static void ath_rx_ps_beacon(struct ath_softc *sc, struct sk_buff *skb)
556 * fails to send a frame indicating that all CAB frames have 589 * fails to send a frame indicating that all CAB frames have
557 * been delivered. 590 * been delivered.
558 */ 591 */
592 sc->sc_flags &= ~SC_OP_WAIT_FOR_CAB;
559 DPRINTF(sc, ATH_DBG_PS, "PS wait for CAB frames timed out\n"); 593 DPRINTF(sc, ATH_DBG_PS, "PS wait for CAB frames timed out\n");
560 } 594 }
561
562 /* No more broadcast/multicast frames to be received at this point. */
563 ath_rx_ps_back_to_sleep(sc);
564} 595}
565 596
566static void ath_rx_ps(struct ath_softc *sc, struct sk_buff *skb) 597static void ath_rx_ps(struct ath_softc *sc, struct sk_buff *skb)
@@ -578,13 +609,13 @@ static void ath_rx_ps(struct ath_softc *sc, struct sk_buff *skb)
578 ieee80211_is_action(hdr->frame_control)) && 609 ieee80211_is_action(hdr->frame_control)) &&
579 is_multicast_ether_addr(hdr->addr1) && 610 is_multicast_ether_addr(hdr->addr1) &&
580 !ieee80211_has_moredata(hdr->frame_control)) { 611 !ieee80211_has_moredata(hdr->frame_control)) {
581 DPRINTF(sc, ATH_DBG_PS, "All PS CAB frames received, back to "
582 "sleep\n");
583 /* 612 /*
584 * No more broadcast/multicast frames to be received at this 613 * No more broadcast/multicast frames to be received at this
585 * point. 614 * point.
586 */ 615 */
587 ath_rx_ps_back_to_sleep(sc); 616 sc->sc_flags &= ~SC_OP_WAIT_FOR_CAB;
617 DPRINTF(sc, ATH_DBG_PS, "All PS CAB frames received, back to "
618 "sleep\n");
588 } else if ((sc->sc_flags & SC_OP_WAIT_FOR_PSPOLL_DATA) && 619 } else if ((sc->sc_flags & SC_OP_WAIT_FOR_PSPOLL_DATA) &&
589 !is_multicast_ether_addr(hdr->addr1) && 620 !is_multicast_ether_addr(hdr->addr1) &&
590 !ieee80211_has_morefrags(hdr->frame_control)) { 621 !ieee80211_has_morefrags(hdr->frame_control)) {
@@ -619,13 +650,18 @@ static void ath_rx_send_to_mac80211(struct ath_softc *sc, struct sk_buff *skb,
619 if (aphy == NULL) 650 if (aphy == NULL)
620 continue; 651 continue;
621 nskb = skb_copy(skb, GFP_ATOMIC); 652 nskb = skb_copy(skb, GFP_ATOMIC);
622 if (nskb) 653 if (nskb) {
623 __ieee80211_rx(aphy->hw, nskb, rx_status); 654 memcpy(IEEE80211_SKB_RXCB(nskb), rx_status,
655 sizeof(*rx_status));
656 ieee80211_rx(aphy->hw, nskb);
657 }
624 } 658 }
625 __ieee80211_rx(sc->hw, skb, rx_status); 659 memcpy(IEEE80211_SKB_RXCB(skb), rx_status, sizeof(*rx_status));
660 ieee80211_rx(sc->hw, skb);
626 } else { 661 } else {
627 /* Deliver unicast frames based on receiver address */ 662 /* Deliver unicast frames based on receiver address */
628 __ieee80211_rx(ath_get_virt_hw(sc, hdr), skb, rx_status); 663 memcpy(IEEE80211_SKB_RXCB(skb), rx_status, sizeof(*rx_status));
664 ieee80211_rx(ath_get_virt_hw(sc, hdr), skb);
629 } 665 }
630} 666}
631 667