2014-03-21 09:32:42

by Janusz Dziedzic

[permalink] [raw]
Subject: [PATCH 0/8] ath10k: refactor htt_rx path

This patchset remove htt_rx_info and intoduce usage
of ieee80211_rx_status template. Introduce calculation
split for per-ppdu and per-mpdu. Remove not needed
calculation we did before for each mpdu. Before we
did calculation for each mpdu and in case of heavy
traffic we could have eg. 15mpdus in one ppdu.

This ieee80211_rx_status template will be also required
to fix rates, rssi we will report to mac80211. I will
send this patches soon.

First two patches - no functional changes.

Tested on AP135, didn't notice any TP drop with this patchset.

Base on:
[PATCH 1/2] ath10k: add ath10k_htt_rx_amsdu_allowed function
[PATCH 2/2] ath10k: Fill per-ppdu info in rx_info only once
I send before.

Please review.

Janusz Dziedzic (8):
ath10k: move rx related functions to htt_rx.c
ath10k: rename process_rx_rates to ath10k_htt_rx_h_rates
ath10k: introduce ieee80211_rx_status to htt_rx_info
ath10k: setup rx channel per ppdu
ath10k: kill not needed fields from htt_rx_info
ath10k: return error when ath10k_htt_rx_amsdu_pop() fail
ath10k: improve way we play with attention flags
ath10k: finally kill htt_rx_info

drivers/net/wireless/ath/ath10k/htt.h | 18 +-
drivers/net/wireless/ath/ath10k/htt_rx.c | 440 ++++++++++++++++++++----------
drivers/net/wireless/ath/ath10k/txrx.c | 183 -------------
drivers/net/wireless/ath/ath10k/txrx.h | 1 -
4 files changed, 299 insertions(+), 343 deletions(-)

--
1.7.9.5



2014-03-21 09:32:46

by Janusz Dziedzic

[permalink] [raw]
Subject: [PATCH 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-21 09:32:44

by Janusz Dziedzic

[permalink] [raw]
Subject: [PATCH 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-21 09:32:48

by Janusz Dziedzic

[permalink] [raw]
Subject: [PATCH 5/8] ath10k: kill not needed fields from htt_rx_info

Kill rates, tsf, fcs_err, mic_err, amsdu_more, encrypt_type, signal
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 | 13 ---
drivers/net/wireless/ath/ath10k/htt_rx.c | 134 +++++++++++++++++-------------
2 files changed, 74 insertions(+), 73 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/htt.h b/drivers/net/wireless/ath/ath10k/htt.h
index e80f033..870f807 100644
--- a/drivers/net/wireless/ath/ath10k/htt.h
+++ b/drivers/net/wireless/ath/ath10k/htt.h
@@ -1176,19 +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;
- s8 signal;
- 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 b37540b..a994a4f 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,27 @@ 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) {
+ info->rx_status.flag &= ~(RX_FLAG_DECRYPTED |
+ RX_FLAG_IV_STRIPPED |
+ RX_FLAG_MMIC_STRIPPED);
+ 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 +791,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 +808,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 +909,14 @@ 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;
+ else
+ info->rx_status.flag &= ~RX_FLAG_AMSDU_MORE;

ath10k_process_rx(htt->ar, info);
}
@@ -995,7 +991,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 +1136,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 +1192,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);
@@ -1217,15 +1212,25 @@ 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;
+
+ 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 +1238,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 +1253,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 +1266,24 @@ 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)
+ fcs_err = ath10k_htt_rx_has_fcs_err(msdu_head);
+ if (fcs_err)
+ info.rx_status.flag |= RX_FLAG_FAILED_FCS_CRC;
+ else
+ 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;
+ else
+ 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 +1303,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 +1357,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 +1371,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 +1387,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-24 08:56:20

by Kalle Valo

[permalink] [raw]
Subject: Re: [PATCH 4/8] ath10k: setup rx channel per ppdu

Janusz Dziedzic <[email protected]> writes:

> Setup band and frequency in ieee80211_rx_status
> only once - for ppdu.
>
> Signed-off-by: Janusz Dziedzic <[email protected]>

[...]

> @@ -775,23 +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;
>
> - status->signal = info->signal;

What about the signal, how is it set now? I don't see that anywhere in
this patch.

--
Kalle Valo

2014-03-24 09:38:45

by Kalle Valo

[permalink] [raw]
Subject: Re: [PATCH 8/8] ath10k: finally kill htt_rx_info

