aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichal Kazior <michal.kazior@tieto.com>2014-11-18 02:24:49 -0500
committerKalle Valo <kvalo@qca.qualcomm.com>2014-11-20 08:43:59 -0500
commitb9fd8a8420fe9c20fc639f7abd6561661f2ecd3e (patch)
tree3004681f6e14f32429244a75a00b34011a652319
parentf0e2770ff75efb6353a73321271d80e4529ff3ab (diff)
ath10k: use rx descriptor for ppdu status extraction
This makes it more in line with the new Rx path. It also makes the code more reusable because Rx descriptor is more accessible. Signed-off-by: Michal Kazior <michal.kazior@tieto.com> Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
-rw-r--r--drivers/net/wireless/ath/ath10k/htt_rx.c136
1 files changed, 95 insertions, 41 deletions
diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c b/drivers/net/wireless/ath/ath10k/htt_rx.c
index 332abc751c18..3d503b0057f0 100644
--- a/drivers/net/wireless/ath/ath10k/htt_rx.c
+++ b/drivers/net/wireless/ath/ath10k/htt_rx.c
@@ -629,23 +629,34 @@ static const u8 rx_legacy_rate_idx[] = {
629}; 629};
630 630
631static void ath10k_htt_rx_h_rates(struct ath10k *ar, 631static void ath10k_htt_rx_h_rates(struct ath10k *ar,
632 enum ieee80211_band band, 632 struct ieee80211_rx_status *status,
633 u8 info0, u32 info1, u32 info2, 633 struct htt_rx_desc *rxd)
634 struct ieee80211_rx_status *status)
635{ 634{
635 enum ieee80211_band band;
636 u8 cck, rate, rate_idx, bw, sgi, mcs, nss; 636 u8 cck, rate, rate_idx, bw, sgi, mcs, nss;
637 u8 preamble = 0; 637 u8 preamble = 0;
638 u32 info1, info2, info3;
638 639
639 /* Check if valid fields */ 640 /* Band value can't be set as undefined but freq can be 0 - use that to
640 if (!(info0 & HTT_RX_INDICATION_INFO0_START_VALID)) 641 * determine whether band is provided.
642 *
643 * FIXME: Perhaps this can go away if CCK rate reporting is a little
644 * reworked?
645 */
646 if (!status->freq)
641 return; 647 return;
642 648
643 preamble = MS(info1, HTT_RX_INDICATION_INFO1_PREAMBLE_TYPE); 649 band = status->band;
650 info1 = __le32_to_cpu(rxd->ppdu_start.info1);
651 info2 = __le32_to_cpu(rxd->ppdu_start.info2);
652 info3 = __le32_to_cpu(rxd->ppdu_start.info3);
653
654 preamble = MS(info1, RX_PPDU_START_INFO1_PREAMBLE_TYPE);
644 655
645 switch (preamble) { 656 switch (preamble) {
646 case HTT_RX_LEGACY: 657 case HTT_RX_LEGACY:
647 cck = info0 & HTT_RX_INDICATION_INFO0_LEGACY_RATE_CCK; 658 cck = info1 & RX_PPDU_START_INFO1_L_SIG_RATE_SELECT;
648 rate = MS(info0, HTT_RX_INDICATION_INFO0_LEGACY_RATE); 659 rate = MS(info1, RX_PPDU_START_INFO1_L_SIG_RATE);
649 rate_idx = 0; 660 rate_idx = 0;
650 661
651 if (rate < 0x08 || rate > 0x0F) 662 if (rate < 0x08 || rate > 0x0F)
@@ -672,11 +683,11 @@ static void ath10k_htt_rx_h_rates(struct ath10k *ar,
672 break; 683 break;
673 case HTT_RX_HT: 684 case HTT_RX_HT:
674 case HTT_RX_HT_WITH_TXBF: 685 case HTT_RX_HT_WITH_TXBF:
675 /* HT-SIG - Table 20-11 in info1 and info2 */ 686 /* HT-SIG - Table 20-11 in info2 and info3 */
676 mcs = info1 & 0x1F; 687 mcs = info2 & 0x1F;
677 nss = mcs >> 3; 688 nss = mcs >> 3;
678 bw = (info1 >> 7) & 1; 689 bw = (info2 >> 7) & 1;
679 sgi = (info2 >> 7) & 1; 690 sgi = (info3 >> 7) & 1;
680 691
681 status->rate_idx = mcs; 692 status->rate_idx = mcs;
682 status->flag |= RX_FLAG_HT; 693 status->flag |= RX_FLAG_HT;
@@ -687,12 +698,12 @@ static void ath10k_htt_rx_h_rates(struct ath10k *ar,
687 break; 698 break;
688 case HTT_RX_VHT: 699 case HTT_RX_VHT:
689 case HTT_RX_VHT_WITH_TXBF: 700 case HTT_RX_VHT_WITH_TXBF:
690 /* VHT-SIG-A1 in info 1, VHT-SIG-A2 in info2 701 /* VHT-SIG-A1 in info2, VHT-SIG-A2 in info3
691 TODO check this */ 702 TODO check this */
692 mcs = (info2 >> 4) & 0x0F; 703 mcs = (info3 >> 4) & 0x0F;
693 nss = ((info1 >> 10) & 0x07) + 1; 704 nss = ((info2 >> 10) & 0x07) + 1;
694 bw = info1 & 3; 705 bw = info2 & 3;
695 sgi = info2 & 1; 706 sgi = info3 & 1;
696 707
697 status->rate_idx = mcs; 708 status->rate_idx = mcs;
698 status->vht_nss = nss; 709 status->vht_nss = nss;
@@ -740,6 +751,72 @@ static bool ath10k_htt_rx_h_channel(struct ath10k *ar,
740 return true; 751 return true;
741} 752}
742 753
754static void ath10k_htt_rx_h_signal(struct ath10k *ar,
755 struct ieee80211_rx_status *status,
756 struct htt_rx_desc *rxd)
757{
758 /* FIXME: Get real NF */
759 status->signal = ATH10K_DEFAULT_NOISE_FLOOR +
760 rxd->ppdu_start.rssi_comb;
761 status->flag &= ~RX_FLAG_NO_SIGNAL_VAL;
762}
763
764static void ath10k_htt_rx_h_mactime(struct ath10k *ar,
765 struct ieee80211_rx_status *status,
766 struct htt_rx_desc *rxd)
767{
768 /* FIXME: TSF is known only at the end of PPDU, in the last MPDU. This
769 * means all prior MSDUs in a PPDU are reported to mac80211 without the
770 * TSF. Is it worth holding frames until end of PPDU is known?
771 *
772 * FIXME: Can we get/compute 64bit TSF?
773 */
774 status->mactime = __le32_to_cpu(rxd->ppdu_end.tsf_timestamp);
775 status->flag |= RX_FLAG_MACTIME_END;
776}
777
778static void ath10k_htt_rx_h_ppdu(struct ath10k *ar,
779 struct sk_buff_head *amsdu,
780 struct ieee80211_rx_status *status)
781{
782 struct sk_buff *first;
783 struct htt_rx_desc *rxd;
784 bool is_first_ppdu;
785 bool is_last_ppdu;
786
787 if (skb_queue_empty(amsdu))
788 return;
789
790 first = skb_peek(amsdu);
791 rxd = (void *)first->data - sizeof(*rxd);
792
793 is_first_ppdu = !!(rxd->attention.flags &
794 __cpu_to_le32(RX_ATTENTION_FLAGS_FIRST_MPDU));
795 is_last_ppdu = !!(rxd->attention.flags &
796 __cpu_to_le32(RX_ATTENTION_FLAGS_LAST_MPDU));
797
798 if (is_first_ppdu) {
799 /* New PPDU starts so clear out the old per-PPDU status. */
800 status->freq = 0;
801 status->rate_idx = 0;
802 status->vht_nss = 0;
803 status->vht_flag &= ~RX_VHT_FLAG_80MHZ;
804 status->flag &= ~(RX_FLAG_HT |
805 RX_FLAG_VHT |
806 RX_FLAG_SHORT_GI |
807 RX_FLAG_40MHZ |
808 RX_FLAG_MACTIME_END);
809 status->flag |= RX_FLAG_NO_SIGNAL_VAL;
810
811 ath10k_htt_rx_h_signal(ar, status, rxd);
812 ath10k_htt_rx_h_channel(ar, status);
813 ath10k_htt_rx_h_rates(ar, status, rxd);
814 }
815
816 if (is_last_ppdu)
817 ath10k_htt_rx_h_mactime(ar, status, rxd);
818}
819
743static const char * const tid_to_ac[] = { 820static const char * const tid_to_ac[] = {
744 "BE", 821 "BE",
745 "BK", 822 "BK",
@@ -1358,7 +1435,6 @@ static void ath10k_htt_rx_handler(struct ath10k_htt *htt,
1358 int num_mpdu_ranges; 1435 int num_mpdu_ranges;
1359 int fw_desc_len; 1436 int fw_desc_len;
1360 u8 *fw_desc; 1437 u8 *fw_desc;
1361 bool channel_set;
1362 int i, ret, mpdu_count = 0; 1438 int i, ret, mpdu_count = 0;
1363 1439
1364 lockdep_assert_held(&htt->rx_ring.lock); 1440 lockdep_assert_held(&htt->rx_ring.lock);
@@ -1373,29 +1449,6 @@ static void ath10k_htt_rx_handler(struct ath10k_htt *htt,
1373 HTT_RX_INDICATION_INFO1_NUM_MPDU_RANGES); 1449 HTT_RX_INDICATION_INFO1_NUM_MPDU_RANGES);
1374 mpdu_ranges = htt_rx_ind_get_mpdu_ranges(rx); 1450 mpdu_ranges = htt_rx_ind_get_mpdu_ranges(rx);
1375 1451
1376 /* Fill this once, while this is per-ppdu */
1377 if (rx->ppdu.info0 & HTT_RX_INDICATION_INFO0_START_VALID) {
1378 memset(rx_status, 0, sizeof(*rx_status));
1379 rx_status->signal = ATH10K_DEFAULT_NOISE_FLOOR +
1380 rx->ppdu.combined_rssi;
1381 }
1382
1383 if (rx->ppdu.info0 & HTT_RX_INDICATION_INFO0_END_VALID) {
1384 /* TSF available only in 32-bit */
1385 rx_status->mactime = __le32_to_cpu(rx->ppdu.tsf) & 0xffffffff;
1386 rx_status->flag |= RX_FLAG_MACTIME_END;
1387 }
1388
1389 channel_set = ath10k_htt_rx_h_channel(htt->ar, rx_status);
1390
1391 if (channel_set) {
1392 ath10k_htt_rx_h_rates(htt->ar, rx_status->band,
1393 rx->ppdu.info0,
1394 __le32_to_cpu(rx->ppdu.info1),
1395 __le32_to_cpu(rx->ppdu.info2),
1396 rx_status);
1397 }
1398
1399 ath10k_dbg_dump(ar, ATH10K_DBG_HTT_DUMP, NULL, "htt rx ind: ", 1452 ath10k_dbg_dump(ar, ATH10K_DBG_HTT_DUMP, NULL, "htt rx ind: ",
1400 rx, sizeof(*rx) + 1453 rx, sizeof(*rx) +
1401 (sizeof(struct htt_rx_indication_mpdu_range) * 1454 (sizeof(struct htt_rx_indication_mpdu_range) *
@@ -1418,6 +1471,7 @@ static void ath10k_htt_rx_handler(struct ath10k_htt *htt,
1418 break; 1471 break;
1419 } 1472 }
1420 1473
1474 ath10k_htt_rx_h_ppdu(ar, &amsdu, rx_status);
1421 ath10k_htt_rx_h_unchain(ar, &amsdu, ret > 0); 1475 ath10k_htt_rx_h_unchain(ar, &amsdu, ret > 0);
1422 ath10k_htt_rx_h_filter(ar, &amsdu, rx_status); 1476 ath10k_htt_rx_h_filter(ar, &amsdu, rx_status);
1423 ath10k_htt_rx_h_mpdu(ar, &amsdu, rx_status); 1477 ath10k_htt_rx_h_mpdu(ar, &amsdu, rx_status);