aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath
diff options
context:
space:
mode:
authorSujith Manoharan <c_manoha@qca.qualcomm.com>2013-08-13 23:41:18 -0400
committerJohn W. Linville <linville@tuxdriver.com>2013-08-15 16:08:04 -0400
commit6f38482eb0630e0be304d5c4fa0e2e5c0a701e91 (patch)
tree6dbbcc9ef6347ac4e9d9b5d94b12abe4bcf86e78 /drivers/net/wireless/ath
parenta5525d9c8246cad653858044ccfd8a16143e84f6 (diff)
ath9k: Fix RX beacon processing
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> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/ath')
-rw-r--r--drivers/net/wireless/ath/ath9k/recv.c48
1 files changed, 22 insertions, 26 deletions
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c
index 823b4111e282..090c27e756b8 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,
1037#endif 1037#endif
1038} 1038}
1039 1039
1040static bool ath9k_is_mybeacon(struct ath_softc *sc, struct ieee80211_hdr *hdr)
1041{
1042 struct ath_hw *ah = sc->sc_ah;
1043 struct ath_common *common = ath9k_hw_common(ah);
1044
1045 if (ieee80211_is_beacon(hdr->frame_control)) {
1046 RX_STAT_INC(rx_beacons);
1047 if (!is_zero_ether_addr(common->curbssid) &&
1048 ether_addr_equal(hdr->addr3, common->curbssid))
1049 return true;
1050 }
1051
1052 return false;
1053}
1054
1040/* 1055/*
1041 * For Decrypt or Demic errors, we only mark packet status here and always push 1056 * For Decrypt or Demic errors, we only mark packet status here and always push
1042 * up the frame up to let mac80211 handle the actual error case, be it no 1057 * up the frame up to let mac80211 handle the actual error case, be it no
1043 * decryption key or real decryption error. This let us keep statistics there. 1058 * decryption key or real decryption error. This let us keep statistics there.
1044 */ 1059 */
1045static int ath9k_rx_skb_preprocess(struct ath_softc *sc, 1060static int ath9k_rx_skb_preprocess(struct ath_softc *sc,
1046 struct ieee80211_hdr *hdr, 1061 struct sk_buff *skb,
1047 struct ath_rx_status *rx_stats, 1062 struct ath_rx_status *rx_stats,
1048 struct ieee80211_rx_status *rx_status, 1063 struct ieee80211_rx_status *rx_status,
1049 bool *decrypt_error, u64 tsf) 1064 bool *decrypt_error, u64 tsf)
@@ -1051,6 +1066,7 @@ static int ath9k_rx_skb_preprocess(struct ath_softc *sc,
1051 struct ieee80211_hw *hw = sc->hw; 1066 struct ieee80211_hw *hw = sc->hw;
1052 struct ath_hw *ah = sc->sc_ah; 1067 struct ath_hw *ah = sc->sc_ah;
1053 struct ath_common *common = ath9k_hw_common(ah); 1068 struct ath_common *common = ath9k_hw_common(ah);
1069 struct ieee80211_hdr *hdr;
1054 bool discard_current = sc->rx.discard_next; 1070 bool discard_current = sc->rx.discard_next;
1055 1071
1056 /* 1072 /*
@@ -1083,6 +1099,8 @@ static int ath9k_rx_skb_preprocess(struct ath_softc *sc,
1083 if (rx_stats->rs_more) 1099 if (rx_stats->rs_more)
1084 return 0; 1100 return 0;
1085 1101
1102 hdr = (struct ieee80211_hdr *) (skb->data + ah->caps.rx_status_len);
1103
1086 ath9k_process_tsf(rx_stats, rx_status, tsf); 1104 ath9k_process_tsf(rx_stats, rx_status, tsf);
1087 ath_debug_stat_rx(sc, rx_stats); 1105 ath_debug_stat_rx(sc, rx_stats);
1088 1106
@@ -1105,6 +1123,8 @@ static int ath9k_rx_skb_preprocess(struct ath_softc *sc,
1105 if (!ath9k_rx_accept(common, hdr, rx_status, rx_stats, decrypt_error)) 1123 if (!ath9k_rx_accept(common, hdr, rx_status, rx_stats, decrypt_error))
1106 return -EINVAL; 1124 return -EINVAL;
1107 1125
1126 rx_stats->is_mybeacon = ath9k_is_mybeacon(sc, hdr);
1127
1108 if (ath9k_process_rate(common, hw, rx_stats, rx_status)) 1128 if (ath9k_process_rate(common, hw, rx_stats, rx_status))
1109 return -EINVAL; 1129 return -EINVAL;
1110 1130
@@ -1198,24 +1218,6 @@ static void ath9k_apply_ampdu_details(struct ath_softc *sc,
1198 } 1218 }
1199} 1219}
1200 1220
1201static bool ath9k_is_mybeacon(struct ath_softc *sc, struct sk_buff *skb)
1202{
1203 struct ath_hw *ah = sc->sc_ah;
1204 struct ath_common *common = ath9k_hw_common(ah);
1205 struct ieee80211_hdr *hdr;
1206
1207 hdr = (struct ieee80211_hdr *) (skb->data + ah->caps.rx_status_len);
1208
1209 if (ieee80211_is_beacon(hdr->frame_control)) {
1210 RX_STAT_INC(rx_beacons);
1211 if (!is_zero_ether_addr(common->curbssid) &&
1212 ether_addr_equal(hdr->addr3, common->curbssid))
1213 return true;
1214 }
1215
1216 return false;
1217}
1218
1219int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp) 1221int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
1220{ 1222{
1221 struct ath_buf *bf; 1223 struct ath_buf *bf;
@@ -1225,7 +1227,6 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
1225 struct ath9k_hw_capabilities *pCap = &ah->caps; 1227 struct ath9k_hw_capabilities *pCap = &ah->caps;
1226 struct ath_common *common = ath9k_hw_common(ah); 1228 struct ath_common *common = ath9k_hw_common(ah);
1227 struct ieee80211_hw *hw = sc->hw; 1229 struct ieee80211_hw *hw = sc->hw;
1228 struct ieee80211_hdr *hdr;
1229 int retval; 1230 int retval;
1230 struct ath_rx_status rs; 1231 struct ath_rx_status rs;
1231 enum ath9k_rx_qtype qtype; 1232 enum ath9k_rx_qtype qtype;
@@ -1269,15 +1270,10 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
1269 else 1270 else
1270 hdr_skb = skb; 1271 hdr_skb = skb;
1271 1272
1272 rs.is_mybeacon = ath9k_is_mybeacon(sc, hdr_skb);
1273
1274 hdr = (struct ieee80211_hdr *) (hdr_skb->data +
1275 ah->caps.rx_status_len);
1276
1277 rxs = IEEE80211_SKB_RXCB(hdr_skb); 1273 rxs = IEEE80211_SKB_RXCB(hdr_skb);
1278 memset(rxs, 0, sizeof(struct ieee80211_rx_status)); 1274 memset(rxs, 0, sizeof(struct ieee80211_rx_status));
1279 1275
1280 retval = ath9k_rx_skb_preprocess(sc, hdr, &rs, rxs, 1276 retval = ath9k_rx_skb_preprocess(sc, hdr_skb, &rs, rxs,
1281 &decrypt_error, tsf); 1277 &decrypt_error, tsf);
1282 if (retval) 1278 if (retval)
1283 goto requeue_drop_frag; 1279 goto requeue_drop_frag;