2014-03-19 08:49:33

by Janusz Dziedzic

[permalink] [raw]
Subject: [RFC v2 1/8] ath10k: move rx related functions to htt_rx.c

No functional changes.

Signed-off-by: Janusz Dziedzic <[email protected]>
---
drivers/net/wireless/ath/ath10k/htt_rx.c | 183 ++++++++++++++++++++++++++++++
drivers/net/wireless/ath/ath10k/txrx.c | 183 ------------------------------
drivers/net/wireless/ath/ath10k/txrx.h | 1 -
3 files changed, 183 insertions(+), 184 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c b/drivers/net/wireless/ath/ath10k/htt_rx.c
index a407d98..c07fc8f 100644
--- a/drivers/net/wireless/ath/ath10k/htt_rx.c
+++ b/drivers/net/wireless/ath/ath10k/htt_rx.c
@@ -636,6 +636,189 @@ struct amsdu_subframe_hdr {
__be16 len;
} __packed;

+static const u8 rx_legacy_rate_idx[] = {
+ 3, /* 0x00 - 11Mbps */
+ 2, /* 0x01 - 5.5Mbps */
+ 1, /* 0x02 - 2Mbps */
+ 0, /* 0x03 - 1Mbps */
+ 3, /* 0x04 - 11Mbps */
+ 2, /* 0x05 - 5.5Mbps */
+ 1, /* 0x06 - 2Mbps */
+ 0, /* 0x07 - 1Mbps */
+ 10, /* 0x08 - 48Mbps */
+ 8, /* 0x09 - 24Mbps */
+ 6, /* 0x0A - 12Mbps */
+ 4, /* 0x0B - 6Mbps */
+ 11, /* 0x0C - 54Mbps */
+ 9, /* 0x0D - 36Mbps */
+ 7, /* 0x0E - 18Mbps */
+ 5, /* 0x0F - 9Mbps */
+};
+
+static void process_rx_rates(struct ath10k *ar, struct htt_rx_info *info,
+ enum ieee80211_band band,
+ struct ieee80211_rx_status *status)
+{
+ u8 cck, rate, rate_idx, bw, sgi, mcs, nss;
+ u8 info0 = info->rate.info0;
+ u32 info1 = info->rate.info1;
+ u32 info2 = info->rate.info2;
+ u8 preamble = 0;
+
+ /* Check if valid fields */
+ if (!(info0 & HTT_RX_INDICATION_INFO0_START_VALID))
+ return;
+
+ preamble = MS(info1, HTT_RX_INDICATION_INFO1_PREAMBLE_TYPE);
+
+ switch (preamble) {
+ case HTT_RX_LEGACY:
+ cck = info0 & HTT_RX_INDICATION_INFO0_LEGACY_RATE_CCK;
+ rate = MS(info0, HTT_RX_INDICATION_INFO0_LEGACY_RATE);
+ rate_idx = 0;
+
+ if (rate < 0x08 || rate > 0x0F)
+ break;
+
+ switch (band) {
+ case IEEE80211_BAND_2GHZ:
+ if (cck)
+ rate &= ~BIT(3);
+ rate_idx = rx_legacy_rate_idx[rate];
+ break;
+ case IEEE80211_BAND_5GHZ:
+ rate_idx = rx_legacy_rate_idx[rate];
+ /* We are using same rate table registering
+ HW - ath10k_rates[]. In case of 5GHz skip
+ CCK rates, so -4 here */
+ rate_idx -= 4;
+ break;
+ default:
+ break;
+ }
+
+ status->rate_idx = rate_idx;
+ break;
+ case HTT_RX_HT:
+ case HTT_RX_HT_WITH_TXBF:
+ /* HT-SIG - Table 20-11 in info1 and info2 */
+ mcs = info1 & 0x1F;
+ nss = mcs >> 3;
+ bw = (info1 >> 7) & 1;
+ sgi = (info2 >> 7) & 1;
+
+ status->rate_idx = mcs;
+ status->flag |= RX_FLAG_HT;
+ if (sgi)
+ status->flag |= RX_FLAG_SHORT_GI;
+ if (bw)
+ status->flag |= RX_FLAG_40MHZ;
+ break;
+ case HTT_RX_VHT:
+ case HTT_RX_VHT_WITH_TXBF:
+ /* VHT-SIG-A1 in info 1, VHT-SIG-A2 in info2
+ TODO check this */
+ mcs = (info2 >> 4) & 0x0F;
+ nss = ((info1 >> 10) & 0x07) + 1;
+ bw = info1 & 3;
+ sgi = info2 & 1;
+
+ status->rate_idx = mcs;
+ status->vht_nss = nss;
+
+ if (sgi)
+ status->flag |= RX_FLAG_SHORT_GI;
+
+ switch (bw) {
+ /* 20MHZ */
+ case 0:
+ break;
+ /* 40MHZ */
+ case 1:
+ status->flag |= RX_FLAG_40MHZ;
+ break;
+ /* 80MHZ */
+ case 2:
+ status->vht_flag |= RX_VHT_FLAG_80MHZ;
+ }
+
+ status->flag |= RX_FLAG_VHT;
+ break;
+ default:
+ break;
+ }
+}
+
+static void ath10k_process_rx(struct ath10k *ar, struct htt_rx_info *info)
+{
+ struct ieee80211_rx_status *status;
+ struct ieee80211_channel *ch;
+ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)info->skb->data;
+
+ status = IEEE80211_SKB_RXCB(info->skb);
+ memset(status, 0, sizeof(*status));
+
+ if (info->encrypt_type != HTT_RX_MPDU_ENCRYPT_NONE) {
+ status->flag |= RX_FLAG_DECRYPTED | RX_FLAG_IV_STRIPPED |
+ RX_FLAG_MMIC_STRIPPED;
+ hdr->frame_control = __cpu_to_le16(
+ __le16_to_cpu(hdr->frame_control) &
+ ~IEEE80211_FCTL_PROTECTED);
+ }
+
+ if (info->mic_err)
+ status->flag |= RX_FLAG_MMIC_ERROR;
+
+ if (info->fcs_err)
+ status->flag |= RX_FLAG_FAILED_FCS_CRC;
+
+ if (info->amsdu_more)
+ status->flag |= RX_FLAG_AMSDU_MORE;
+
+ status->signal = info->signal;
+
+ spin_lock_bh(&ar->data_lock);
+ ch = ar->scan_channel;
+ if (!ch)
+ ch = ar->rx_channel;
+ spin_unlock_bh(&ar->data_lock);
+
+ if (!ch) {
+ ath10k_warn("no channel configured; ignoring frame!\n");
+ dev_kfree_skb_any(info->skb);
+ return;
+ }
+
+ process_rx_rates(ar, info, ch->band, status);
+ status->band = ch->band;
+ status->freq = ch->center_freq;
+
+ if (info->rate.info0 & HTT_RX_INDICATION_INFO0_END_VALID) {
+ /* TSF available only in 32-bit */
+ status->mactime = info->tsf & 0xffffffff;
+ status->flag |= RX_FLAG_MACTIME_END;
+ }
+
+ ath10k_dbg(ATH10K_DBG_DATA,
+ "rx skb %p len %u %s%s%s%s%s %srate_idx %u vht_nss %u freq %u band %u flag 0x%x fcs-err %i\n",
+ info->skb,
+ info->skb->len,
+ status->flag == 0 ? "legacy" : "",
+ status->flag & RX_FLAG_HT ? "ht" : "",
+ status->flag & RX_FLAG_VHT ? "vht" : "",
+ status->flag & RX_FLAG_40MHZ ? "40" : "",
+ status->vht_flag & RX_VHT_FLAG_80MHZ ? "80" : "",
+ status->flag & RX_FLAG_SHORT_GI ? "sgi " : "",
+ status->rate_idx,
+ status->vht_nss,
+ status->freq,
+ status->band, status->flag, info->fcs_err);
+ ath10k_dbg_dump(ATH10K_DBG_HTT_DUMP, NULL, "rx skb: ",
+ info->skb->data, info->skb->len);
+
+ ieee80211_rx(ar->hw, info->skb);
+}
+
static int ath10k_htt_rx_nwifi_hdrlen(struct ieee80211_hdr *hdr)
{
/* nwifi header is padded to 4 bytes. this fixes 4addr rx */
diff --git a/drivers/net/wireless/ath/ath10k/txrx.c b/drivers/net/wireless/ath/ath10k/txrx.c
index 0541dd9..82669a7 100644
--- a/drivers/net/wireless/ath/ath10k/txrx.c
+++ b/drivers/net/wireless/ath/ath10k/txrx.c
@@ -100,189 +100,6 @@ exit:
wake_up(&htt->empty_tx_wq);
}

