aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath/ath9k/recv.c
diff options
context:
space:
mode:
authorSujith Manoharan <c_manoha@qca.qualcomm.com>2013-08-13 23:41:21 -0400
committerJohn W. Linville <linville@tuxdriver.com>2013-08-15 16:08:05 -0400
commit7c5c73cde03c876b23d840e82f4df687bce83b44 (patch)
tree4b6119e6ce1610344dee0b39a4d522a49dcddf62 /drivers/net/wireless/ath/ath9k/recv.c
parentb09255957b69d7b5ea1ad9d2b455a4f8769e06e7 (diff)
ath9k: Fix error condition for corrupt descriptors
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> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/ath/ath9k/recv.c')
-rw-r--r--drivers/net/wireless/ath/ath9k/recv.c28
1 files changed, 18 insertions, 10 deletions
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c
index 30cb7267c12b..ec8928041da0 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,
1068 struct ath_common *common = ath9k_hw_common(ah); 1068 struct ath_common *common = ath9k_hw_common(ah);
1069 struct ieee80211_hdr *hdr; 1069 struct ieee80211_hdr *hdr;
1070 bool discard_current = sc->rx.discard_next; 1070 bool discard_current = sc->rx.discard_next;
1071 int ret = 0;
1071 1072
1072 /* 1073 /*
1073 * Discard corrupt descriptors which are marked in 1074 * Discard corrupt descriptors which are marked in
@@ -1106,8 +1107,10 @@ static int ath9k_rx_skb_preprocess(struct ath_softc *sc,
1106 * This is different from the other corrupt descriptor 1107 * This is different from the other corrupt descriptor
1107 * condition handled above. 1108 * condition handled above.
1108 */ 1109 */
1109 if (rx_stats->rs_status & ATH9K_RXERR_CORRUPT_DESC) 1110 if (rx_stats->rs_status & ATH9K_RXERR_CORRUPT_DESC) {
1110 return -EINVAL; 1111 ret = -EINVAL;
1112 goto exit;
1113 }
1111 1114
1112 hdr = (struct ieee80211_hdr *) (skb->data + ah->caps.rx_status_len); 1115 hdr = (struct ieee80211_hdr *) (skb->data + ah->caps.rx_status_len);
1113 1116
@@ -1123,15 +1126,18 @@ static int ath9k_rx_skb_preprocess(struct ath_softc *sc,
1123 if (ath_process_fft(sc, hdr, rx_stats, rx_status->mactime)) 1126 if (ath_process_fft(sc, hdr, rx_stats, rx_status->mactime))
1124 RX_STAT_INC(rx_spectral); 1127 RX_STAT_INC(rx_spectral);
1125 1128
1126 return -EINVAL; 1129 ret = -EINVAL;
1130 goto exit;
1127 } 1131 }
1128 1132
1129 /* 1133 /*
1130 * everything but the rate is checked here, the rate check is done 1134 * everything but the rate is checked here, the rate check is done
1131 * separately to avoid doing two lookups for a rate for each frame. 1135 * separately to avoid doing two lookups for a rate for each frame.
1132 */ 1136 */
1133 if (!ath9k_rx_accept(common, hdr, rx_status, rx_stats, decrypt_error)) 1137 if (!ath9k_rx_accept(common, hdr, rx_status, rx_stats, decrypt_error)) {
1134 return -EINVAL; 1138 ret = -EINVAL;
1139 goto exit;
1140 }
1135 1141
1136 rx_stats->is_mybeacon = ath9k_is_mybeacon(sc, hdr); 1142 rx_stats->is_mybeacon = ath9k_is_mybeacon(sc, hdr);
1137 if (rx_stats->is_mybeacon) { 1143 if (rx_stats->is_mybeacon) {
@@ -1139,8 +1145,10 @@ static int ath9k_rx_skb_preprocess(struct ath_softc *sc,
1139 ath_start_rx_poll(sc, 3); 1145 ath_start_rx_poll(sc, 3);
1140 } 1146 }
1141 1147
1142 if (ath9k_process_rate(common, hw, rx_stats, rx_status)) 1148 if (ath9k_process_rate(common, hw, rx_stats, rx_status)) {
1143 return -EINVAL; 1149 ret =-EINVAL;
1150 goto exit;
1151 }
1144 1152
1145 ath9k_process_rssi(common, hw, hdr, rx_stats); 1153 ath9k_process_rssi(common, hw, hdr, rx_stats);
1146 1154
@@ -1152,15 +1160,15 @@ static int ath9k_rx_skb_preprocess(struct ath_softc *sc,
1152 if (rx_stats->rs_moreaggr) 1160 if (rx_stats->rs_moreaggr)
1153 rx_status->flag |= RX_FLAG_NO_SIGNAL_VAL; 1161 rx_status->flag |= RX_FLAG_NO_SIGNAL_VAL;
1154 1162
1155 sc->rx.discard_next = false;
1156
1157#ifdef CONFIG_ATH9K_BTCOEX_SUPPORT 1163#ifdef CONFIG_ATH9K_BTCOEX_SUPPORT
1158 if (ieee80211_is_data_present(hdr->frame_control) && 1164 if (ieee80211_is_data_present(hdr->frame_control) &&
1159 !ieee80211_is_qos_nullfunc(hdr->frame_control)) 1165 !ieee80211_is_qos_nullfunc(hdr->frame_control))
1160 sc->rx.num_pkts++; 1166 sc->rx.num_pkts++;
1161#endif 1167#endif
1162 1168
1163 return 0; 1169exit:
1170 sc->rx.discard_next = false;
1171 return ret;
1164} 1172}
1165 1173
1166static void ath9k_rx_skb_postprocess(struct ath_common *common, 1174static void ath9k_rx_skb_postprocess(struct ath_common *common,