Janusz Dziedzic <[email protected]> writes:

> Struct htt_rx_info is not needed anymore while
> we will use ieee80211_rx_status structure as
> as template.
>
> Signed-off-by: Janusz Dziedzic <[email protected]>

[...]

> -static void ath10k_process_rx(struct ath10k *ar, struct htt_rx_info *info)
> +static void ath10k_process_rx(struct ath10k *ar,
> + struct ieee80211_rx_status *rx_status,
> + struct sk_buff *skb)
> {
> struct ieee80211_rx_status *status;
>
> - status = IEEE80211_SKB_RXCB(info->skb);
> - memcpy(status, &info->rx_status, sizeof(*status));
> + status = IEEE80211_SKB_RXCB(skb);
> + memcpy(status, rx_status, sizeof(*status));

I guess you saw this suggestion from the buildbot:

>> drivers/net/wireless/ath/ath10k/htt_rx.c:803:1-7: Replace memcpy with struct assignment

--
Kalle Valo

2014-03-24 10:17:30

by Janusz Dziedzic

[permalink] [raw]
Subject: Re: [PATCH 4/8] ath10k: setup rx channel per ppdu

On 24 March 2014 09:56, Kalle Valo <[email protected]> wrote:
> Janusz Dziedzic <[email protected]> writes:
>
>> Setup band and frequency in ieee80211_rx_status
>> only once - for ppdu.
>>
>> Signed-off-by: Janusz Dziedzic <[email protected]>
>
> [...]
>
>> @@ -775,23 +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;
>>
>> - status->signal = info->signal;
>
> What about the signal, how is it set now? I don't see that anywhere in
> this patch.
>
This belongs to next patch - will fix it.

BR
janusz

2014-03-21 09:32:49

by Janusz Dziedzic

[permalink] [raw]
Subject: [PATCH 6/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 a994a4f..64abc2a 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.
*
@@ -1139,11 +1143,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");
@@ -1199,6 +1198,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);

@@ -1242,15 +1242,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,
@@ -1259,8 +1265,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;
}
@@ -1308,7 +1314,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;
@@ -1322,19 +1328,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-24 09:40:33

by Kalle Valo

[permalink] [raw]
Subject: Re: [PATCH 7/8] ath10k: improve way we play with attention flags

Janusz Dziedzic <[email protected]> writes:

> Remove almost the same code, and do only once
> __le32_to_cpu() conversion.
>
> Signed-off-by: Janusz Dziedzic <[email protected]>

This patch introduces one checkpatch warning:

drivers/net/wireless/ath/ath10k/htt_rx.c:1209: CHECK: No space is necessary after a cast

--
Kalle Valo

2014-03-21 09:32:45

by Janusz Dziedzic

[permalink] [raw]
Subject: [PATCH 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-21 09:32:52

by Janusz Dziedzic

[permalink] [raw]
Subject: [PATCH 8/8] ath10k: finally kill htt_rx_info

Struct htt_rx_info is not needed anymore while
we will use ieee80211_rx_status structure as
as template.

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

diff --git a/drivers/net/wireless/ath/ath10k/htt.h b/drivers/net/wireless/ath/ath10k/htt.h
index 870f807..2d669c0 100644
--- a/drivers/net/wireless/ath/ath10k/htt.h
+++ b/drivers/net/wireless/ath/ath10k/htt.h
@@ -1173,11 +1173,6 @@ struct htt_peer_unmap_event {
u16 peer_id;
};

-struct htt_rx_info {
- struct sk_buff *skb;
- struct ieee80211_rx_status rx_status;
-};
-
struct ath10k_htt_txbuf {
struct htt_data_tx_desc_frag frags[2];
struct ath10k_htc_hdr htc_hdr;
diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c b/drivers/net/wireless/ath/ath10k/htt_rx.c
index bc40f11..1bb3c5e 100644
--- a/drivers/net/wireless/ath/ath10k/htt_rx.c
+++ b/drivers/net/wireless/ath/ath10k/htt_rx.c
@@ -752,22 +752,23 @@ static void ath10k_htt_rx_h_rates(struct ath10k *ar,
}

static void ath10k_htt_rx_h_protected(struct ath10k_htt *htt,
- struct htt_rx_info *info,
+ struct ieee80211_rx_status *rx_status,
+ struct sk_buff *skb,
enum htt_rx_mpdu_encrypt_type enctype)
{
- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)info->skb->data;
+ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;


if (enctype == HTT_RX_MPDU_ENCRYPT_NONE) {
- info->rx_status.flag &= ~(RX_FLAG_DECRYPTED |
- RX_FLAG_IV_STRIPPED |
- RX_FLAG_MMIC_STRIPPED);
+ rx_status->flag &= ~(RX_FLAG_DECRYPTED |
+ RX_FLAG_IV_STRIPPED |
+ RX_FLAG_MMIC_STRIPPED);
return;
}

- info->rx_status.flag |= RX_FLAG_DECRYPTED |
- RX_FLAG_IV_STRIPPED |
- RX_FLAG_MMIC_STRIPPED;
+ 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);
}
@@ -792,17 +793,19 @@ static bool ath10k_htt_rx_h_channel(struct ath10k *ar,
return true;
}