-static const u8 rx_legacy_rate_idx[] = {
- 3, /* 0x00 - 11Mbps */
- 2, /* 0x01 - 5.5Mbps */
- 1, /* 0x02 - 2Mbps */
- 0, /* 0x03 - 1Mbps */
- 3, /* 0x04 - 11Mbps */
- 2, /* 0x05 - 5.5Mbps */
- 1, /* 0x06 - 2Mbps */
- 0, /* 0x07 - 1Mbps */
- 10, /* 0x08 - 48Mbps */
- 8, /* 0x09 - 24Mbps */
- 6, /* 0x0A - 12Mbps */
- 4, /* 0x0B - 6Mbps */
- 11, /* 0x0C - 54Mbps */
- 9, /* 0x0D - 36Mbps */
- 7, /* 0x0E - 18Mbps */
- 5, /* 0x0F - 9Mbps */
-};
-
-static void process_rx_rates(struct ath10k *ar, struct htt_rx_info *info,
- enum ieee80211_band band,
- struct ieee80211_rx_status *status)
-{
- u8 cck, rate, rate_idx, bw, sgi, mcs, nss;
- u8 info0 = info->rate.info0;
- u32 info1 = info->rate.info1;
- u32 info2 = info->rate.info2;
- u8 preamble = 0;
-
- /* Check if valid fields */
- if (!(info0 & HTT_RX_INDICATION_INFO0_START_VALID))
- return;
-
- preamble = MS(info1, HTT_RX_INDICATION_INFO1_PREAMBLE_TYPE);
-
- switch (preamble) {
- case HTT_RX_LEGACY:
- cck = info0 & HTT_RX_INDICATION_INFO0_LEGACY_RATE_CCK;
- rate = MS(info0, HTT_RX_INDICATION_INFO0_LEGACY_RATE);
- rate_idx = 0;
-
- if (rate < 0x08 || rate > 0x0F)
- break;
-
- switch (band) {
- case IEEE80211_BAND_2GHZ:
- if (cck)
- rate &= ~BIT(3);
- rate_idx = rx_legacy_rate_idx[rate];
- break;
- case IEEE80211_BAND_5GHZ:
- rate_idx = rx_legacy_rate_idx[rate];
- /* We are using same rate table registering
- HW - ath10k_rates[]. In case of 5GHz skip
- CCK rates, so -4 here */
- rate_idx -= 4;
- break;
- default:
- break;
- }
-
- status->rate_idx = rate_idx;
- break;
- case HTT_RX_HT:
- case HTT_RX_HT_WITH_TXBF:
- /* HT-SIG - Table 20-11 in info1 and info2 */
- mcs = info1 & 0x1F;
- nss = mcs >> 3;
- bw = (info1 >> 7) & 1;
- sgi = (info2 >> 7) & 1;
-
- status->rate_idx = mcs;
- status->flag |= RX_FLAG_HT;
- if (sgi)
- status->flag |= RX_FLAG_SHORT_GI;
- if (bw)
- status->flag |= RX_FLAG_40MHZ;
- break;
- case HTT_RX_VHT:
- case HTT_RX_VHT_WITH_TXBF:
- /* VHT-SIG-A1 in info 1, VHT-SIG-A2 in info2
- TODO check this */
- mcs = (info2 >> 4) & 0x0F;
- nss = ((info1 >> 10) & 0x07) + 1;
- bw = info1 & 3;
- sgi = info2 & 1;
-
- status->rate_idx = mcs;
- status->vht_nss = nss;
-
- if (sgi)
- status->flag |= RX_FLAG_SHORT_GI;
-
- switch (bw) {
- /* 20MHZ */
- case 0:
- break;
- /* 40MHZ */
- case 1:
- status->flag |= RX_FLAG_40MHZ;
- break;
- /* 80MHZ */
- case 2:
- status->vht_flag |= RX_VHT_FLAG_80MHZ;
- }
-
- status->flag |= RX_FLAG_VHT;
- break;
- default:
- break;
- }
-}
-
-void ath10k_process_rx(struct ath10k *ar, struct htt_rx_info *info)
-{
- struct ieee80211_rx_status *status;
- struct ieee80211_channel *ch;
- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)info->skb->data;
-
- status = IEEE80211_SKB_RXCB(info->skb);
- memset(status, 0, sizeof(*status));
-
- if (info->encrypt_type != HTT_RX_MPDU_ENCRYPT_NONE) {
- status->flag |= RX_FLAG_DECRYPTED | RX_FLAG_IV_STRIPPED |
- RX_FLAG_MMIC_STRIPPED;
- hdr->frame_control = __cpu_to_le16(
- __le16_to_cpu(hdr->frame_control) &
- ~IEEE80211_FCTL_PROTECTED);
- }
-
- if (info->mic_err)
- status->flag |= RX_FLAG_MMIC_ERROR;
-
- if (info->fcs_err)
- status->flag |= RX_FLAG_FAILED_FCS_CRC;
-
- if (info->amsdu_more)
- status->flag |= RX_FLAG_AMSDU_MORE;
-
- status->signal = info->signal;
-
- spin_lock_bh(&ar->data_lock);
- ch = ar->scan_channel;
- if (!ch)
- ch = ar->rx_channel;
- spin_unlock_bh(&ar->data_lock);
-
- if (!ch) {
- ath10k_warn("no channel configured; ignoring frame!\n");
- dev_kfree_skb_any(info->skb);
- return;
- }
-
- process_rx_rates(ar, info, ch->band, status);
- status->band = ch->band;
- status->freq = ch->center_freq;
-
- if (info->rate.info0 & HTT_RX_INDICATION_INFO0_END_VALID) {
- /* TSF available only in 32-bit */
- status->mactime = info->tsf & 0xffffffff;
- status->flag |= RX_FLAG_MACTIME_END;
- }
-
- ath10k_dbg(ATH10K_DBG_DATA,
- "rx skb %p len %u %s%s%s%s%s %srate_idx %u vht_nss %u freq %u band %u flag 0x%x fcs-err %i\n",
- info->skb,
- info->skb->len,
- status->flag == 0 ? "legacy" : "",
- status->flag & RX_FLAG_HT ? "ht" : "",
- status->flag & RX_FLAG_VHT ? "vht" : "",
- status->flag & RX_FLAG_40MHZ ? "40" : "",
- status->vht_flag & RX_VHT_FLAG_80MHZ ? "80" : "",
- status->flag & RX_FLAG_SHORT_GI ? "sgi " : "",
- status->rate_idx,
- status->vht_nss,
- status->freq,
- status->band, status->flag, info->fcs_err);
- ath10k_dbg_dump(ATH10K_DBG_HTT_DUMP, NULL, "rx skb: ",
- info->skb->data, info->skb->len);
-
- ieee80211_rx(ar->hw, info->skb);
-}
-
struct ath10k_peer *ath10k_peer_find(struct ath10k *ar, int vdev_id,
const u8 *addr)
{
diff --git a/drivers/net/wireless/ath/ath10k/txrx.h b/drivers/net/wireless/ath/ath10k/txrx.h
index 356dc9c..aee3e20 100644
--- a/drivers/net/wireless/ath/ath10k/txrx.h
+++ b/drivers/net/wireless/ath/ath10k/txrx.h
@@ -21,7 +21,6 @@

void ath10k_txrx_tx_unref(struct ath10k_htt *htt,
const struct htt_tx_done *tx_done);
-void ath10k_process_rx(struct ath10k *ar, struct htt_rx_info *info);

struct ath10k_peer *ath10k_peer_find(struct ath10k *ar, int vdev_id,
const u8 *addr);
--
1.7.9.5



2014-03-19 08:49:39

by Janusz Dziedzic

[permalink] [raw]
Subject: [RFC v2 6/8] ath10k: kill not needed fields from htt_rx_info

Kill rates, tsf, fcs_err, mic_err, amsdu_more, encrypt_type
from htt_rx_info and setup this directly in ieee80211_rx_status.

Signed-off-by: Janusz Dziedzic <[email protected]>
---
drivers/net/wireless/ath/ath10k/htt.h | 12 ---
drivers/net/wireless/ath/ath10k/htt_rx.c | 128 ++++++++++++++++--------------
2 files changed, 70 insertions(+), 70 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/htt.h b/drivers/net/wireless/ath/ath10k/htt.h
index 9f5da2b..870f807 100644
--- a/drivers/net/wireless/ath/ath10k/htt.h
+++ b/drivers/net/wireless/ath/ath10k/htt.h
@@ -1176,18 +1176,6 @@ struct htt_peer_unmap_event {
struct htt_rx_info {
struct sk_buff *skb;
struct ieee80211_rx_status rx_status;
- enum htt_rx_mpdu_status status;
- enum htt_rx_mpdu_encrypt_type encrypt_type;
- struct {
- u8 info0;
- u32 info1;
- u32 info2;
- } rate;
-
- u32 tsf;
- bool fcs_err;
- bool amsdu_more;
- bool mic_err;
};

struct ath10k_htt_txbuf {
diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c b/drivers/net/wireless/ath/ath10k/htt_rx.c
index 4797b59..1af1021 100644
--- a/drivers/net/wireless/ath/ath10k/htt_rx.c
+++ b/drivers/net/wireless/ath/ath10k/htt_rx.c
@@ -655,14 +655,12 @@ static const u8 rx_legacy_rate_idx[] = {
5, /* 0x0F - 9Mbps */
};

-static void ath10k_htt_rx_h_rates(struct ath10k *ar, struct htt_rx_info *info,
+static void ath10k_htt_rx_h_rates(struct ath10k *ar,
enum ieee80211_band band,
+ u8 info0, u32 info1, u32 info2,
struct ieee80211_rx_status *status)
{
u8 cck, rate, rate_idx, bw, sgi, mcs, nss;
- u8 info0 = info->rate.info0;
- u32 info1 = info->rate.info1;
- u32 info2 = info->rate.info2;
u8 preamble = 0;

/* Check if valid fields */
@@ -749,6 +747,23 @@ static void ath10k_htt_rx_h_rates(struct ath10k *ar, struct htt_rx_info *info,
}
}

+static void ath10k_htt_rx_h_protected(struct ath10k_htt *htt,
+ struct htt_rx_info *info,
+ enum htt_rx_mpdu_encrypt_type enctype)
+{
+ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)info->skb->data;
+
+
+ if (enctype == HTT_RX_MPDU_ENCRYPT_NONE)
+ return;
+
+ info->rx_status.flag |= RX_FLAG_DECRYPTED |
+ RX_FLAG_IV_STRIPPED |
+ RX_FLAG_MMIC_STRIPPED;
+ hdr->frame_control = __cpu_to_le16(__le16_to_cpu(hdr->frame_control) &
+ ~IEEE80211_FCTL_PROTECTED);
+}
+
static bool ath10k_htt_rx_h_channel(struct ath10k *ar,
struct ieee80211_rx_status *status)
{
@@ -772,36 +787,10 @@ static bool ath10k_htt_rx_h_channel(struct ath10k *ar,
static void ath10k_process_rx(struct ath10k *ar, struct htt_rx_info *info)
{
struct ieee80211_rx_status *status;
- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)info->skb->data;

status = IEEE80211_SKB_RXCB(info->skb);
memcpy(status, &info->rx_status, sizeof(*status));

- if (info->encrypt_type != HTT_RX_MPDU_ENCRYPT_NONE) {
- status->flag |= RX_FLAG_DECRYPTED | RX_FLAG_IV_STRIPPED |
- RX_FLAG_MMIC_STRIPPED;
- hdr->frame_control = __cpu_to_le16(
- __le16_to_cpu(hdr->frame_control) &
- ~IEEE80211_FCTL_PROTECTED);
- }
-
- if (info->mic_err)
- status->flag |= RX_FLAG_MMIC_ERROR;
-
- if (info->fcs_err)
- status->flag |= RX_FLAG_FAILED_FCS_CRC;
-
- if (info->amsdu_more)
- status->flag |= RX_FLAG_AMSDU_MORE;
-
- ath10k_htt_rx_h_rates(ar, info, status->band, status);
-
- if (info->rate.info0 & HTT_RX_INDICATION_INFO0_END_VALID) {
- /* TSF available only in 32-bit */
- status->mactime = info->tsf & 0xffffffff;
- status->flag |= RX_FLAG_MACTIME_END;
- }
-
ath10k_dbg(ATH10K_DBG_DATA,
"rx skb %p len %u %s%s%s%s%s %srate_idx %u vht_nss %u freq %u band %u flag 0x%x fcs-err %i\n",
info->skb,
@@ -815,7 +804,8 @@ static void ath10k_process_rx(struct ath10k *ar, struct htt_rx_info *info)
status->rate_idx,
status->vht_nss,
status->freq,
- status->band, status->flag, info->fcs_err);
+ status->band, status->flag,
+ !!(status->flag & RX_FLAG_FAILED_FCS_CRC));
ath10k_dbg_dump(ATH10K_DBG_HTT_DUMP, NULL, "rx skb: ",
info->skb->data, info->skb->len);

@@ -915,12 +905,12 @@ static void ath10k_htt_rx_amsdu(struct ath10k_htt *htt,
}

info->skb = skb;
- info->encrypt_type = enctype;
+ ath10k_htt_rx_h_protected(htt, info, enctype);
skb = skb->next;
info->skb->next = NULL;

if (skb)
- info->amsdu_more = true;
+ info->rx_status.flag |= RX_FLAG_AMSDU_MORE;

ath10k_process_rx(htt->ar, info);
}
@@ -995,7 +985,7 @@ static void ath10k_htt_rx_msdu(struct ath10k_htt *htt, struct htt_rx_info *info)
}

info->skb = skb;
- info->encrypt_type = enctype;
+ ath10k_htt_rx_h_protected(htt, info, enctype);

ath10k_process_rx(htt->ar, info);
}
@@ -1140,11 +1130,9 @@ static int ath10k_unchain_msdu(struct sk_buff *msdu_head)

static bool ath10k_htt_rx_amsdu_allowed(struct ath10k_htt *htt,
struct sk_buff *head,
- struct htt_rx_info *info,
+ enum htt_rx_mpdu_status status,
bool channel_set)
{
- enum htt_rx_mpdu_status status = info->status;
-
if (!head) {
ath10k_warn("htt rx no data!\n");
return false;
@@ -1198,11 +1186,12 @@ static void ath10k_htt_rx_handler(struct ath10k_htt *htt,
{
struct htt_rx_info info;
struct htt_rx_indication_mpdu_range *mpdu_ranges;
+ enum htt_rx_mpdu_status status;
struct ieee80211_hdr *hdr;
int num_mpdu_ranges;
int fw_desc_len;
u8 *fw_desc;
- bool channel_set;
+ bool channel_set, fcs_err, mic_err;
int i, j;

lockdep_assert_held(&htt->rx_ring.lock);
@@ -1220,12 +1209,22 @@ static void ath10k_htt_rx_handler(struct ath10k_htt *htt,
info.rx_status.signal = ATH10K_DEFAULT_NOISE_FLOOR;
info.rx_status.signal += rx->ppdu.combined_rssi;

+ if (rx->ppdu.info0 & HTT_RX_INDICATION_INFO0_END_VALID) {
+ /* TSF available only in 32-bit */
+ info.rx_status.mactime =
+ __le32_to_cpu(rx->ppdu.tsf) & 0xffffffff;
+ info.rx_status.flag |= RX_FLAG_MACTIME_END;
+ }
+
channel_set = ath10k_htt_rx_h_channel(htt->ar, &info.rx_status);

- info.rate.info0 = rx->ppdu.info0;
- info.rate.info1 = __le32_to_cpu(rx->ppdu.info1);
- info.rate.info2 = __le32_to_cpu(rx->ppdu.info2);
- info.tsf = __le32_to_cpu(rx->ppdu.tsf);
+ if (channel_set) {
+ ath10k_htt_rx_h_rates(htt->ar, info.rx_status.band,
+ rx->ppdu.info0,
+ __le32_to_cpu(rx->ppdu.info1),
+ __le32_to_cpu(rx->ppdu.info2),
+ &info.rx_status);
+ }

ath10k_dbg_dump(ATH10K_DBG_HTT_DUMP, NULL, "htt rx ind: ",
rx, sizeof(*rx) +
@@ -1233,7 +1232,7 @@ static void ath10k_htt_rx_handler(struct ath10k_htt *htt,
num_mpdu_ranges));

for (i = 0; i < num_mpdu_ranges; i++) {
- info.status = mpdu_ranges[i].mpdu_range_status;
+ status = mpdu_ranges[i].mpdu_range_status;

for (j = 0; j < mpdu_ranges[i].mpdu_count; j++) {
struct sk_buff *msdu_head, *msdu_tail;
@@ -1248,7 +1247,7 @@ static void ath10k_htt_rx_handler(struct ath10k_htt *htt,
&msdu_tail);

if (!ath10k_htt_rx_amsdu_allowed(htt, msdu_head,
- &info,
+ status,
channel_set)) {
ath10k_htt_rx_free_msdu_chain(msdu_head);
continue;
@@ -1261,14 +1260,28 @@ static void ath10k_htt_rx_handler(struct ath10k_htt *htt,
}

info.skb = msdu_head;
- info.fcs_err = ath10k_htt_rx_has_fcs_err(msdu_head);
- info.mic_err = ath10k_htt_rx_has_mic_err(msdu_head);

- if (info.fcs_err)
+ /* Clean per-mpdu specyfic flags */
+ info.rx_status.flag &= ~(RX_FLAG_AMSDU_MORE |
+ RX_FLAG_FAILED_FCS_CRC |
+ RX_FLAG_MMIC_ERROR |
+ RX_FLAG_DECRYPTED |
+ RX_FLAG_IV_STRIPPED |
+ RX_FLAG_MMIC_STRIPPED);
+
+ fcs_err = ath10k_htt_rx_has_fcs_err(msdu_head);
+ if (fcs_err)
+ info.rx_status.flag |= RX_FLAG_FAILED_FCS_CRC;
+
+ mic_err = ath10k_htt_rx_has_mic_err(msdu_head);
+ if (mic_err)
+ info.rx_status.flag |= RX_FLAG_MMIC_ERROR;
+
+ if (fcs_err)
ath10k_dbg(ATH10K_DBG_HTT,
"htt rx has FCS err\n");

- if (info.mic_err)
+ if (mic_err)
ath10k_dbg(ATH10K_DBG_HTT,
"htt rx has MIC err\n");

@@ -1288,6 +1301,7 @@ static void ath10k_htt_rx_frag_handler(struct ath10k_htt *htt,
struct htt_rx_fragment_indication *frag)
{
struct sk_buff *msdu_head, *msdu_tail;
+ enum htt_rx_mpdu_encrypt_type enctype;
struct htt_rx_desc *rxd;
enum rx_msdu_decap_format fmt;
struct htt_rx_info info = {};
@@ -1341,15 +1355,13 @@ static void ath10k_htt_rx_frag_handler(struct ath10k_htt *htt,
}

info.skb = msdu_head;
- info.status = HTT_RX_IND_MPDU_STATUS_OK;
- info.encrypt_type = MS(__le32_to_cpu(rxd->mpdu_start.info0),
- RX_MPDU_START_INFO0_ENCRYPT_TYPE);
+ enctype = MS(__le32_to_cpu(rxd->mpdu_start.info0),
+ RX_MPDU_START_INFO0_ENCRYPT_TYPE);
+ ath10k_htt_rx_h_protected(htt, &info, enctype);
info.skb->ip_summed = ath10k_htt_rx_get_csum_state(info.skb);

- if (tkip_mic_err) {
+ if (tkip_mic_err)
ath10k_warn("tkip mic error\n");
- info.status = HTT_RX_IND_MPDU_STATUS_TKIP_MIC_ERR;
- }

if (decrypt_err) {
ath10k_warn("decryption err in fragmented rx\n");
@@ -1357,9 +1369,9 @@ static void ath10k_htt_rx_frag_handler(struct ath10k_htt *htt,
goto end;
}

- if (info.encrypt_type != HTT_RX_MPDU_ENCRYPT_NONE) {
+ if (enctype != HTT_RX_MPDU_ENCRYPT_NONE) {
hdrlen = ieee80211_hdrlen(hdr->frame_control);
- paramlen = ath10k_htt_rx_crypto_param_len(info.encrypt_type);
+ paramlen = ath10k_htt_rx_crypto_param_len(enctype);

/* It is more efficient to move the header than the payload */
memmove((void *)info.skb->data + paramlen,
@@ -1373,11 +1385,11 @@ static void ath10k_htt_rx_frag_handler(struct ath10k_htt *htt,
trim = 4;

/* remove crypto trailer */
- trim += ath10k_htt_rx_crypto_tail_len(info.encrypt_type);
+ trim += ath10k_htt_rx_crypto_tail_len(enctype);

/* last fragment of TKIP frags has MIC */
if (!ieee80211_has_morefrags(hdr->frame_control) &&
- info.encrypt_type == HTT_RX_MPDU_ENCRYPT_TKIP_WPA)
+ enctype == HTT_RX_MPDU_ENCRYPT_TKIP_WPA)
trim += 8;

if (trim > info.skb->len) {
--
1.7.9.5


2014-03-19 08:49:40

by Janusz Dziedzic

[permalink] [raw]
Subject: [RFC v2 7/8] ath10k: return error when ath10k_htt_rx_amsdu_pop() fail

Return error when rx_amsdu_pop() will fail.

Signed-off-by: Janusz Dziedzic <[email protected]>
---
drivers/net/wireless/ath/ath10k/htt_rx.c | 50 ++++++++++++++++--------------
1 file changed, 26 insertions(+), 24 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c b/drivers/net/wireless/ath/ath10k/htt_rx.c
index 1af1021..8bccba5 100644
--- a/drivers/net/wireless/ath/ath10k/htt_rx.c
+++ b/drivers/net/wireless/ath/ath10k/htt_rx.c
@@ -297,6 +297,7 @@ static void ath10k_htt_rx_free_msdu_chain(struct sk_buff *skb)
}
}

+/* return: < 0 fatal error, 0 - non chained msdu, 1 chained msdu */
static int ath10k_htt_rx_amsdu_pop(struct ath10k_htt *htt,
u8 **fw_desc, int *fw_desc_len,
struct sk_buff **head_msdu,
@@ -310,7 +311,7 @@ static int ath10k_htt_rx_amsdu_pop(struct ath10k_htt *htt,

if (htt->rx_confused) {
ath10k_warn("htt is confused. refusing rx\n");
- return 0;
+ return -1;
}

msdu = *head_msdu = ath10k_htt_rx_netbuf_pop(htt);
@@ -442,6 +443,9 @@ static int ath10k_htt_rx_amsdu_pop(struct ath10k_htt *htt,
}
*tail_msdu = msdu;

+ if (*head_msdu == NULL)
+ msdu_chaining = -1;
+
/*
* Don't refill the ring yet.
*
@@ -1133,11 +1137,6 @@ static bool ath10k_htt_rx_amsdu_allowed(struct ath10k_htt *htt,
enum htt_rx_mpdu_status status,
bool channel_set)
{
- if (!head) {
- ath10k_warn("htt rx no data!\n");
- return false;
- }
-
if (head->len == 0) {
ath10k_dbg(ATH10K_DBG_HTT,
"htt rx dropping due to zero-len\n");
@@ -1193,6 +1192,7 @@ static void ath10k_htt_rx_handler(struct ath10k_htt *htt,
u8 *fw_desc;
bool channel_set, fcs_err, mic_err;
int i, j;
+ int ret;

lockdep_assert_held(&htt->rx_ring.lock);

@@ -1236,15 +1236,21 @@ static void ath10k_htt_rx_handler(struct ath10k_htt *htt,

for (j = 0; j < mpdu_ranges[i].mpdu_count; j++) {
struct sk_buff *msdu_head, *msdu_tail;
- int msdu_chaining;

msdu_head = NULL;
msdu_tail = NULL;
- msdu_chaining = ath10k_htt_rx_amsdu_pop(htt,
- &fw_desc,
- &fw_desc_len,
- &msdu_head,
- &msdu_tail);
+ ret = ath10k_htt_rx_amsdu_pop(htt,
+ &fw_desc,
+ &fw_desc_len,
+ &msdu_head,
+ &msdu_tail);
+
+ if (ret < 0) {
+ ath10k_warn("failed to pop amsdu from htt rx ring %d\n",
+ ret);
+ ath10k_htt_rx_free_msdu_chain(msdu_head);
+ continue;
+ }

if (!ath10k_htt_rx_amsdu_allowed(htt, msdu_head,
status,
@@ -1253,8 +1259,8 @@ static void ath10k_htt_rx_handler(struct ath10k_htt *htt,
continue;
}

- if (msdu_chaining &&
- (ath10k_unchain_msdu(msdu_head) < 0)) {
+ if (ret > 0 &&
+ ath10k_unchain_msdu(msdu_head) < 0) {
ath10k_htt_rx_free_msdu_chain(msdu_head);
continue;
}
@@ -1306,7 +1312,7 @@ static void ath10k_htt_rx_frag_handler(struct ath10k_htt *htt,
enum rx_msdu_decap_format fmt;
struct htt_rx_info info = {};
struct ieee80211_hdr *hdr;
- int msdu_chaining;
+ int ret;
bool tkip_mic_err;
bool decrypt_err;
u8 *fw_desc;
@@ -1320,19 +1326,15 @@ static void ath10k_htt_rx_frag_handler(struct ath10k_htt *htt,
msdu_tail = NULL;

spin_lock_bh(&htt->rx_ring.lock);
- msdu_chaining = ath10k_htt_rx_amsdu_pop(htt, &fw_desc, &fw_desc_len,
- &msdu_head, &msdu_tail);
+ ret = ath10k_htt_rx_amsdu_pop(htt, &fw_desc, &fw_desc_len,
+ &msdu_head, &msdu_tail);
spin_unlock_bh(&htt->rx_ring.lock);

ath10k_dbg(ATH10K_DBG_HTT_DUMP, "htt rx frag ahead\n");

- if (!msdu_head) {
- ath10k_warn("htt rx frag no data\n");
- return;
- }
-
- if (msdu_chaining || msdu_head != msdu_tail) {
- ath10k_warn("aggregation with fragmentation?!\n");
+ if (ret) {
+ ath10k_warn("failed to pop amsdu from httr rx ring for fragmented rx %d\n",
+ ret);
ath10k_htt_rx_free_msdu_chain(msdu_head);
return;
}
--
1.7.9.5


2014-03-19 08:49:34

by Janusz Dziedzic

[permalink] [raw]
Subject: [RFC v2 2/8] ath10k: rename process_rx_rates to ath10k_htt_rx_h_rates

No functional changes.

Signed-off-by: Janusz Dziedzic <[email protected]>
---
drivers/net/wireless/ath/ath10k/htt_rx.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c b/drivers/net/wireless/ath/ath10k/htt_rx.c
index c07fc8f..fd14c3a 100644
--- a/drivers/net/wireless/ath/ath10k/htt_rx.c
+++ b/drivers/net/wireless/ath/ath10k/htt_rx.c
@@ -655,9 +655,9 @@ static const u8 rx_legacy_rate_idx[] = {
5, /* 0x0F - 9Mbps */
};

-static void process_rx_rates(struct ath10k *ar, struct htt_rx_info *info,
- enum ieee80211_band band,
- struct ieee80211_rx_status *status)
+static void ath10k_htt_rx_h_rates(struct ath10k *ar, struct htt_rx_info *info,
+ enum ieee80211_band band,
+ struct ieee80211_rx_status *status)
{
u8 cck, rate, rate_idx, bw, sgi, mcs, nss;
u8 info0 = info->rate.info0;
@@ -789,7 +789,7 @@ static void ath10k_process_rx(struct ath10k *ar, struct htt_rx_info *info)
return;
}

- process_rx_rates(ar, info, ch->band, status);
+ ath10k_htt_rx_h_rates(ar, info, ch->band, status);
status->band = ch->band;
status->freq = ch->center_freq;

--
1.7.9.5


2014-03-19 08:49:37

by Janusz Dziedzic

[permalink] [raw]
Subject: [RFC v2 4/8] ath10k: kill signal field in htt_rx_info

Setup signal field directly in ieee80211_rx_status.

Signed-off-by: Janusz Dziedzic <[email protected]>
---
drivers/net/wireless/ath/ath10k/htt.h | 1 -
drivers/net/wireless/ath/ath10k/htt_rx.c | 6 ++----
2 files changed, 2 insertions(+), 5 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/htt.h b/drivers/net/wireless/ath/ath10k/htt.h
index e80f033..9f5da2b 100644
--- a/drivers/net/wireless/ath/ath10k/htt.h
+++ b/drivers/net/wireless/ath/ath10k/htt.h
@@ -1178,7 +1178,6 @@ struct htt_rx_info {
struct ieee80211_rx_status rx_status;
enum htt_rx_mpdu_status status;
enum htt_rx_mpdu_encrypt_type encrypt_type;
- s8 signal;
struct {
u8 info0;
u32 info1;
diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c b/drivers/net/wireless/ath/ath10k/htt_rx.c
index f18e41c..415ef1c 100644
--- a/drivers/net/wireless/ath/ath10k/htt_rx.c
+++ b/drivers/net/wireless/ath/ath10k/htt_rx.c
@@ -775,8 +775,6 @@ static void ath10k_process_rx(struct ath10k *ar, struct htt_rx_info *info)
if (info->amsdu_more)
status->flag |= RX_FLAG_AMSDU_MORE;

- status->signal = info->signal;
-
spin_lock_bh(&ar->data_lock);
ch = ar->scan_channel;
if (!ch)
@@ -1207,8 +1205,8 @@ static void ath10k_htt_rx_handler(struct ath10k_htt *htt,
mpdu_ranges = htt_rx_ind_get_mpdu_ranges(rx);

/* Fill this once, while this is per-ppdu */
- info.signal = ATH10K_DEFAULT_NOISE_FLOOR;
- info.signal += rx->ppdu.combined_rssi;
+ info.rx_status.signal = ATH10K_DEFAULT_NOISE_FLOOR;
+ info.rx_status.signal += rx->ppdu.combined_rssi;

info.rate.info0 = rx->ppdu.info0;
info.rate.info1 = __le32_to_cpu(rx->ppdu.info1);
--
1.7.9.5


2014-03-19 08:49:41

by Janusz Dziedzic

[permalink] [raw]
Subject: [RFC v2 8/8] ath10k: improve way we play with attention flags

Remove almost the same code, and do only once
__le32_to_cpu() conversion.

Signed-off-by: Janusz Dziedzic <[email protected]>
---
drivers/net/wireless/ath/ath10k/htt_rx.c | 89 +++++++-----------------------
1 file changed, 19 insertions(+), 70 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c b/drivers/net/wireless/ath/ath10k/htt_rx.c
index 8bccba5..665a256 100644
--- a/drivers/net/wireless/ath/ath10k/htt_rx.c
+++ b/drivers/net/wireless/ath/ath10k/htt_rx.c
@@ -994,62 +994,6 @@ static void ath10k_htt_rx_msdu(struct ath10k_htt *htt, struct htt_rx_info *info)
ath10k_process_rx(htt->ar, info);
}

-static bool ath10k_htt_rx_has_decrypt_err(struct sk_buff *skb)
-{
- struct htt_rx_desc *rxd;
- u32 flags;
-
- rxd = (void *)skb->data - sizeof(*rxd);
- flags = __le32_to_cpu(rxd->attention.flags);
-
- if (flags & RX_ATTENTION_FLAGS_DECRYPT_ERR)
- return true;
-
- return false;
-}
-
-static bool ath10k_htt_rx_has_fcs_err(struct sk_buff *skb)
-{
- struct htt_rx_desc *rxd;
- u32 flags;
-
- rxd = (void *)skb->data - sizeof(*rxd);
- flags = __le32_to_cpu(rxd->attention.flags);
-
- if (flags & RX_ATTENTION_FLAGS_FCS_ERR)
- return true;
-
- return false;
-}
-
-static bool ath10k_htt_rx_has_mic_err(struct sk_buff *skb)
-{
- struct htt_rx_desc *rxd;
- u32 flags;
-
- rxd = (void *)skb->data - sizeof(*rxd);
- flags = __le32_to_cpu(rxd->attention.flags);
-
- if (flags & RX_ATTENTION_FLAGS_TKIP_MIC_ERR)
- return true;
-
- return false;
-}
-
-static bool ath10k_htt_rx_is_mgmt(struct sk_buff *skb)
-{
- struct htt_rx_desc *rxd;
- u32 flags;
-
- rxd = (void *)skb->data - sizeof(*rxd);
- flags = __le32_to_cpu(rxd->attention.flags);
-
- if (flags & RX_ATTENTION_FLAGS_MGMT_TYPE)
- return true;
-
- return false;
-}
-
static int ath10k_htt_rx_get_csum_state(struct sk_buff *skb)
{
struct htt_rx_desc *rxd;
@@ -1135,7 +1079,8 @@ static int ath10k_unchain_msdu(struct sk_buff *msdu_head)
static bool ath10k_htt_rx_amsdu_allowed(struct ath10k_htt *htt,
struct sk_buff *head,
enum htt_rx_mpdu_status status,
- bool channel_set)
+ bool channel_set,
+ u32 attention)
{
if (head->len == 0) {
ath10k_dbg(ATH10K_DBG_HTT,
@@ -1143,7 +1088,7 @@ static bool ath10k_htt_rx_amsdu_allowed(struct ath10k_htt *htt,
return false;
}

- if (ath10k_htt_rx_has_decrypt_err(head)) {
+ if (attention & RX_ATTENTION_FLAGS_DECRYPT_ERR) {
ath10k_dbg(ATH10K_DBG_HTT,
"htt rx dropping due to decrypt-err\n");
return false;
@@ -1156,7 +1101,7 @@ static bool ath10k_htt_rx_amsdu_allowed(struct ath10k_htt *htt,

/* Skip mgmt frames while we handle this in WMI */
if (status == HTT_RX_IND_MPDU_STATUS_MGMT_CTRL ||
- ath10k_htt_rx_is_mgmt(head)) {
+ attention & RX_ATTENTION_FLAGS_MGMT_TYPE) {
ath10k_dbg(ATH10K_DBG_HTT, "htt rx mgmt ctrl\n");
return false;
}
@@ -1185,12 +1130,14 @@ static void ath10k_htt_rx_handler(struct ath10k_htt *htt,
{
struct htt_rx_info info;
struct htt_rx_indication_mpdu_range *mpdu_ranges;
+ struct htt_rx_desc *rxd;
enum htt_rx_mpdu_status status;
struct ieee80211_hdr *hdr;
int num_mpdu_ranges;
+ u32 attention;
int fw_desc_len;
u8 *fw_desc;
- bool channel_set, fcs_err, mic_err;
+ bool channel_set;
int i, j;
int ret;

@@ -1252,9 +1199,15 @@ static void ath10k_htt_rx_handler(struct ath10k_htt *htt,
continue;
}

+ rxd = container_of((void *) msdu_head->data,
+ struct htt_rx_desc,
+ msdu_payload);
+ attention = __le32_to_cpu(rxd->attention.flags);
+
if (!ath10k_htt_rx_amsdu_allowed(htt, msdu_head,
status,
- channel_set)) {
+ channel_set,
+ attention)) {
ath10k_htt_rx_free_msdu_chain(msdu_head);
continue;
}
@@ -1275,21 +1228,17 @@ static void ath10k_htt_rx_handler(struct ath10k_htt *htt,
RX_FLAG_IV_STRIPPED |
RX_FLAG_MMIC_STRIPPED);

- fcs_err = ath10k_htt_rx_has_fcs_err(msdu_head);
- if (fcs_err)
+ if (attention & RX_ATTENTION_FLAGS_FCS_ERR) {
info.rx_status.flag |= RX_FLAG_FAILED_FCS_CRC;
-
- mic_err = ath10k_htt_rx_has_mic_err(msdu_head);
- if (mic_err)
- info.rx_status.flag |= RX_FLAG_MMIC_ERROR;
-
- if (fcs_err)
ath10k_dbg(ATH10K_DBG_HTT,
"htt rx has FCS err\n");
+ }

- if (mic_err)
+ if (attention & RX_ATTENTION_FLAGS_TKIP_MIC_ERR) {
+ info.rx_status.flag |= RX_FLAG_MMIC_ERROR;
ath10k_dbg(ATH10K_DBG_HTT,
"htt rx has MIC err\n");
+ }

hdr = ath10k_htt_rx_skb_get_hdr(msdu_head);

--
1.7.9.5


2014-03-19 08:49:36

by Janusz Dziedzic

[permalink] [raw]
Subject: [RFC v2 3/8] ath10k: introduce ieee80211_rx_status to htt_rx_info

Will be used as a template, and final storage for
rx_status.

Signed-off-by: Janusz Dziedzic <[email protected]>
---
drivers/net/wireless/ath/ath10k/htt.h | 2 ++
drivers/net/wireless/ath/ath10k/htt_rx.c | 2 +-
2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/ath/ath10k/htt.h b/drivers/net/wireless/ath/ath10k/htt.h
index 654867f..e80f033 100644
--- a/drivers/net/wireless/ath/ath10k/htt.h
+++ b/drivers/net/wireless/ath/ath10k/htt.h
@@ -21,6 +21,7 @@
#include <linux/bug.h>
#include <linux/interrupt.h>
#include <linux/dmapool.h>
+#include <net/mac80211.h>

#include "htc.h"
#include "rx_desc.h"
@@ -1174,6 +1175,7 @@ struct htt_peer_unmap_event {

struct htt_rx_info {
struct sk_buff *skb;
+ struct ieee80211_rx_status rx_status;
enum htt_rx_mpdu_status status;
enum htt_rx_mpdu_encrypt_type encrypt_type;
s8 signal;
diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c b/drivers/net/wireless/ath/ath10k/htt_rx.c
index fd14c3a..f18e41c 100644
--- a/drivers/net/wireless/ath/ath10k/htt_rx.c
+++ b/drivers/net/wireless/ath/ath10k/htt_rx.c
@@ -756,7 +756,7 @@ static void ath10k_process_rx(struct ath10k *ar, struct htt_rx_info *info)
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)info->skb->data;

status = IEEE80211_SKB_RXCB(info->skb);
- memset(status, 0, sizeof(*status));
+ memcpy(status, &info->rx_status, sizeof(*status));

if (info->encrypt_type != HTT_RX_MPDU_ENCRYPT_NONE) {
status->flag |= RX_FLAG_DECRYPTED | RX_FLAG_IV_STRIPPED |
--
1.7.9.5


2014-03-19 08:49:38

by Janusz Dziedzic

[permalink] [raw]
Subject: [RFC v2 5/8] ath10k: setup rx channel per ppdu

Setup band and frequency in ieee80211_rx_status
only once - for ppdu.

Signed-off-by: Janusz Dziedzic <[email protected]>
---
drivers/net/wireless/ath/ath10k/htt_rx.c | 51 +++++++++++++++++++-----------
1 file changed, 33 insertions(+), 18 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c b/drivers/net/wireless/ath/ath10k/htt_rx.c
index 415ef1c..4797b59 100644
--- a/drivers/net/wireless/ath/ath10k/htt_rx.c
+++ b/drivers/net/wireless/ath/ath10k/htt_rx.c
@@ -749,10 +749,29 @@ static void ath10k_htt_rx_h_rates(struct ath10k *ar, struct htt_rx_info *info,
}
}

+static bool ath10k_htt_rx_h_channel(struct ath10k *ar,
+ struct ieee80211_rx_status *status)
+{
+ struct ieee80211_channel *ch;
+
+ spin_lock_bh(&ar->data_lock);
+ ch = ar->scan_channel;
+ if (!ch)
+ ch = ar->rx_channel;
+ spin_unlock_bh(&ar->data_lock);
+
+ if (!ch)
+ return false;
+
+ status->band = ch->band;
+ status->freq = ch->center_freq;
+
+ return true;
+}
+
static void ath10k_process_rx(struct ath10k *ar, struct htt_rx_info *info)
{
struct ieee80211_rx_status *status;
- struct ieee80211_channel *ch;
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)info->skb->data;

status = IEEE80211_SKB_RXCB(info->skb);
@@ -775,21 +794,7 @@ static void ath10k_process_rx(struct ath10k *ar, struct htt_rx_info *info)
if (info->amsdu_more)
status->flag |= RX_FLAG_AMSDU_MORE;

- spin_lock_bh(&ar->data_lock);
- ch = ar->scan_channel;
- if (!ch)
- ch = ar->rx_channel;
- spin_unlock_bh(&ar->data_lock);
-
- if (!ch) {
- ath10k_warn("no channel configured; ignoring frame!\n");
- dev_kfree_skb_any(info->skb);
- return;
- }
-
- ath10k_htt_rx_h_rates(ar, info, ch->band, status);
- status->band = ch->band;
- status->freq = ch->center_freq;
+ ath10k_htt_rx_h_rates(ar, info, status->band, status);

if (info->rate.info0 & HTT_RX_INDICATION_INFO0_END_VALID) {
/* TSF available only in 32-bit */
@@ -1135,7 +1140,8 @@ static int ath10k_unchain_msdu(struct sk_buff *msdu_head)

static bool ath10k_htt_rx_amsdu_allowed(struct ath10k_htt *htt,
struct sk_buff *head,
- struct htt_rx_info *info)
+ struct htt_rx_info *info,
+ bool channel_set)
{
enum htt_rx_mpdu_status status = info->status;

@@ -1156,6 +1162,11 @@ static bool ath10k_htt_rx_amsdu_allowed(struct ath10k_htt *htt,
return false;
}

+ if (!channel_set) {
+ ath10k_warn("no channel configured; ignoring frame!\n");
+ return false;
+ }
+
/* Skip mgmt frames while we handle this in WMI */
if (status == HTT_RX_IND_MPDU_STATUS_MGMT_CTRL ||
ath10k_htt_rx_is_mgmt(head)) {
@@ -1191,6 +1202,7 @@ static void ath10k_htt_rx_handler(struct ath10k_htt *htt,
int num_mpdu_ranges;
int fw_desc_len;
u8 *fw_desc;
+ bool channel_set;
int i, j;

lockdep_assert_held(&htt->rx_ring.lock);
@@ -1208,6 +1220,8 @@ static void ath10k_htt_rx_handler(struct ath10k_htt *htt,
info.rx_status.signal = ATH10K_DEFAULT_NOISE_FLOOR;
info.rx_status.signal += rx->ppdu.combined_rssi;

+ channel_set = ath10k_htt_rx_h_channel(htt->ar, &info.rx_status);
+
info.rate.info0 = rx->ppdu.info0;
info.rate.info1 = __le32_to_cpu(rx->ppdu.info1);
info.rate.info2 = __le32_to_cpu(rx->ppdu.info2);
@@ -1234,7 +1248,8 @@ static void ath10k_htt_rx_handler(struct ath10k_htt *htt,
&msdu_tail);

if (!ath10k_htt_rx_amsdu_allowed(htt, msdu_head,
- &info)) {
+ &info,
+ channel_set)) {
ath10k_htt_rx_free_msdu_chain(msdu_head);
continue;
}
--
1.7.9.5