* [PATCH 01/14] ath9k: Use a subroutine to check for "mybeacon"
@ 2013-08-14 3:41 Sujith Manoharan
2013-08-14 3:41 ` [PATCH 02/14] ath9k: Fix phy error handling for DFS Sujith Manoharan
` (12 more replies)
0 siblings, 13 replies; 14+ messages in thread
From: Sujith Manoharan @ 2013-08-14 3:41 UTC (permalink / raw)
To: John Linville; +Cc: linux-wireless
From: Sujith Manoharan <c_manoha@qca.qualcomm.com>
Signed-off-by: Sujith Manoharan <c_manoha@qca.qualcomm.com>
---
drivers/net/wireless/ath/ath9k/recv.c | 36 ++++++++++++++++++++++-------------
1 file changed, 23 insertions(+), 13 deletions(-)
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c
index 2dd851a..0c23053 100644
--- a/drivers/net/wireless/ath/ath9k/recv.c
+++ b/drivers/net/wireless/ath/ath9k/recv.c
@@ -1160,6 +1160,24 @@ static void ath9k_apply_ampdu_details(struct ath_softc *sc,
}
}
+static bool ath9k_is_mybeacon(struct ath_softc *sc, struct sk_buff *skb)
+{
+ struct ath_hw *ah = sc->sc_ah;
+ struct ath_common *common = ath9k_hw_common(ah);
+ struct ieee80211_hdr *hdr;
+
+ hdr = (struct ieee80211_hdr *) (skb->data + ah->caps.rx_status_len);
+
+ if (ieee80211_is_beacon(hdr->frame_control)) {
+ RX_STAT_INC(rx_beacons);
+ if (!is_zero_ether_addr(common->curbssid) &&
+ ether_addr_equal(hdr->addr3, common->curbssid))
+ return true;
+ }
+
+ return false;
+}
+
int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
{
struct ath_buf *bf;
@@ -1175,7 +1193,6 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
enum ath9k_rx_qtype qtype;
bool edma = !!(ah->caps.hw_caps & ATH9K_HW_CAP_EDMA);
int dma_type;
- u8 rx_status_len = ah->caps.rx_status_len;
u64 tsf = 0;
u32 tsf_lower = 0;
unsigned long flags;
@@ -1216,18 +1233,10 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
else
hdr_skb = skb;
- hdr = (struct ieee80211_hdr *) (hdr_skb->data + rx_status_len);
- rxs = IEEE80211_SKB_RXCB(hdr_skb);
- if (ieee80211_is_beacon(hdr->frame_control)) {
- RX_STAT_INC(rx_beacons);
- if (!is_zero_ether_addr(common->curbssid) &&
- ether_addr_equal(hdr->addr3, common->curbssid))
- rs.is_mybeacon = true;
- else
- rs.is_mybeacon = false;
- }
- else
- rs.is_mybeacon = false;
+ rs.is_mybeacon = ath9k_is_mybeacon(sc, hdr_skb);
+
+ hdr = (struct ieee80211_hdr *) (hdr_skb->data +
+ ah->caps.rx_status_len);
if (ieee80211_is_data_present(hdr->frame_control) &&
!ieee80211_is_qos_nullfunc(hdr->frame_control))
@@ -1235,6 +1244,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
ath_debug_stat_rx(sc, &rs);
+ rxs = IEEE80211_SKB_RXCB(hdr_skb);
memset(rxs, 0, sizeof(struct ieee80211_rx_status));
rxs->mactime = (tsf & ~0xffffffffULL) | rs.rs_tstamp;
--
1.8.3.4
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 02/14] ath9k: Fix phy error handling for DFS
2013-08-14 3:41 [PATCH 01/14] ath9k: Use a subroutine to check for "mybeacon" Sujith Manoharan
@ 2013-08-14 3:41 ` Sujith Manoharan
2013-08-14 3:41 ` [PATCH 03/14] ath9k: Discard invalid frames early Sujith Manoharan
` (11 subsequent siblings)
12 siblings, 0 replies; 14+ messages in thread
From: Sujith Manoharan @ 2013-08-14 3:41 UTC (permalink / raw)
To: John Linville; +Cc: linux-wireless
From: Sujith Manoharan <c_manoha@qca.qualcomm.com>
Since the DFS code appears to process the phy errors
ATH9K_PHYERR_RADAR and ATH9K_PHYERR_FALSE_RADAR_EXT,
check for the correct phyerr status in the main RX
tasklet routine.
Signed-off-by: Sujith Manoharan <c_manoha@qca.qualcomm.com>
---
drivers/net/wireless/ath/ath9k/recv.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c
index 0c23053..83b3fc5 100644
--- a/drivers/net/wireless/ath/ath9k/recv.c
+++ b/drivers/net/wireless/ath/ath9k/recv.c
@@ -1256,10 +1256,9 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
unlikely(tsf_lower - rs.rs_tstamp > 0x10000000))
rxs->mactime += 0x100000000ULL;
- if (rs.rs_phyerr == ATH9K_PHYERR_RADAR)
+ if (rs.rs_status & ATH9K_RXERR_PHY) {
ath9k_dfs_process_phyerr(sc, hdr, &rs, rxs->mactime);
- if (rs.rs_status & ATH9K_RXERR_PHY) {
if (ath_process_fft(sc, hdr, &rs, rxs->mactime)) {
RX_STAT_INC(rx_spectral);
goto requeue_drop_frag;
--
1.8.3.4
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 03/14] ath9k: Discard invalid frames early
2013-08-14 3:41 [PATCH 01/14] ath9k: Use a subroutine to check for "mybeacon" Sujith Manoharan
2013-08-14 3:41 ` [PATCH 02/14] ath9k: Fix phy error handling for DFS Sujith Manoharan
@ 2013-08-14 3:41 ` Sujith Manoharan
2013-08-14 3:41 ` [PATCH 04/14] ath9k: Fix RX crypto processing Sujith Manoharan
` (10 subsequent siblings)
12 siblings, 0 replies; 14+ messages in thread
From: Sujith Manoharan @ 2013-08-14 3:41 UTC (permalink / raw)
To: John Linville; +Cc: linux-wireless
From: Sujith Manoharan <c_manoha@qca.qualcomm.com>
Frames with invalid or zero length can be discarded
early, there is no need to check the crypto bits.
Signed-off-by: Sujith Manoharan <c_manoha@qca.qualcomm.com>
---
drivers/net/wireless/ath/ath9k/recv.c | 38 ++++++++++++++++++++---------------
1 file changed, 22 insertions(+), 16 deletions(-)
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c
index 83b3fc5..f8cc2b3 100644
--- a/drivers/net/wireless/ath/ath9k/recv.c
+++ b/drivers/net/wireless/ath/ath9k/recv.c
@@ -764,7 +764,6 @@ static bool ath9k_rx_accept(struct ath_common *common,
bool is_mc, is_valid_tkip, strip_mic, mic_error;
struct ath_hw *ah = common->ah;
__le16 fc;
- u8 rx_status_len = ah->caps.rx_status_len;
fc = hdr->frame_control;
@@ -786,21 +785,6 @@ static bool ath9k_rx_accept(struct ath_common *common,
!test_bit(rx_stats->rs_keyix, common->ccmp_keymap))
rx_stats->rs_status &= ~ATH9K_RXERR_KEYMISS;
- if (!rx_stats->rs_datalen) {
- RX_STAT_INC(rx_len_err);
- return false;
- }
-
- /*
- * rs_status follows rs_datalen so if rs_datalen is too large
- * we can take a hint that hardware corrupted it, so ignore
- * those frames.
- */
- if (rx_stats->rs_datalen > (common->rx_bufsize - rx_status_len)) {
- RX_STAT_INC(rx_len_err);
- return false;
- }
-
/* Only use error bits from the last fragment */
if (rx_stats->rs_more)
return true;
@@ -949,11 +933,33 @@ static int ath9k_rx_skb_preprocess(struct ath_softc *sc,
struct ath_common *common = ath9k_hw_common(ah);
bool discard_current = sc->rx.discard_next;
+ /*
+ * Discard corrupt descriptors which are marked in
+ * ath_get_next_rx_buf().
+ */
sc->rx.discard_next = rx_stats->rs_more;
if (discard_current)
return -EINVAL;
/*
+ * Discard zero-length packets.
+ */
+ if (!rx_stats->rs_datalen) {
+ RX_STAT_INC(rx_len_err);
+ return -EINVAL;
+ }
+
+ /*
+ * rs_status follows rs_datalen so if rs_datalen is too large
+ * we can take a hint that hardware corrupted it, so ignore
+ * those frames.
+ */
+ if (rx_stats->rs_datalen > (common->rx_bufsize - ah->caps.rx_status_len)) {
+ RX_STAT_INC(rx_len_err);
+ return -EINVAL;
+ }
+
+ /*
* everything but the rate is checked here, the rate check is done
* separately to avoid doing two lookups for a rate for each frame.
*/
--
1.8.3.4
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 04/14] ath9k: Fix RX crypto processing
2013-08-14 3:41 [PATCH 01/14] ath9k: Use a subroutine to check for "mybeacon" Sujith Manoharan
2013-08-14 3:41 ` [PATCH 02/14] ath9k: Fix phy error handling for DFS Sujith Manoharan
2013-08-14 3:41 ` [PATCH 03/14] ath9k: Discard invalid frames early Sujith Manoharan
@ 2013-08-14 3:41 ` Sujith Manoharan
2013-08-14 3:41 ` [PATCH 05/14] ath9k: Fix TSF processing Sujith Manoharan
` (9 subsequent siblings)
12 siblings, 0 replies; 14+ messages in thread
From: Sujith Manoharan @ 2013-08-14 3:41 UTC (permalink / raw)
To: John Linville; +Cc: linux-wireless
From: Sujith Manoharan <c_manoha@qca.qualcomm.com>
The keymiss events are valid only in the last descriptor
of a packet. Fix this by making sure that we return
early in case of chained descriptors.
Signed-off-by: Sujith Manoharan <c_manoha@qca.qualcomm.com>
---
drivers/net/wireless/ath/ath9k/recv.c | 12 ++++--------
1 file changed, 4 insertions(+), 8 deletions(-)
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c
index f8cc2b3..b04a971 100644
--- a/drivers/net/wireless/ath/ath9k/recv.c
+++ b/drivers/net/wireless/ath/ath9k/recv.c
@@ -785,10 +785,6 @@ static bool ath9k_rx_accept(struct ath_common *common,
!test_bit(rx_stats->rs_keyix, common->ccmp_keymap))
rx_stats->rs_status &= ~ATH9K_RXERR_KEYMISS;
- /* Only use error bits from the last fragment */
- if (rx_stats->rs_more)
- return true;
-
mic_error = is_valid_tkip && !ieee80211_is_ctl(fc) &&
!ieee80211_has_morefrags(fc) &&
!(le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG) &&
@@ -959,6 +955,10 @@ static int ath9k_rx_skb_preprocess(struct ath_softc *sc,
return -EINVAL;
}
+ /* Only use status info from the last fragment */
+ if (rx_stats->rs_more)
+ return 0;
+
/*
* everything but the rate is checked here, the rate check is done
* separately to avoid doing two lookups for a rate for each frame.
@@ -966,10 +966,6 @@ static int ath9k_rx_skb_preprocess(struct ath_softc *sc,
if (!ath9k_rx_accept(common, hdr, rx_status, rx_stats, decrypt_error))
return -EINVAL;
- /* Only use status info from the last fragment */
- if (rx_stats->rs_more)
- return 0;
-
if (ath9k_process_rate(common, hw, rx_stats, rx_status))
return -EINVAL;
--
1.8.3.4
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 05/14] ath9k: Fix TSF processing
2013-08-14 3:41 [PATCH 01/14] ath9k: Use a subroutine to check for "mybeacon" Sujith Manoharan
` (2 preceding siblings ...)
2013-08-14 3:41 ` [PATCH 04/14] ath9k: Fix RX crypto processing Sujith Manoharan
@ 2013-08-14 3:41 ` Sujith Manoharan
2013-08-14 3:41 ` [PATCH 06/14] ath9k: Reorder some functions Sujith Manoharan
` (8 subsequent siblings)
12 siblings, 0 replies; 14+ messages in thread
From: Sujith Manoharan @ 2013-08-14 3:41 UTC (permalink / raw)
To: John Linville; +Cc: linux-wireless
From: Sujith Manoharan <c_manoha@qca.qualcomm.com>
There is no need to calculate the mactime for chained
descriptor packets, so make sure that this is done
only for the last fragment of valid packets.
Signed-off-by: Sujith Manoharan <c_manoha@qca.qualcomm.com>
---
drivers/net/wireless/ath/ath9k/recv.c | 33 ++++++++++++++++++++-------------
1 file changed, 20 insertions(+), 13 deletions(-)
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c
index b04a971..9fabd5f 100644
--- a/drivers/net/wireless/ath/ath9k/recv.c
+++ b/drivers/net/wireless/ath/ath9k/recv.c
@@ -913,6 +913,22 @@ static void ath9k_process_rssi(struct ath_common *common,
ah->stats.avgbrssi = rssi;
}
+static void ath9k_process_tsf(struct ath_rx_status *rs,
+ struct ieee80211_rx_status *rxs,
+ u64 tsf)
+{
+ u32 tsf_lower = tsf & 0xffffffff;
+
+ rxs->mactime = (tsf & ~0xffffffffULL) | rs->rs_tstamp;
+ if (rs->rs_tstamp > tsf_lower &&
+ unlikely(rs->rs_tstamp - tsf_lower > 0x10000000))
+ rxs->mactime -= 0x100000000ULL;
+
+ if (rs->rs_tstamp < tsf_lower &&
+ unlikely(tsf_lower - rs->rs_tstamp > 0x10000000))
+ rxs->mactime += 0x100000000ULL;
+}
+
/*
* For Decrypt or Demic errors, we only mark packet status here and always push
* up the frame up to let mac80211 handle the actual error case, be it no
@@ -922,7 +938,7 @@ static int ath9k_rx_skb_preprocess(struct ath_softc *sc,
struct ieee80211_hdr *hdr,
struct ath_rx_status *rx_stats,
struct ieee80211_rx_status *rx_status,
- bool *decrypt_error)
+ bool *decrypt_error, u64 tsf)
{
struct ieee80211_hw *hw = sc->hw;
struct ath_hw *ah = sc->sc_ah;
@@ -959,6 +975,8 @@ static int ath9k_rx_skb_preprocess(struct ath_softc *sc,
if (rx_stats->rs_more)
return 0;
+ ath9k_process_tsf(rx_stats, rx_status, tsf);
+
/*
* everything but the rate is checked here, the rate check is done
* separately to avoid doing two lookups for a rate for each frame.
@@ -1196,7 +1214,6 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
bool edma = !!(ah->caps.hw_caps & ATH9K_HW_CAP_EDMA);
int dma_type;
u64 tsf = 0;
- u32 tsf_lower = 0;
unsigned long flags;
dma_addr_t new_buf_addr;
@@ -1208,7 +1225,6 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
qtype = hp ? ATH9K_RX_QUEUE_HP : ATH9K_RX_QUEUE_LP;
tsf = ath9k_hw_gettsf64(ah);
- tsf_lower = tsf & 0xffffffff;
do {
bool decrypt_error = false;
@@ -1249,15 +1265,6 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
rxs = IEEE80211_SKB_RXCB(hdr_skb);
memset(rxs, 0, sizeof(struct ieee80211_rx_status));
- rxs->mactime = (tsf & ~0xffffffffULL) | rs.rs_tstamp;
- if (rs.rs_tstamp > tsf_lower &&
- unlikely(rs.rs_tstamp - tsf_lower > 0x10000000))
- rxs->mactime -= 0x100000000ULL;
-
- if (rs.rs_tstamp < tsf_lower &&
- unlikely(tsf_lower - rs.rs_tstamp > 0x10000000))
- rxs->mactime += 0x100000000ULL;
-
if (rs.rs_status & ATH9K_RXERR_PHY) {
ath9k_dfs_process_phyerr(sc, hdr, &rs, rxs->mactime);
@@ -1268,7 +1275,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
}
retval = ath9k_rx_skb_preprocess(sc, hdr, &rs, rxs,
- &decrypt_error);
+ &decrypt_error, tsf);
if (retval)
goto requeue_drop_frag;
--
1.8.3.4
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 06/14] ath9k: Reorder some functions
2013-08-14 3:41 [PATCH 01/14] ath9k: Use a subroutine to check for "mybeacon" Sujith Manoharan
` (3 preceding siblings ...)
2013-08-14 3:41 ` [PATCH 05/14] ath9k: Fix TSF processing Sujith Manoharan
@ 2013-08-14 3:41 ` Sujith Manoharan
2013-08-14 3:41 ` [PATCH 07/14] ath9k: Fix PHY error processing Sujith Manoharan
` (7 subsequent siblings)
12 siblings, 0 replies; 14+ messages in thread
From: Sujith Manoharan @ 2013-08-14 3:41 UTC (permalink / raw)
To: John Linville; +Cc: linux-wireless
From: Sujith Manoharan <c_manoha@qca.qualcomm.com>
Signed-off-by: Sujith Manoharan <c_manoha@qca.qualcomm.com>
---
drivers/net/wireless/ath/ath9k/recv.c | 220 +++++++++++++++++-----------------
1 file changed, 110 insertions(+), 110 deletions(-)
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c
index 9fabd5f..51e7d16 100644
--- a/drivers/net/wireless/ath/ath9k/recv.c
+++ b/drivers/net/wireless/ath/ath9k/recv.c
@@ -929,6 +929,116 @@ static void ath9k_process_tsf(struct ath_rx_status *rs,
rxs->mactime += 0x100000000ULL;
}
+#ifdef CONFIG_ATH9K_DEBUGFS
+static s8 fix_rssi_inv_only(u8 rssi_val)
+{
+ if (rssi_val == 128)
+ rssi_val = 0;
+ return (s8) rssi_val;
+}
+#endif
+
+/* returns 1 if this was a spectral frame, even if not handled. */
+static int ath_process_fft(struct ath_softc *sc, struct ieee80211_hdr *hdr,
+ struct ath_rx_status *rs, u64 tsf)
+{
+#ifdef CONFIG_ATH9K_DEBUGFS
+ struct ath_hw *ah = sc->sc_ah;
+ u8 bins[SPECTRAL_HT20_NUM_BINS];
+ u8 *vdata = (u8 *)hdr;
+ struct fft_sample_ht20 fft_sample;
+ struct ath_radar_info *radar_info;
+ struct ath_ht20_mag_info *mag_info;
+ int len = rs->rs_datalen;
+ int dc_pos;
+ u16 length, max_magnitude;
+
+ /* AR9280 and before report via ATH9K_PHYERR_RADAR, AR93xx and newer
+ * via ATH9K_PHYERR_SPECTRAL. Haven't seen ATH9K_PHYERR_FALSE_RADAR_EXT
+ * yet, but this is supposed to be possible as well.
+ */
+ if (rs->rs_phyerr != ATH9K_PHYERR_RADAR &&
+ rs->rs_phyerr != ATH9K_PHYERR_FALSE_RADAR_EXT &&
+ rs->rs_phyerr != ATH9K_PHYERR_SPECTRAL)
+ return 0;
+
+ /* check if spectral scan bit is set. This does not have to be checked
+ * if received through a SPECTRAL phy error, but shouldn't hurt.
+ */
+ radar_info = ((struct ath_radar_info *)&vdata[len]) - 1;
+ if (!(radar_info->pulse_bw_info & SPECTRAL_SCAN_BITMASK))
+ return 0;
+
+ /* Variation in the data length is possible and will be fixed later.
+ * Note that we only support HT20 for now.
+ *
+ * TODO: add HT20_40 support as well.
+ */
+ if ((len > SPECTRAL_HT20_TOTAL_DATA_LEN + 2) ||
+ (len < SPECTRAL_HT20_TOTAL_DATA_LEN - 1))
+ return 1;
+
+ fft_sample.tlv.type = ATH_FFT_SAMPLE_HT20;
+ length = sizeof(fft_sample) - sizeof(fft_sample.tlv);
+ fft_sample.tlv.length = __cpu_to_be16(length);
+
+ fft_sample.freq = __cpu_to_be16(ah->curchan->chan->center_freq);
+ fft_sample.rssi = fix_rssi_inv_only(rs->rs_rssi_ctl0);
+ fft_sample.noise = ah->noise;
+
+ switch (len - SPECTRAL_HT20_TOTAL_DATA_LEN) {
+ case 0:
+ /* length correct, nothing to do. */
+ memcpy(bins, vdata, SPECTRAL_HT20_NUM_BINS);
+ break;
+ case -1:
+ /* first byte missing, duplicate it. */
+ memcpy(&bins[1], vdata, SPECTRAL_HT20_NUM_BINS - 1);
+ bins[0] = vdata[0];
+ break;
+ case 2:
+ /* MAC added 2 extra bytes at bin 30 and 32, remove them. */
+ memcpy(bins, vdata, 30);
+ bins[30] = vdata[31];
+ memcpy(&bins[31], &vdata[33], SPECTRAL_HT20_NUM_BINS - 31);
+ break;
+ case 1:
+ /* MAC added 2 extra bytes AND first byte is missing. */
+ bins[0] = vdata[0];
+ memcpy(&bins[0], vdata, 30);
+ bins[31] = vdata[31];
+ memcpy(&bins[32], &vdata[33], SPECTRAL_HT20_NUM_BINS - 32);
+ break;
+ default:
+ return 1;
+ }
+
+ /* DC value (value in the middle) is the blind spot of the spectral
+ * sample and invalid, interpolate it.
+ */
+ dc_pos = SPECTRAL_HT20_NUM_BINS / 2;
+ bins[dc_pos] = (bins[dc_pos + 1] + bins[dc_pos - 1]) / 2;
+
+ /* mag data is at the end of the frame, in front of radar_info */
+ mag_info = ((struct ath_ht20_mag_info *)radar_info) - 1;
+
+ /* copy raw bins without scaling them */
+ memcpy(fft_sample.data, bins, SPECTRAL_HT20_NUM_BINS);
+ fft_sample.max_exp = mag_info->max_exp & 0xf;
+
+ max_magnitude = spectral_max_magnitude(mag_info->all_bins);
+ fft_sample.max_magnitude = __cpu_to_be16(max_magnitude);
+ fft_sample.max_index = spectral_max_index(mag_info->all_bins);
+ fft_sample.bitmap_weight = spectral_bitmap_weight(mag_info->all_bins);
+ fft_sample.tsf = __cpu_to_be64(tsf);
+
+ ath_debug_send_fft_sample(sc, &fft_sample.tlv);
+ return 1;
+#else
+ return 0;
+#endif
+}
+
/*
* For Decrypt or Demic errors, we only mark packet status here and always push
* up the frame up to let mac80211 handle the actual error case, be it no
@@ -1052,116 +1162,6 @@ static void ath9k_rx_skb_postprocess(struct ath_common *common,
rxs->flag &= ~RX_FLAG_DECRYPTED;
}
-#ifdef CONFIG_ATH9K_DEBUGFS
-static s8 fix_rssi_inv_only(u8 rssi_val)
-{
- if (rssi_val == 128)
- rssi_val = 0;
- return (s8) rssi_val;
-}
-#endif
-
-/* returns 1 if this was a spectral frame, even if not handled. */
-static int ath_process_fft(struct ath_softc *sc, struct ieee80211_hdr *hdr,
- struct ath_rx_status *rs, u64 tsf)
-{
-#ifdef CONFIG_ATH9K_DEBUGFS
- struct ath_hw *ah = sc->sc_ah;
- u8 bins[SPECTRAL_HT20_NUM_BINS];
- u8 *vdata = (u8 *)hdr;
- struct fft_sample_ht20 fft_sample;
- struct ath_radar_info *radar_info;
- struct ath_ht20_mag_info *mag_info;
- int len = rs->rs_datalen;
- int dc_pos;
- u16 length, max_magnitude;
-
- /* AR9280 and before report via ATH9K_PHYERR_RADAR, AR93xx and newer
- * via ATH9K_PHYERR_SPECTRAL. Haven't seen ATH9K_PHYERR_FALSE_RADAR_EXT
- * yet, but this is supposed to be possible as well.
- */
- if (rs->rs_phyerr != ATH9K_PHYERR_RADAR &&
- rs->rs_phyerr != ATH9K_PHYERR_FALSE_RADAR_EXT &&
- rs->rs_phyerr != ATH9K_PHYERR_SPECTRAL)
- return 0;
-
- /* check if spectral scan bit is set. This does not have to be checked
- * if received through a SPECTRAL phy error, but shouldn't hurt.
- */
- radar_info = ((struct ath_radar_info *)&vdata[len]) - 1;
- if (!(radar_info->pulse_bw_info & SPECTRAL_SCAN_BITMASK))
- return 0;
-
- /* Variation in the data length is possible and will be fixed later.
- * Note that we only support HT20 for now.
- *
- * TODO: add HT20_40 support as well.
- */
- if ((len > SPECTRAL_HT20_TOTAL_DATA_LEN + 2) ||
- (len < SPECTRAL_HT20_TOTAL_DATA_LEN - 1))
- return 1;
-
- fft_sample.tlv.type = ATH_FFT_SAMPLE_HT20;
- length = sizeof(fft_sample) - sizeof(fft_sample.tlv);
- fft_sample.tlv.length = __cpu_to_be16(length);
-
- fft_sample.freq = __cpu_to_be16(ah->curchan->chan->center_freq);
- fft_sample.rssi = fix_rssi_inv_only(rs->rs_rssi_ctl0);
- fft_sample.noise = ah->noise;
-
- switch (len - SPECTRAL_HT20_TOTAL_DATA_LEN) {
- case 0:
- /* length correct, nothing to do. */
- memcpy(bins, vdata, SPECTRAL_HT20_NUM_BINS);
- break;
- case -1:
- /* first byte missing, duplicate it. */
- memcpy(&bins[1], vdata, SPECTRAL_HT20_NUM_BINS - 1);
- bins[0] = vdata[0];
- break;
- case 2:
- /* MAC added 2 extra bytes at bin 30 and 32, remove them. */
- memcpy(bins, vdata, 30);
- bins[30] = vdata[31];
- memcpy(&bins[31], &vdata[33], SPECTRAL_HT20_NUM_BINS - 31);
- break;
- case 1:
- /* MAC added 2 extra bytes AND first byte is missing. */
- bins[0] = vdata[0];
- memcpy(&bins[0], vdata, 30);
- bins[31] = vdata[31];
- memcpy(&bins[32], &vdata[33], SPECTRAL_HT20_NUM_BINS - 32);
- break;
- default:
- return 1;
- }
-
- /* DC value (value in the middle) is the blind spot of the spectral
- * sample and invalid, interpolate it.
- */
- dc_pos = SPECTRAL_HT20_NUM_BINS / 2;
- bins[dc_pos] = (bins[dc_pos + 1] + bins[dc_pos - 1]) / 2;
-
- /* mag data is at the end of the frame, in front of radar_info */
- mag_info = ((struct ath_ht20_mag_info *)radar_info) - 1;
-
- /* copy raw bins without scaling them */
- memcpy(fft_sample.data, bins, SPECTRAL_HT20_NUM_BINS);
- fft_sample.max_exp = mag_info->max_exp & 0xf;
-
- max_magnitude = spectral_max_magnitude(mag_info->all_bins);
- fft_sample.max_magnitude = __cpu_to_be16(max_magnitude);
- fft_sample.max_index = spectral_max_index(mag_info->all_bins);
- fft_sample.bitmap_weight = spectral_bitmap_weight(mag_info->all_bins);
- fft_sample.tsf = __cpu_to_be64(tsf);
-
- ath_debug_send_fft_sample(sc, &fft_sample.tlv);
- return 1;
-#else
- return 0;
-#endif
-}
-
static void ath9k_apply_ampdu_details(struct ath_softc *sc,
struct ath_rx_status *rs, struct ieee80211_rx_status *rxs)
{
--
1.8.3.4
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 07/14] ath9k: Fix PHY error processing
2013-08-14 3:41 [PATCH 01/14] ath9k: Use a subroutine to check for "mybeacon" Sujith Manoharan
` (4 preceding siblings ...)
2013-08-14 3:41 ` [PATCH 06/14] ath9k: Reorder some functions Sujith Manoharan
@ 2013-08-14 3:41 ` Sujith Manoharan
2013-08-14 3:41 ` [PATCH 08/14] ath9k: Fix RX debug statistics Sujith Manoharan
` (6 subsequent siblings)
12 siblings, 0 replies; 14+ messages in thread
From: Sujith Manoharan @ 2013-08-14 3:41 UTC (permalink / raw)
To: John Linville; +Cc: linux-wireless
From: Sujith Manoharan <c_manoha@qca.qualcomm.com>
Parse the PHY error details only for the last fragment
in case descriptors are chained.
Signed-off-by: Sujith Manoharan <c_manoha@qca.qualcomm.com>
---
drivers/net/wireless/ath/ath9k/recv.c | 23 ++++++++++++-----------
1 file changed, 12 insertions(+), 11 deletions(-)
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c
index 51e7d16..e18adde 100644
--- a/drivers/net/wireless/ath/ath9k/recv.c
+++ b/drivers/net/wireless/ath/ath9k/recv.c
@@ -803,8 +803,6 @@ static bool ath9k_rx_accept(struct ath_common *common,
rxs->flag |= RX_FLAG_FAILED_FCS_CRC;
mic_error = false;
}
- if (rx_stats->rs_status & ATH9K_RXERR_PHY)
- return false;
if ((rx_stats->rs_status & ATH9K_RXERR_DECRYPT) ||
(!is_mc && (rx_stats->rs_status & ATH9K_RXERR_KEYMISS))) {
@@ -1088,6 +1086,18 @@ static int ath9k_rx_skb_preprocess(struct ath_softc *sc,
ath9k_process_tsf(rx_stats, rx_status, tsf);
/*
+ * Process PHY errors and return so that the packet
+ * can be dropped.
+ */
+ if (rx_stats->rs_status & ATH9K_RXERR_PHY) {
+ ath9k_dfs_process_phyerr(sc, hdr, rx_stats, rx_status->mactime);
+ if (ath_process_fft(sc, hdr, rx_stats, rx_status->mactime))
+ RX_STAT_INC(rx_spectral);
+
+ return -EINVAL;
+ }
+
+ /*
* everything but the rate is checked here, the rate check is done
* separately to avoid doing two lookups for a rate for each frame.
*/
@@ -1265,15 +1275,6 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
rxs = IEEE80211_SKB_RXCB(hdr_skb);
memset(rxs, 0, sizeof(struct ieee80211_rx_status));
- if (rs.rs_status & ATH9K_RXERR_PHY) {
- ath9k_dfs_process_phyerr(sc, hdr, &rs, rxs->mactime);
-
- if (ath_process_fft(sc, hdr, &rs, rxs->mactime)) {
- RX_STAT_INC(rx_spectral);
- goto requeue_drop_frag;
- }
- }
-
retval = ath9k_rx_skb_preprocess(sc, hdr, &rs, rxs,
&decrypt_error, tsf);
if (retval)
--
1.8.3.4
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 08/14] ath9k: Fix RX debug statistics
2013-08-14 3:41 [PATCH 01/14] ath9k: Use a subroutine to check for "mybeacon" Sujith Manoharan
` (5 preceding siblings ...)
2013-08-14 3:41 ` [PATCH 07/14] ath9k: Fix PHY error processing Sujith Manoharan
@ 2013-08-14 3:41 ` Sujith Manoharan
2013-08-14 3:41 ` [PATCH 09/14] ath9k: Fix RX packet counter Sujith Manoharan
` (5 subsequent siblings)
12 siblings, 0 replies; 14+ messages in thread
From: Sujith Manoharan @ 2013-08-14 3:41 UTC (permalink / raw)
To: John Linville; +Cc: linux-wireless
From: Sujith Manoharan <c_manoha@qca.qualcomm.com>
The various error bits that ath_debug_stat_rx()
checks are valid only for the last descriptor for
a chained packet, handle this correctly.
Signed-off-by: Sujith Manoharan <c_manoha@qca.qualcomm.com>
---
drivers/net/wireless/ath/ath9k/recv.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c
index e18adde..2d0017c 100644
--- a/drivers/net/wireless/ath/ath9k/recv.c
+++ b/drivers/net/wireless/ath/ath9k/recv.c
@@ -1084,6 +1084,7 @@ static int ath9k_rx_skb_preprocess(struct ath_softc *sc,
return 0;
ath9k_process_tsf(rx_stats, rx_status, tsf);
+ ath_debug_stat_rx(sc, rx_stats);
/*
* Process PHY errors and return so that the packet
@@ -1270,8 +1271,6 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
!ieee80211_is_qos_nullfunc(hdr->frame_control))
sc->rx.num_pkts++;
- ath_debug_stat_rx(sc, &rs);
-
rxs = IEEE80211_SKB_RXCB(hdr_skb);
memset(rxs, 0, sizeof(struct ieee80211_rx_status));
--
1.8.3.4
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 09/14] ath9k: Fix RX packet counter
2013-08-14 3:41 [PATCH 01/14] ath9k: Use a subroutine to check for "mybeacon" Sujith Manoharan
` (6 preceding siblings ...)
2013-08-14 3:41 ` [PATCH 08/14] ath9k: Fix RX debug statistics Sujith Manoharan
@ 2013-08-14 3:41 ` Sujith Manoharan
2013-08-14 3:41 ` [PATCH 10/14] ath9k: Fix RX beacon processing Sujith Manoharan
` (4 subsequent siblings)
12 siblings, 0 replies; 14+ messages in thread
From: Sujith Manoharan @ 2013-08-14 3:41 UTC (permalink / raw)
To: John Linville; +Cc: linux-wireless
From: Sujith Manoharan <c_manoha@qca.qualcomm.com>
Handle chained descriptors and increment the RX counter
only for valid packets. Since this is used only by MCI,
use CONFIG_ATH9K_BTCOEX_SUPPORT.
Signed-off-by: Sujith Manoharan <c_manoha@qca.qualcomm.com>
---
drivers/net/wireless/ath/ath9k/recv.c | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c
index 2d0017c..823b411 100644
--- a/drivers/net/wireless/ath/ath9k/recv.c
+++ b/drivers/net/wireless/ath/ath9k/recv.c
@@ -1119,6 +1119,13 @@ static int ath9k_rx_skb_preprocess(struct ath_softc *sc,
rx_status->flag |= RX_FLAG_NO_SIGNAL_VAL;
sc->rx.discard_next = false;
+
+#ifdef CONFIG_ATH9K_BTCOEX_SUPPORT
+ if (ieee80211_is_data_present(hdr->frame_control) &&
+ !ieee80211_is_qos_nullfunc(hdr->frame_control))
+ sc->rx.num_pkts++;
+#endif
+
return 0;
}
@@ -1267,10 +1274,6 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
hdr = (struct ieee80211_hdr *) (hdr_skb->data +
ah->caps.rx_status_len);
- if (ieee80211_is_data_present(hdr->frame_control) &&
- !ieee80211_is_qos_nullfunc(hdr->frame_control))
- sc->rx.num_pkts++;
-
rxs = IEEE80211_SKB_RXCB(hdr_skb);
memset(rxs, 0, sizeof(struct ieee80211_rx_status));
--
1.8.3.4
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 10/14] ath9k: Fix RX beacon processing
2013-08-14 3:41 [PATCH 01/14] ath9k: Use a subroutine to check for "mybeacon" Sujith Manoharan
` (7 preceding siblings ...)
2013-08-14 3:41 ` [PATCH 09/14] ath9k: Fix RX packet counter Sujith Manoharan
@ 2013-08-14 3:41 ` Sujith Manoharan
2013-08-14 3:41 ` [PATCH 11/14] ath9k: Move the RX poll check to preprocess() Sujith Manoharan
` (3 subsequent siblings)
12 siblings, 0 replies; 14+ messages in thread
From: Sujith Manoharan @ 2013-08-14 3:41 UTC (permalink / raw)
To: John Linville; +Cc: linux-wireless
From: Sujith Manoharan <c_manoha@qca.qualcomm.com>
Make sure that chained descriptors are handled correctly
before the packet is parsed to determine if it is a beacon.
Signed-off-by: Sujith Manoharan <c_manoha@qca.qualcomm.com>
---
drivers/net/wireless/ath/ath9k/recv.c | 48 ++++++++++++++++-------------------
1 file changed, 22 insertions(+), 26 deletions(-)
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c
index 823b411..090c27e 100644
--- a/drivers/net/wireless/ath/ath9k/recv.c
+++ b/drivers/net/wireless/ath/ath9k/recv.c
@@ -1037,13 +1037,28 @@ static int ath_process_fft(struct ath_softc *sc, struct ieee80211_hdr *hdr,
#endif
}
+static bool ath9k_is_mybeacon(struct ath_softc *sc, struct ieee80211_hdr *hdr)
+{
+ struct ath_hw *ah = sc->sc_ah;
+ struct ath_common *common = ath9k_hw_common(ah);
+
+ if (ieee80211_is_beacon(hdr->frame_control)) {
+ RX_STAT_INC(rx_beacons);
+ if (!is_zero_ether_addr(common->curbssid) &&
+ ether_addr_equal(hdr->addr3, common->curbssid))
+ return true;
+ }
+
+ return false;
+}
+
/*
* For Decrypt or Demic errors, we only mark packet status here and always push
* up the frame up to let mac80211 handle the actual error case, be it no
* decryption key or real decryption error. This let us keep statistics there.
*/
static int ath9k_rx_skb_preprocess(struct ath_softc *sc,
- struct ieee80211_hdr *hdr,
+ struct sk_buff *skb,
struct ath_rx_status *rx_stats,
struct ieee80211_rx_status *rx_status,
bool *decrypt_error, u64 tsf)
@@ -1051,6 +1066,7 @@ static int ath9k_rx_skb_preprocess(struct ath_softc *sc,
struct ieee80211_hw *hw = sc->hw;
struct ath_hw *ah = sc->sc_ah;
struct ath_common *common = ath9k_hw_common(ah);
+ struct ieee80211_hdr *hdr;
bool discard_current = sc->rx.discard_next;
/*
@@ -1083,6 +1099,8 @@ static int ath9k_rx_skb_preprocess(struct ath_softc *sc,
if (rx_stats->rs_more)
return 0;
+ hdr = (struct ieee80211_hdr *) (skb->data + ah->caps.rx_status_len);
+
ath9k_process_tsf(rx_stats, rx_status, tsf);
ath_debug_stat_rx(sc, rx_stats);
@@ -1105,6 +1123,8 @@ static int ath9k_rx_skb_preprocess(struct ath_softc *sc,
if (!ath9k_rx_accept(common, hdr, rx_status, rx_stats, decrypt_error))
return -EINVAL;
+ rx_stats->is_mybeacon = ath9k_is_mybeacon(sc, hdr);
+
if (ath9k_process_rate(common, hw, rx_stats, rx_status))
return -EINVAL;
@@ -1198,24 +1218,6 @@ static void ath9k_apply_ampdu_details(struct ath_softc *sc,
}
}
-static bool ath9k_is_mybeacon(struct ath_softc *sc, struct sk_buff *skb)
-{
- struct ath_hw *ah = sc->sc_ah;
- struct ath_common *common = ath9k_hw_common(ah);
- struct ieee80211_hdr *hdr;
-
- hdr = (struct ieee80211_hdr *) (skb->data + ah->caps.rx_status_len);
-
- if (ieee80211_is_beacon(hdr->frame_control)) {
- RX_STAT_INC(rx_beacons);
- if (!is_zero_ether_addr(common->curbssid) &&
- ether_addr_equal(hdr->addr3, common->curbssid))
- return true;
- }
-
- return false;
-}
-
int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
{
struct ath_buf *bf;
@@ -1225,7 +1227,6 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
struct ath9k_hw_capabilities *pCap = &ah->caps;
struct ath_common *common = ath9k_hw_common(ah);
struct ieee80211_hw *hw = sc->hw;
- struct ieee80211_hdr *hdr;
int retval;
struct ath_rx_status rs;
enum ath9k_rx_qtype qtype;
@@ -1269,15 +1270,10 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
else
hdr_skb = skb;
- rs.is_mybeacon = ath9k_is_mybeacon(sc, hdr_skb);
-
- hdr = (struct ieee80211_hdr *) (hdr_skb->data +
- ah->caps.rx_status_len);
-
rxs = IEEE80211_SKB_RXCB(hdr_skb);
memset(rxs, 0, sizeof(struct ieee80211_rx_status));
- retval = ath9k_rx_skb_preprocess(sc, hdr, &rs, rxs,
+ retval = ath9k_rx_skb_preprocess(sc, hdr_skb, &rs, rxs,
&decrypt_error, tsf);
if (retval)
goto requeue_drop_frag;
--
1.8.3.4
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 11/14] ath9k: Move the RX poll check to preprocess()
2013-08-14 3:41 [PATCH 01/14] ath9k: Use a subroutine to check for "mybeacon" Sujith Manoharan
` (8 preceding siblings ...)
2013-08-14 3:41 ` [PATCH 10/14] ath9k: Fix RX beacon processing Sujith Manoharan
@ 2013-08-14 3:41 ` Sujith Manoharan
2013-08-14 3:41 ` [PATCH 12/14] ath9k: Handle corrupt descriptors properly Sujith Manoharan
` (2 subsequent siblings)
12 siblings, 0 replies; 14+ messages in thread
From: Sujith Manoharan @ 2013-08-14 3:41 UTC (permalink / raw)
To: John Linville; +Cc: linux-wireless
From: Sujith Manoharan <c_manoha@qca.qualcomm.com>
Signed-off-by: Sujith Manoharan <c_manoha@qca.qualcomm.com>
---
drivers/net/wireless/ath/ath9k/recv.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c
index 090c27e..5b84ce4 100644
--- a/drivers/net/wireless/ath/ath9k/recv.c
+++ b/drivers/net/wireless/ath/ath9k/recv.c
@@ -1124,6 +1124,10 @@ static int ath9k_rx_skb_preprocess(struct ath_softc *sc,
return -EINVAL;
rx_stats->is_mybeacon = ath9k_is_mybeacon(sc, hdr);
+ if (rx_stats->is_mybeacon) {
+ sc->hw_busy_count = 0;
+ ath_start_rx_poll(sc, 3);
+ }
if (ath9k_process_rate(common, hw, rx_stats, rx_status))
return -EINVAL;
@@ -1278,10 +1282,6 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
if (retval)
goto requeue_drop_frag;
- if (rs.is_mybeacon) {
- sc->hw_busy_count = 0;
- ath_start_rx_poll(sc, 3);
- }
/* Ensure we always have an skb to requeue once we are done
* processing the current buffer's skb */
requeue_skb = ath_rxbuf_alloc(common, common->rx_bufsize, GFP_ATOMIC);
--
1.8.3.4
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 12/14] ath9k: Handle corrupt descriptors properly
2013-08-14 3:41 [PATCH 01/14] ath9k: Use a subroutine to check for "mybeacon" Sujith Manoharan
` (9 preceding siblings ...)
2013-08-14 3:41 ` [PATCH 11/14] ath9k: Move the RX poll check to preprocess() Sujith Manoharan
@ 2013-08-14 3:41 ` Sujith Manoharan
2013-08-14 3:41 ` [PATCH 13/14] ath9k: Fix error condition for corrupt descriptors Sujith Manoharan
2013-08-14 3:41 ` [PATCH 14/14] ath9k: Remove unused function argument Sujith Manoharan
12 siblings, 0 replies; 14+ messages in thread
From: Sujith Manoharan @ 2013-08-14 3:41 UTC (permalink / raw)
To: John Linville; +Cc: linux-wireless
From: Sujith Manoharan <c_manoha@qca.qualcomm.com>
The MIC/PHYERR/CRC error bits are valid only for
the last desc. for chained packets. Check this early
in the preprocess() routine and bail out.
Signed-off-by: Sujith Manoharan <c_manoha@qca.qualcomm.com>
---
drivers/net/wireless/ath/ath9k/recv.c | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c
index 5b84ce4..30cb726 100644
--- a/drivers/net/wireless/ath/ath9k/recv.c
+++ b/drivers/net/wireless/ath/ath9k/recv.c
@@ -1099,6 +1099,16 @@ static int ath9k_rx_skb_preprocess(struct ath_softc *sc,
if (rx_stats->rs_more)
return 0;
+ /*
+ * Return immediately if the RX descriptor has been marked
+ * as corrupt based on the various error bits.
+ *
+ * This is different from the other corrupt descriptor
+ * condition handled above.
+ */
+ if (rx_stats->rs_status & ATH9K_RXERR_CORRUPT_DESC)
+ return -EINVAL;
+
hdr = (struct ieee80211_hdr *) (skb->data + ah->caps.rx_status_len);
ath9k_process_tsf(rx_stats, rx_status, tsf);
@@ -1335,8 +1345,6 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
sc->rx.frag = skb;
goto requeue;
}
- if (rs.rs_status & ATH9K_RXERR_CORRUPT_DESC)
- goto requeue_drop_frag;
if (sc->rx.frag) {
int space = skb->len - skb_tailroom(hdr_skb);
--
1.8.3.4
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 13/14] ath9k: Fix error condition for corrupt descriptors
2013-08-14 3:41 [PATCH 01/14] ath9k: Use a subroutine to check for "mybeacon" Sujith Manoharan
` (10 preceding siblings ...)
2013-08-14 3:41 ` [PATCH 12/14] ath9k: Handle corrupt descriptors properly Sujith Manoharan
@ 2013-08-14 3:41 ` Sujith Manoharan
2013-08-14 3:41 ` [PATCH 14/14] ath9k: Remove unused function argument Sujith Manoharan
12 siblings, 0 replies; 14+ messages in thread
From: Sujith Manoharan @ 2013-08-14 3:41 UTC (permalink / raw)
To: John Linville; +Cc: linux-wireless
From: Sujith Manoharan <c_manoha@qca.qualcomm.com>
In case a descriptor has the "done" bit clear and the
next descriptor has it set, we drop both of them. If
the packet that is received after these two packets
is dropped for some reason, "discard_next" will not cleared.
Fix this.
Signed-off-by: Sujith Manoharan <c_manoha@qca.qualcomm.com>
---
drivers/net/wireless/ath/ath9k/recv.c | 28 ++++++++++++++++++----------
1 file changed, 18 insertions(+), 10 deletions(-)
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c
index 30cb726..ec89280 100644
--- a/drivers/net/wireless/ath/ath9k/recv.c
+++ b/drivers/net/wireless/ath/ath9k/recv.c
@@ -1068,6 +1068,7 @@ static int ath9k_rx_skb_preprocess(struct ath_softc *sc,
struct ath_common *common = ath9k_hw_common(ah);
struct ieee80211_hdr *hdr;
bool discard_current = sc->rx.discard_next;
+ int ret = 0;
/*
* Discard corrupt descriptors which are marked in
@@ -1106,8 +1107,10 @@ static int ath9k_rx_skb_preprocess(struct ath_softc *sc,
* This is different from the other corrupt descriptor
* condition handled above.
*/
- if (rx_stats->rs_status & ATH9K_RXERR_CORRUPT_DESC)
- return -EINVAL;
+ if (rx_stats->rs_status & ATH9K_RXERR_CORRUPT_DESC) {
+ ret = -EINVAL;
+ goto exit;
+ }
hdr = (struct ieee80211_hdr *) (skb->data + ah->caps.rx_status_len);
@@ -1123,15 +1126,18 @@ static int ath9k_rx_skb_preprocess(struct ath_softc *sc,
if (ath_process_fft(sc, hdr, rx_stats, rx_status->mactime))
RX_STAT_INC(rx_spectral);
- return -EINVAL;
+ ret = -EINVAL;
+ goto exit;
}
/*
* everything but the rate is checked here, the rate check is done
* separately to avoid doing two lookups for a rate for each frame.
*/
- if (!ath9k_rx_accept(common, hdr, rx_status, rx_stats, decrypt_error))
- return -EINVAL;
+ if (!ath9k_rx_accept(common, hdr, rx_status, rx_stats, decrypt_error)) {
+ ret = -EINVAL;
+ goto exit;
+ }
rx_stats->is_mybeacon = ath9k_is_mybeacon(sc, hdr);
if (rx_stats->is_mybeacon) {
@@ -1139,8 +1145,10 @@ static int ath9k_rx_skb_preprocess(struct ath_softc *sc,
ath_start_rx_poll(sc, 3);
}
- if (ath9k_process_rate(common, hw, rx_stats, rx_status))
- return -EINVAL;
+ if (ath9k_process_rate(common, hw, rx_stats, rx_status)) {
+ ret =-EINVAL;
+ goto exit;
+ }
ath9k_process_rssi(common, hw, hdr, rx_stats);
@@ -1152,15 +1160,15 @@ static int ath9k_rx_skb_preprocess(struct ath_softc *sc,
if (rx_stats->rs_moreaggr)
rx_status->flag |= RX_FLAG_NO_SIGNAL_VAL;
- sc->rx.discard_next = false;
-
#ifdef CONFIG_ATH9K_BTCOEX_SUPPORT
if (ieee80211_is_data_present(hdr->frame_control) &&
!ieee80211_is_qos_nullfunc(hdr->frame_control))
sc->rx.num_pkts++;
#endif
- return 0;
+exit:
+ sc->rx.discard_next = false;
+ return ret;
}
static void ath9k_rx_skb_postprocess(struct ath_common *common,
--
1.8.3.4
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 14/14] ath9k: Remove unused function argument
2013-08-14 3:41 [PATCH 01/14] ath9k: Use a subroutine to check for "mybeacon" Sujith Manoharan
` (11 preceding siblings ...)
2013-08-14 3:41 ` [PATCH 13/14] ath9k: Fix error condition for corrupt descriptors Sujith Manoharan
@ 2013-08-14 3:41 ` Sujith Manoharan
12 siblings, 0 replies; 14+ messages in thread
From: Sujith Manoharan @ 2013-08-14 3:41 UTC (permalink / raw)
To: John Linville; +Cc: linux-wireless
From: Sujith Manoharan <c_manoha@qca.qualcomm.com>
Signed-off-by: Sujith Manoharan <c_manoha@qca.qualcomm.com>
---
drivers/net/wireless/ath/ath9k/recv.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c
index ec89280..3b47198 100644
--- a/drivers/net/wireless/ath/ath9k/recv.c
+++ b/drivers/net/wireless/ath/ath9k/recv.c
@@ -885,7 +885,6 @@ static int ath9k_process_rate(struct ath_common *common,
static void ath9k_process_rssi(struct ath_common *common,
struct ieee80211_hw *hw,
- struct ieee80211_hdr *hdr,
struct ath_rx_status *rx_stats)
{
struct ath_softc *sc = hw->priv;
@@ -1150,7 +1149,7 @@ static int ath9k_rx_skb_preprocess(struct ath_softc *sc,
goto exit;
}
- ath9k_process_rssi(common, hw, hdr, rx_stats);
+ ath9k_process_rssi(common, hw, rx_stats);
rx_status->band = hw->conf.chandef.chan->band;
rx_status->freq = hw->conf.chandef.chan->center_freq;
--
1.8.3.4
^ permalink raw reply related [flat|nested] 14+ messages in thread
end of thread, other threads:[~2013-08-14 3:45 UTC | newest]
Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-08-14 3:41 [PATCH 01/14] ath9k: Use a subroutine to check for "mybeacon" Sujith Manoharan
2013-08-14 3:41 ` [PATCH 02/14] ath9k: Fix phy error handling for DFS Sujith Manoharan
2013-08-14 3:41 ` [PATCH 03/14] ath9k: Discard invalid frames early Sujith Manoharan
2013-08-14 3:41 ` [PATCH 04/14] ath9k: Fix RX crypto processing Sujith Manoharan
2013-08-14 3:41 ` [PATCH 05/14] ath9k: Fix TSF processing Sujith Manoharan
2013-08-14 3:41 ` [PATCH 06/14] ath9k: Reorder some functions Sujith Manoharan
2013-08-14 3:41 ` [PATCH 07/14] ath9k: Fix PHY error processing Sujith Manoharan
2013-08-14 3:41 ` [PATCH 08/14] ath9k: Fix RX debug statistics Sujith Manoharan
2013-08-14 3:41 ` [PATCH 09/14] ath9k: Fix RX packet counter Sujith Manoharan
2013-08-14 3:41 ` [PATCH 10/14] ath9k: Fix RX beacon processing Sujith Manoharan
2013-08-14 3:41 ` [PATCH 11/14] ath9k: Move the RX poll check to preprocess() Sujith Manoharan
2013-08-14 3:41 ` [PATCH 12/14] ath9k: Handle corrupt descriptors properly Sujith Manoharan
2013-08-14 3:41 ` [PATCH 13/14] ath9k: Fix error condition for corrupt descriptors Sujith Manoharan
2013-08-14 3:41 ` [PATCH 14/14] ath9k: Remove unused function argument Sujith Manoharan
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).