-static void ath10k_process_rx(struct ath10k *ar, struct htt_rx_info *info)
+static void ath10k_process_rx(struct ath10k *ar,
+ struct ieee80211_rx_status *rx_status,
+ struct sk_buff *skb)
{
struct ieee80211_rx_status *status;

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

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 %imic-err %i\n",
- info->skb,
- info->skb->len,
+ skb,
+ skb->len,
status->flag == 0 ? "legacy" : "",
status->flag & RX_FLAG_HT ? "ht" : "",
status->flag & RX_FLAG_VHT ? "vht" : "",
@@ -816,9 +819,9 @@ static void ath10k_process_rx(struct ath10k *ar, struct htt_rx_info *info)
!!(status->flag & RX_FLAG_FAILED_FCS_CRC),
!!(status->flag & RX_FLAG_MMIC_ERROR));
ath10k_dbg_dump(ATH10K_DBG_HTT_DUMP, NULL, "rx skb: ",
- info->skb->data, info->skb->len);
+ skb->data, skb->len);

- ieee80211_rx(ar->hw, info->skb);
+ ieee80211_rx(ar->hw, skb);
}

static int ath10k_htt_rx_nwifi_hdrlen(struct ieee80211_hdr *hdr)
@@ -828,11 +831,12 @@ static int ath10k_htt_rx_nwifi_hdrlen(struct ieee80211_hdr *hdr)
}

static void ath10k_htt_rx_amsdu(struct ath10k_htt *htt,
- struct htt_rx_info *info)
+ struct ieee80211_rx_status *rx_status,
+ struct sk_buff *skb_in)
{
struct htt_rx_desc *rxd;
+ struct sk_buff *skb = skb_in;
struct sk_buff *first;
- struct sk_buff *skb = info->skb;
enum rx_msdu_decap_format fmt;
enum htt_rx_mpdu_encrypt_type enctype;
struct ieee80211_hdr *hdr;
@@ -913,26 +917,27 @@ static void ath10k_htt_rx_amsdu(struct ath10k_htt *htt,
break;
}

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

if (skb)
- info->rx_status.flag |= RX_FLAG_AMSDU_MORE;
+ rx_status->flag |= RX_FLAG_AMSDU_MORE;
else
- info->rx_status.flag &= ~RX_FLAG_AMSDU_MORE;
+ rx_status->flag &= ~RX_FLAG_AMSDU_MORE;

- ath10k_process_rx(htt->ar, info);
+ ath10k_process_rx(htt->ar, rx_status, skb_in);
}

/* FIXME: It might be nice to re-assemble the A-MSDU when there's a
* monitor interface active for sniffing purposes. */
}

-static void ath10k_htt_rx_msdu(struct ath10k_htt *htt, struct htt_rx_info *info)
+static void ath10k_htt_rx_msdu(struct ath10k_htt *htt,
+ struct ieee80211_rx_status *rx_status,
+ struct sk_buff *skb)
{
- struct sk_buff *skb = info->skb;
struct htt_rx_desc *rxd;
struct ieee80211_hdr *hdr;
enum rx_msdu_decap_format fmt;
@@ -995,10 +1000,9 @@ static void ath10k_htt_rx_msdu(struct ath10k_htt *htt, struct htt_rx_info *info)
break;
}

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

- ath10k_process_rx(htt->ar, info);
+ ath10k_process_rx(htt->ar, rx_status, skb);
}

static int ath10k_htt_rx_get_csum_state(struct sk_buff *skb)
@@ -1135,7 +1139,7 @@ static bool ath10k_htt_rx_amsdu_allowed(struct ath10k_htt *htt,
static void ath10k_htt_rx_handler(struct ath10k_htt *htt,
struct htt_rx_indication *rx)
{
- struct htt_rx_info info;
+ struct ieee80211_rx_status rx_status;
struct htt_rx_indication_mpdu_range *mpdu_ranges;
struct htt_rx_desc *rxd;
enum htt_rx_mpdu_status status;
@@ -1150,7 +1154,7 @@ static void ath10k_htt_rx_handler(struct ath10k_htt *htt,

lockdep_assert_held(&htt->rx_ring.lock);

- memset(&info, 0, sizeof(info));
+ memset(&rx_status, 0, sizeof(rx_status));

fw_desc_len = __le16_to_cpu(rx->prefix.fw_rx_desc_bytes);
fw_desc = (u8 *)&rx->fw_desc;
@@ -1160,24 +1164,23 @@ 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.rx_status.signal = ATH10K_DEFAULT_NOISE_FLOOR;
- info.rx_status.signal += rx->ppdu.combined_rssi;
+ rx_status.signal = ATH10K_DEFAULT_NOISE_FLOOR;
+ 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;
+ 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, &info.rx_status);
+ channel_set = ath10k_htt_rx_h_channel(htt->ar, &rx_status);

if (channel_set) {
- ath10k_htt_rx_h_rates(htt->ar, info.rx_status.band,
+ 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),
- &info.rx_status);
+ &rx_status);
}

ath10k_dbg_dump(ATH10K_DBG_HTT_DUMP, NULL, "htt rx ind: ",
@@ -1225,24 +1228,22 @@ static void ath10k_htt_rx_handler(struct ath10k_htt *htt,
continue;
}

- info.skb = msdu_head;
-
if (attention & RX_ATTENTION_FLAGS_FCS_ERR)
- info.rx_status.flag |= RX_FLAG_FAILED_FCS_CRC;
+ rx_status.flag |= RX_FLAG_FAILED_FCS_CRC;
else
- info.rx_status.flag &= ~RX_FLAG_FAILED_FCS_CRC;
+ rx_status.flag &= ~RX_FLAG_FAILED_FCS_CRC;

if (attention & RX_ATTENTION_FLAGS_TKIP_MIC_ERR)
- info.rx_status.flag |= RX_FLAG_MMIC_ERROR;
+ rx_status.flag |= RX_FLAG_MMIC_ERROR;
else
- info.rx_status.flag &= ~RX_FLAG_MMIC_ERROR;
+ rx_status.flag &= ~RX_FLAG_MMIC_ERROR;

hdr = ath10k_htt_rx_skb_get_hdr(msdu_head);

if (ath10k_htt_rx_hdr_is_amsdu(hdr))
- ath10k_htt_rx_amsdu(htt, &info);
+ ath10k_htt_rx_amsdu(htt, &rx_status, msdu_head);
else
- ath10k_htt_rx_msdu(htt, &info);
+ ath10k_htt_rx_msdu(htt, &rx_status, msdu_head);
}
}

@@ -1256,7 +1257,7 @@ static void ath10k_htt_rx_frag_handler(struct ath10k_htt *htt,
enum htt_rx_mpdu_encrypt_type enctype;
struct htt_rx_desc *rxd;
enum rx_msdu_decap_format fmt;
- struct htt_rx_info info = {};
+ struct ieee80211_rx_status rx_status = {};
struct ieee80211_hdr *hdr;
int ret;
bool tkip_mic_err;
@@ -1302,18 +1303,17 @@ static void ath10k_htt_rx_frag_handler(struct ath10k_htt *htt,
goto end;
}

- info.skb = msdu_head;
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);
+ ath10k_htt_rx_h_protected(htt, &rx_status, msdu_head, enctype);
+ msdu_head->ip_summed = ath10k_htt_rx_get_csum_state(msdu_head);

if (tkip_mic_err)
ath10k_warn("tkip mic error\n");

if (decrypt_err) {
ath10k_warn("decryption err in fragmented rx\n");
- dev_kfree_skb_any(info.skb);
+ dev_kfree_skb_any(msdu_head);
goto end;
}

@@ -1322,11 +1322,11 @@ static void ath10k_htt_rx_frag_handler(struct ath10k_htt *htt,
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,
- (void *)info.skb->data,
+ memmove((void *)msdu_head->data + paramlen,
+ (void *)msdu_head->data,
hdrlen);
- skb_pull(info.skb, paramlen);
- hdr = (struct ieee80211_hdr *)info.skb->data;
+ skb_pull(msdu_head, paramlen);
+ hdr = (struct ieee80211_hdr *)msdu_head->data;
}

/* remove trailing FCS */
@@ -1340,17 +1340,17 @@ static void ath10k_htt_rx_frag_handler(struct ath10k_htt *htt,
enctype == HTT_RX_MPDU_ENCRYPT_TKIP_WPA)
trim += 8;

- if (trim > info.skb->len) {
+ if (trim > msdu_head->len) {
ath10k_warn("htt rx fragment: trailer longer than the frame itself? drop\n");
- dev_kfree_skb_any(info.skb);
+ dev_kfree_skb_any(msdu_head);
goto end;
}

- skb_trim(info.skb, info.skb->len - trim);
+ skb_trim(msdu_head, msdu_head->len - trim);

ath10k_dbg_dump(ATH10K_DBG_HTT_DUMP, NULL, "htt rx frag mpdu: ",
- info.skb->data, info.skb->len);
- ath10k_process_rx(htt->ar, &info);
+ msdu_head->data, msdu_head->len);
+ ath10k_process_rx(htt->ar, &rx_status, msdu_head);

end:
if (fw_desc_len > 0) {
--
1.7.9.5


2014-03-21 09:32:50

by Janusz Dziedzic

[permalink] [raw]
Subject: [PATCH 7/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 | 94 ++++++------------------------
1 file changed, 19 insertions(+), 75 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c b/drivers/net/wireless/ath/ath10k/htt_rx.c
index 64abc2a..bc40f11 100644
--- a/drivers/net/wireless/ath/ath10k/htt_rx.c
+++ b/drivers/net/wireless/ath/ath10k/htt_rx.c
@@ -800,7 +800,7 @@ static void ath10k_process_rx(struct ath10k *ar, struct htt_rx_info *info)
memcpy(status, &info->rx_status, sizeof(*status));

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",
+ "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 %imic-err %i\n",
info->skb,
info->skb->len,
status->flag == 0 ? "legacy" : "",
@@ -813,7 +813,8 @@ static void ath10k_process_rx(struct ath10k *ar, struct htt_rx_info *info)
status->vht_nss,
status->freq,
status->band, status->flag,
- !!(status->flag & RX_FLAG_FAILED_FCS_CRC));
+ !!(status->flag & RX_FLAG_FAILED_FCS_CRC),
+ !!(status->flag & RX_FLAG_MMIC_ERROR));
ath10k_dbg_dump(ATH10K_DBG_HTT_DUMP, NULL, "rx skb: ",
info->skb->data, info->skb->len);

@@ -1000,62 +1001,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;
@@ -1141,7 +1086,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,
@@ -1149,7 +1095,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;
@@ -1162,7 +1108,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;
}
@@ -1191,12 +1137,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;

@@ -1258,9 +1206,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;
}
@@ -1273,26 +1227,16 @@ static void ath10k_htt_rx_handler(struct ath10k_htt *htt,

info.skb = msdu_head;

- 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;
else
info.rx_status.flag &= ~RX_FLAG_FAILED_FCS_CRC;

- mic_err = ath10k_htt_rx_has_mic_err(msdu_head);
- if (mic_err)
+ if (attention & RX_ATTENTION_FLAGS_TKIP_MIC_ERR)
info.rx_status.flag |= RX_FLAG_MMIC_ERROR;
else
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)
- ath10k_dbg(ATH10K_DBG_HTT,
- "htt rx has MIC err\n");
-
hdr = ath10k_htt_rx_skb_get_hdr(msdu_head);

if (ath10k_htt_rx_hdr_is_amsdu(hdr))
--
1.7.9.5


2014-03-21 09:32:47

by Janusz Dziedzic

[permalink] [raw]
Subject: [PATCH 4/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 | 53 +++++++++++++++++++-----------
1 file changed, 33 insertions(+), 20 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c b/drivers/net/wireless/ath/ath10k/htt_rx.c
index f18e41c..b37540b 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,23 +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;

- 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;
- }
-
- 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 */
@@ -1137,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;

@@ -1158,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)) {
@@ -1193,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);
@@ -1210,6 +1220,8 @@ static void ath10k_htt_rx_handler(struct ath10k_htt *htt,
info.signal = ATH10K_DEFAULT_NOISE_FLOOR;
info.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);
@@ -1236,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