Commit b9fd8a84 authored by Michal Kazior's avatar Michal Kazior Committed by Kalle Valo

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: default avatarMichal Kazior <michal.kazior@tieto.com>
Signed-off-by: default avatarKalle Valo <kvalo@qca.qualcomm.com>
parent f0e2770f
...@@ -629,23 +629,34 @@ static const u8 rx_legacy_rate_idx[] = { ...@@ -629,23 +629,34 @@ static const u8 rx_legacy_rate_idx[] = {
}; };
static void ath10k_htt_rx_h_rates(struct ath10k *ar, static void ath10k_htt_rx_h_rates(struct ath10k *ar,
enum ieee80211_band band, struct ieee80211_rx_status *status,
u8 info0, u32 info1, u32 info2, struct htt_rx_desc *rxd)
struct ieee80211_rx_status *status)
{ {
enum ieee80211_band band;
u8 cck, rate, rate_idx, bw, sgi, mcs, nss; u8 cck, rate, rate_idx, bw, sgi, mcs, nss;
u8 preamble = 0; u8 preamble = 0;
u32 info1, info2, info3;
/* Check if valid fields */ /* Band value can't be set as undefined but freq can be 0 - use that to
if (!(info0 & HTT_RX_INDICATION_INFO0_START_VALID)) * determine whether band is provided.
*
* FIXME: Perhaps this can go away if CCK rate reporting is a little
* reworked?
*/
if (!status->freq)
return; return;
preamble = MS(info1, HTT_RX_INDICATION_INFO1_PREAMBLE_TYPE); band = status->band;
info1 = __le32_to_cpu(rxd->ppdu_start.info1);
info2 = __le32_to_cpu(rxd->ppdu_start.info2);
info3 = __le32_to_cpu(rxd->ppdu_start.info3);
preamble = MS(info1, RX_PPDU_START_INFO1_PREAMBLE_TYPE);
switch (preamble) { switch (preamble) {
case HTT_RX_LEGACY: case HTT_RX_LEGACY:
cck = info0 & HTT_RX_INDICATION_INFO0_LEGACY_RATE_CCK; cck = info1 & RX_PPDU_START_INFO1_L_SIG_RATE_SELECT;
rate = MS(info0, HTT_RX_INDICATION_INFO0_LEGACY_RATE); rate = MS(info1, RX_PPDU_START_INFO1_L_SIG_RATE);
rate_idx = 0; rate_idx = 0;
if (rate < 0x08 || rate > 0x0F) if (rate < 0x08 || rate > 0x0F)
...@@ -672,11 +683,11 @@ static void ath10k_htt_rx_h_rates(struct ath10k *ar, ...@@ -672,11 +683,11 @@ static void ath10k_htt_rx_h_rates(struct ath10k *ar,
break; break;
case HTT_RX_HT: case HTT_RX_HT:
case HTT_RX_HT_WITH_TXBF: case HTT_RX_HT_WITH_TXBF:
/* HT-SIG - Table 20-11 in info1 and info2 */ /* HT-SIG - Table 20-11 in info2 and info3 */
mcs = info1 & 0x1F; mcs = info2 & 0x1F;
nss = mcs >> 3; nss = mcs >> 3;
bw = (info1 >> 7) & 1; bw = (info2 >> 7) & 1;
sgi = (info2 >> 7) & 1; sgi = (info3 >> 7) & 1;
status->rate_idx = mcs; status->rate_idx = mcs;
status->flag |= RX_FLAG_HT; status->flag |= RX_FLAG_HT;
...@@ -687,12 +698,12 @@ static void ath10k_htt_rx_h_rates(struct ath10k *ar, ...@@ -687,12 +698,12 @@ static void ath10k_htt_rx_h_rates(struct ath10k *ar,
break; break;
case HTT_RX_VHT: case HTT_RX_VHT:
case HTT_RX_VHT_WITH_TXBF: case HTT_RX_VHT_WITH_TXBF:
/* VHT-SIG-A1 in info 1, VHT-SIG-A2 in info2 /* VHT-SIG-A1 in info2, VHT-SIG-A2 in info3
TODO check this */ TODO check this */
mcs = (info2 >> 4) & 0x0F; mcs = (info3 >> 4) & 0x0F;
nss = ((info1 >> 10) & 0x07) + 1; nss = ((info2 >> 10) & 0x07) + 1;
bw = info1 & 3; bw = info2 & 3;
sgi = info2 & 1; sgi = info3 & 1;
status->rate_idx = mcs; status->rate_idx = mcs;
status->vht_nss = nss; status->vht_nss = nss;
...@@ -740,6 +751,72 @@ static bool ath10k_htt_rx_h_channel(struct ath10k *ar, ...@@ -740,6 +751,72 @@ static bool ath10k_htt_rx_h_channel(struct ath10k *ar,
return true; return true;
} }
static void ath10k_htt_rx_h_signal(struct ath10k *ar,
struct ieee80211_rx_status *status,
struct htt_rx_desc *rxd)
{
/* FIXME: Get real NF */
status->signal = ATH10K_DEFAULT_NOISE_FLOOR +
rxd->ppdu_start.rssi_comb;
status->flag &= ~RX_FLAG_NO_SIGNAL_VAL;
}
static void ath10k_htt_rx_h_mactime(struct ath10k *ar,
struct ieee80211_rx_status *status,
struct htt_rx_desc *rxd)
{
/* FIXME: TSF is known only at the end of PPDU, in the last MPDU. This
* means all prior MSDUs in a PPDU are reported to mac80211 without the
* TSF. Is it worth holding frames until end of PPDU is known?
*
* FIXME: Can we get/compute 64bit TSF?
*/
status->mactime = __le32_to_cpu(rxd->ppdu_end.tsf_timestamp);
status->flag |= RX_FLAG_MACTIME_END;
}
static void ath10k_htt_rx_h_ppdu(struct ath10k *ar,
struct sk_buff_head *amsdu,
struct ieee80211_rx_status *status)
{
struct sk_buff *first;
struct htt_rx_desc *rxd;
bool is_first_ppdu;
bool is_last_ppdu;
if (skb_queue_empty(amsdu))
return;
first = skb_peek(amsdu);
rxd = (void *)first->data - sizeof(*rxd);
is_first_ppdu = !!(rxd->attention.flags &
__cpu_to_le32(RX_ATTENTION_FLAGS_FIRST_MPDU));
is_last_ppdu = !!(rxd->attention.flags &
__cpu_to_le32(RX_ATTENTION_FLAGS_LAST_MPDU));
if (is_first_ppdu) {
/* New PPDU starts so clear out the old per-PPDU status. */
status->freq = 0;
status->rate_idx = 0;
status->vht_nss = 0;
status->vht_flag &= ~RX_VHT_FLAG_80MHZ;
status->flag &= ~(RX_FLAG_HT |
RX_FLAG_VHT |
RX_FLAG_SHORT_GI |
RX_FLAG_40MHZ |
RX_FLAG_MACTIME_END);
status->flag |= RX_FLAG_NO_SIGNAL_VAL;
ath10k_htt_rx_h_signal(ar, status, rxd);
ath10k_htt_rx_h_channel(ar, status);
ath10k_htt_rx_h_rates(ar, status, rxd);
}
if (is_last_ppdu)
ath10k_htt_rx_h_mactime(ar, status, rxd);
}
static const char * const tid_to_ac[] = { static const char * const tid_to_ac[] = {
"BE", "BE",
"BK", "BK",
...@@ -1358,7 +1435,6 @@ static void ath10k_htt_rx_handler(struct ath10k_htt *htt, ...@@ -1358,7 +1435,6 @@ static void ath10k_htt_rx_handler(struct ath10k_htt *htt,
int num_mpdu_ranges; int num_mpdu_ranges;
int fw_desc_len; int fw_desc_len;
u8 *fw_desc; u8 *fw_desc;
bool channel_set;
int i, ret, mpdu_count = 0; int i, ret, mpdu_count = 0;
lockdep_assert_held(&htt->rx_ring.lock); lockdep_assert_held(&htt->rx_ring.lock);
...@@ -1373,29 +1449,6 @@ static void ath10k_htt_rx_handler(struct ath10k_htt *htt, ...@@ -1373,29 +1449,6 @@ static void ath10k_htt_rx_handler(struct ath10k_htt *htt,
HTT_RX_INDICATION_INFO1_NUM_MPDU_RANGES); HTT_RX_INDICATION_INFO1_NUM_MPDU_RANGES);
mpdu_ranges = htt_rx_ind_get_mpdu_ranges(rx); mpdu_ranges = htt_rx_ind_get_mpdu_ranges(rx);
/* Fill this once, while this is per-ppdu */
if (rx->ppdu.info0 & HTT_RX_INDICATION_INFO0_START_VALID) {
memset(rx_status, 0, sizeof(*rx_status));
rx_status->signal = ATH10K_DEFAULT_NOISE_FLOOR +
rx->ppdu.combined_rssi;
}
if (rx->ppdu.info0 & HTT_RX_INDICATION_INFO0_END_VALID) {
/* TSF available only in 32-bit */
rx_status->mactime = __le32_to_cpu(rx->ppdu.tsf) & 0xffffffff;
rx_status->flag |= RX_FLAG_MACTIME_END;
}
channel_set = ath10k_htt_rx_h_channel(htt->ar, rx_status);
if (channel_set) {
ath10k_htt_rx_h_rates(htt->ar, rx_status->band,
rx->ppdu.info0,
__le32_to_cpu(rx->ppdu.info1),
__le32_to_cpu(rx->ppdu.info2),
rx_status);
}
ath10k_dbg_dump(ar, ATH10K_DBG_HTT_DUMP, NULL, "htt rx ind: ", ath10k_dbg_dump(ar, ATH10K_DBG_HTT_DUMP, NULL, "htt rx ind: ",
rx, sizeof(*rx) + rx, sizeof(*rx) +
(sizeof(struct htt_rx_indication_mpdu_range) * (sizeof(struct htt_rx_indication_mpdu_range) *
...@@ -1418,6 +1471,7 @@ static void ath10k_htt_rx_handler(struct ath10k_htt *htt, ...@@ -1418,6 +1471,7 @@ static void ath10k_htt_rx_handler(struct ath10k_htt *htt,
break; break;
} }
ath10k_htt_rx_h_ppdu(ar, &amsdu, rx_status);
ath10k_htt_rx_h_unchain(ar, &amsdu, ret > 0); ath10k_htt_rx_h_unchain(ar, &amsdu, ret > 0);
ath10k_htt_rx_h_filter(ar, &amsdu, rx_status); ath10k_htt_rx_h_filter(ar, &amsdu, rx_status);
ath10k_htt_rx_h_mpdu(ar, &amsdu, rx_status); ath10k_htt_rx_h_mpdu(ar, &amsdu, rx_status);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment