diff options
-rw-r--r-- | drivers/net/wireless/ath/ath9k/common.c | 264 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/common.h | 13 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/recv.c | 267 |
3 files changed, 263 insertions, 281 deletions
diff --git a/drivers/net/wireless/ath/ath9k/common.c b/drivers/net/wireless/ath/ath9k/common.c index 7707341cd0d3..27f9ae56f96c 100644 --- a/drivers/net/wireless/ath/ath9k/common.c +++ b/drivers/net/wireless/ath/ath9k/common.c | |||
@@ -27,270 +27,6 @@ MODULE_AUTHOR("Atheros Communications"); | |||
27 | MODULE_DESCRIPTION("Shared library for Atheros wireless 802.11n LAN cards."); | 27 | MODULE_DESCRIPTION("Shared library for Atheros wireless 802.11n LAN cards."); |
28 | MODULE_LICENSE("Dual BSD/GPL"); | 28 | MODULE_LICENSE("Dual BSD/GPL"); |
29 | 29 | ||
30 | /* Common RX processing */ | ||
31 | |||
32 | /* Assumes you've already done the endian to CPU conversion */ | ||
33 | static bool ath9k_rx_accept(struct ath_common *common, | ||
34 | struct sk_buff *skb, | ||
35 | struct ieee80211_rx_status *rxs, | ||
36 | struct ath_rx_status *rx_stats, | ||
37 | bool *decrypt_error) | ||
38 | { | ||
39 | struct ath_hw *ah = common->ah; | ||
40 | struct ieee80211_hdr *hdr; | ||
41 | __le16 fc; | ||
42 | |||
43 | hdr = (struct ieee80211_hdr *) skb->data; | ||
44 | fc = hdr->frame_control; | ||
45 | |||
46 | if (!rx_stats->rs_datalen) | ||
47 | return false; | ||
48 | /* | ||
49 | * rs_status follows rs_datalen so if rs_datalen is too large | ||
50 | * we can take a hint that hardware corrupted it, so ignore | ||
51 | * those frames. | ||
52 | */ | ||
53 | if (rx_stats->rs_datalen > common->rx_bufsize) | ||
54 | return false; | ||
55 | |||
56 | /* | ||
57 | * rs_more indicates chained descriptors which can be used | ||
58 | * to link buffers together for a sort of scatter-gather | ||
59 | * operation. | ||
60 | * reject the frame, we don't support scatter-gather yet and | ||
61 | * the frame is probably corrupt anyway | ||
62 | */ | ||
63 | if (rx_stats->rs_more) | ||
64 | return false; | ||
65 | |||
66 | /* | ||
67 | * The rx_stats->rs_status will not be set until the end of the | ||
68 | * chained descriptors so it can be ignored if rs_more is set. The | ||
69 | * rs_more will be false at the last element of the chained | ||
70 | * descriptors. | ||
71 | */ | ||
72 | if (rx_stats->rs_status != 0) { | ||
73 | if (rx_stats->rs_status & ATH9K_RXERR_CRC) | ||
74 | rxs->flag |= RX_FLAG_FAILED_FCS_CRC; | ||
75 | if (rx_stats->rs_status & ATH9K_RXERR_PHY) | ||
76 | return false; | ||
77 | |||
78 | if (rx_stats->rs_status & ATH9K_RXERR_DECRYPT) { | ||
79 | *decrypt_error = true; | ||
80 | } else if (rx_stats->rs_status & ATH9K_RXERR_MIC) { | ||
81 | if (ieee80211_is_ctl(fc)) | ||
82 | /* | ||
83 | * Sometimes, we get invalid | ||
84 | * MIC failures on valid control frames. | ||
85 | * Remove these mic errors. | ||
86 | */ | ||
87 | rx_stats->rs_status &= ~ATH9K_RXERR_MIC; | ||
88 | else | ||
89 | rxs->flag |= RX_FLAG_MMIC_ERROR; | ||
90 | } | ||
91 | /* | ||
92 | * Reject error frames with the exception of | ||
93 | * decryption and MIC failures. For monitor mode, | ||
94 | * we also ignore the CRC error. | ||
95 | */ | ||
96 | if (ah->opmode == NL80211_IFTYPE_MONITOR) { | ||
97 | if (rx_stats->rs_status & | ||
98 | ~(ATH9K_RXERR_DECRYPT | ATH9K_RXERR_MIC | | ||
99 | ATH9K_RXERR_CRC)) | ||
100 | return false; | ||
101 | } else { | ||
102 | if (rx_stats->rs_status & | ||
103 | ~(ATH9K_RXERR_DECRYPT | ATH9K_RXERR_MIC)) { | ||
104 | return false; | ||
105 | } | ||
106 | } | ||
107 | } | ||
108 | return true; | ||
109 | } | ||
110 | |||
111 | static int ath9k_process_rate(struct ath_common *common, | ||
112 | struct ieee80211_hw *hw, | ||
113 | struct ath_rx_status *rx_stats, | ||
114 | struct ieee80211_rx_status *rxs, | ||
115 | struct sk_buff *skb) | ||
116 | { | ||
117 | struct ieee80211_supported_band *sband; | ||
118 | enum ieee80211_band band; | ||
119 | unsigned int i = 0; | ||
120 | |||
121 | band = hw->conf.channel->band; | ||
122 | sband = hw->wiphy->bands[band]; | ||
123 | |||
124 | if (rx_stats->rs_rate & 0x80) { | ||
125 | /* HT rate */ | ||
126 | rxs->flag |= RX_FLAG_HT; | ||
127 | if (rx_stats->rs_flags & ATH9K_RX_2040) | ||
128 | rxs->flag |= RX_FLAG_40MHZ; | ||
129 | if (rx_stats->rs_flags & ATH9K_RX_GI) | ||
130 | rxs->flag |= RX_FLAG_SHORT_GI; | ||
131 | rxs->rate_idx = rx_stats->rs_rate & 0x7f; | ||
132 | return 0; | ||
133 | } | ||
134 | |||
135 | for (i = 0; i < sband->n_bitrates; i++) { | ||
136 | if (sband->bitrates[i].hw_value == rx_stats->rs_rate) { | ||
137 | rxs->rate_idx = i; | ||
138 | return 0; | ||
139 | } | ||
140 | if (sband->bitrates[i].hw_value_short == rx_stats->rs_rate) { | ||
141 | rxs->flag |= RX_FLAG_SHORTPRE; | ||
142 | rxs->rate_idx = i; | ||
143 | return 0; | ||
144 | } | ||
145 | } | ||
146 | |||
147 | /* | ||
148 | * No valid hardware bitrate found -- we should not get here | ||
149 | * because hardware has already validated this frame as OK. | ||
150 | */ | ||
151 | ath_print(common, ATH_DBG_XMIT, "unsupported hw bitrate detected " | ||
152 | "0x%02x using 1 Mbit\n", rx_stats->rs_rate); | ||
153 | if ((common->debug_mask & ATH_DBG_XMIT)) | ||
154 | print_hex_dump_bytes("", DUMP_PREFIX_NONE, skb->data, skb->len); | ||
155 | |||
156 | return -EINVAL; | ||
157 | } | ||
158 | |||
159 | static void ath9k_process_rssi(struct ath_common *common, | ||
160 | struct ieee80211_hw *hw, | ||
161 | struct sk_buff *skb, | ||
162 | struct ath_rx_status *rx_stats) | ||
163 | { | ||
164 | struct ath_hw *ah = common->ah; | ||
165 | struct ieee80211_sta *sta; | ||
166 | struct ieee80211_hdr *hdr; | ||
167 | struct ath_node *an; | ||
168 | int last_rssi = ATH_RSSI_DUMMY_MARKER; | ||
169 | __le16 fc; | ||
170 | |||
171 | hdr = (struct ieee80211_hdr *)skb->data; | ||
172 | fc = hdr->frame_control; | ||
173 | |||
174 | rcu_read_lock(); | ||
175 | /* | ||
176 | * XXX: use ieee80211_find_sta! This requires quite a bit of work | ||
177 | * under the current ath9k virtual wiphy implementation as we have | ||
178 | * no way of tying a vif to wiphy. Typically vifs are attached to | ||
179 | * at least one sdata of a wiphy on mac80211 but with ath9k virtual | ||
180 | * wiphy you'd have to iterate over every wiphy and each sdata. | ||
181 | */ | ||
182 | sta = ieee80211_find_sta_by_hw(hw, hdr->addr2); | ||
183 | if (sta) { | ||
184 | an = (struct ath_node *) sta->drv_priv; | ||
185 | if (rx_stats->rs_rssi != ATH9K_RSSI_BAD && | ||
186 | !rx_stats->rs_moreaggr) | ||
187 | ATH_RSSI_LPF(an->last_rssi, rx_stats->rs_rssi); | ||
188 | last_rssi = an->last_rssi; | ||
189 | } | ||
190 | rcu_read_unlock(); | ||
191 | |||
192 | if (likely(last_rssi != ATH_RSSI_DUMMY_MARKER)) | ||
193 | rx_stats->rs_rssi = ATH_EP_RND(last_rssi, | ||
194 | ATH_RSSI_EP_MULTIPLIER); | ||
195 | if (rx_stats->rs_rssi < 0) | ||
196 | rx_stats->rs_rssi = 0; | ||
197 | |||
198 | /* Update Beacon RSSI, this is used by ANI. */ | ||
199 | if (ieee80211_is_beacon(fc)) | ||
200 | ah->stats.avgbrssi = rx_stats->rs_rssi; | ||
201 | } | ||
202 | |||
203 | /* | ||
204 | * For Decrypt or Demic errors, we only mark packet status here and always push | ||
205 | * up the frame up to let mac80211 handle the actual error case, be it no | ||
206 | * decryption key or real decryption error. This let us keep statistics there. | ||
207 | */ | ||
208 | int ath9k_cmn_rx_skb_preprocess(struct ath_common *common, | ||
209 | struct ieee80211_hw *hw, | ||
210 | struct sk_buff *skb, | ||
211 | struct ath_rx_status *rx_stats, | ||
212 | struct ieee80211_rx_status *rx_status, | ||
213 | bool *decrypt_error) | ||
214 | { | ||
215 | struct ath_hw *ah = common->ah; | ||
216 | |||
217 | memset(rx_status, 0, sizeof(struct ieee80211_rx_status)); | ||
218 | |||
219 | /* | ||
220 | * everything but the rate is checked here, the rate check is done | ||
221 | * separately to avoid doing two lookups for a rate for each frame. | ||
222 | */ | ||
223 | if (!ath9k_rx_accept(common, skb, rx_status, rx_stats, decrypt_error)) | ||
224 | return -EINVAL; | ||
225 | |||
226 | ath9k_process_rssi(common, hw, skb, rx_stats); | ||
227 | |||
228 | if (ath9k_process_rate(common, hw, rx_stats, rx_status, skb)) | ||
229 | return -EINVAL; | ||
230 | |||
231 | rx_status->mactime = ath9k_hw_extend_tsf(ah, rx_stats->rs_tstamp); | ||
232 | rx_status->band = hw->conf.channel->band; | ||
233 | rx_status->freq = hw->conf.channel->center_freq; | ||
234 | rx_status->signal = ATH_DEFAULT_NOISE_FLOOR + rx_stats->rs_rssi; | ||
235 | rx_status->antenna = rx_stats->rs_antenna; | ||
236 | rx_status->flag |= RX_FLAG_TSFT; | ||
237 | |||
238 | return 0; | ||
239 | } | ||
240 | EXPORT_SYMBOL(ath9k_cmn_rx_skb_preprocess); | ||
241 | |||
242 | void ath9k_cmn_rx_skb_postprocess(struct ath_common *common, | ||
243 | struct sk_buff *skb, | ||
244 | struct ath_rx_status *rx_stats, | ||
245 | struct ieee80211_rx_status *rxs, | ||
246 | bool decrypt_error) | ||
247 | { | ||
248 | struct ath_hw *ah = common->ah; | ||
249 | struct ieee80211_hdr *hdr; | ||
250 | int hdrlen, padpos, padsize; | ||
251 | u8 keyix; | ||
252 | __le16 fc; | ||
253 | |||
254 | /* see if any padding is done by the hw and remove it */ | ||
255 | hdr = (struct ieee80211_hdr *) skb->data; | ||
256 | hdrlen = ieee80211_get_hdrlen_from_skb(skb); | ||
257 | fc = hdr->frame_control; | ||
258 | padpos = ath9k_cmn_padpos(hdr->frame_control); | ||
259 | |||
260 | /* The MAC header is padded to have 32-bit boundary if the | ||
261 | * packet payload is non-zero. The general calculation for | ||
262 | * padsize would take into account odd header lengths: | ||
263 | * padsize = (4 - padpos % 4) % 4; However, since only | ||
264 | * even-length headers are used, padding can only be 0 or 2 | ||
265 | * bytes and we can optimize this a bit. In addition, we must | ||
266 | * not try to remove padding from short control frames that do | ||
267 | * not have payload. */ | ||
268 | padsize = padpos & 3; | ||
269 | if (padsize && skb->len>=padpos+padsize+FCS_LEN) { | ||
270 | memmove(skb->data + padsize, skb->data, padpos); | ||
271 | skb_pull(skb, padsize); | ||
272 | } | ||
273 | |||
274 | keyix = rx_stats->rs_keyix; | ||
275 | |||
276 | if (!(keyix == ATH9K_RXKEYIX_INVALID) && !decrypt_error && | ||
277 | ieee80211_has_protected(fc)) { | ||
278 | rxs->flag |= RX_FLAG_DECRYPTED; | ||
279 | } else if (ieee80211_has_protected(fc) | ||
280 | && !decrypt_error && skb->len >= hdrlen + 4) { | ||
281 | keyix = skb->data[hdrlen + 3] >> 6; | ||
282 | |||
283 | if (test_bit(keyix, common->keymap)) | ||
284 | rxs->flag |= RX_FLAG_DECRYPTED; | ||
285 | } | ||
286 | if (ah->sw_mgmt_crypto && | ||
287 | (rxs->flag & RX_FLAG_DECRYPTED) && | ||
288 | ieee80211_is_mgmt(fc)) | ||
289 | /* Use software decrypt for management frames. */ | ||
290 | rxs->flag &= ~RX_FLAG_DECRYPTED; | ||
291 | } | ||
292 | EXPORT_SYMBOL(ath9k_cmn_rx_skb_postprocess); | ||
293 | |||
294 | int ath9k_cmn_padpos(__le16 frame_control) | 30 | int ath9k_cmn_padpos(__le16 frame_control) |
295 | { | 31 | { |
296 | int padpos = 24; | 32 | int padpos = 24; |
diff --git a/drivers/net/wireless/ath/ath9k/common.h b/drivers/net/wireless/ath/ath9k/common.h index e08f7e5a26e0..1e6f36027ee8 100644 --- a/drivers/net/wireless/ath/ath9k/common.h +++ b/drivers/net/wireless/ath/ath9k/common.h | |||
@@ -115,19 +115,6 @@ struct ath_node { | |||
115 | int last_rssi; | 115 | int last_rssi; |
116 | }; | 116 | }; |
117 | 117 | ||
118 | int ath9k_cmn_rx_skb_preprocess(struct ath_common *common, | ||
119 | struct ieee80211_hw *hw, | ||
120 | struct sk_buff *skb, | ||
121 | struct ath_rx_status *rx_stats, | ||
122 | struct ieee80211_rx_status *rx_status, | ||
123 | bool *decrypt_error); | ||
124 | |||
125 | void ath9k_cmn_rx_skb_postprocess(struct ath_common *common, | ||
126 | struct sk_buff *skb, | ||
127 | struct ath_rx_status *rx_stats, | ||
128 | struct ieee80211_rx_status *rxs, | ||
129 | bool decrypt_error); | ||
130 | |||
131 | int ath9k_cmn_padpos(__le16 frame_control); | 118 | int ath9k_cmn_padpos(__le16 frame_control); |
132 | int ath9k_cmn_get_hw_crypto_keytype(struct sk_buff *skb); | 119 | int ath9k_cmn_get_hw_crypto_keytype(struct sk_buff *skb); |
133 | void ath9k_cmn_update_ichannel(struct ieee80211_hw *hw, | 120 | void ath9k_cmn_update_ichannel(struct ieee80211_hw *hw, |
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c index e3e52913d83a..a0f89a48509e 100644 --- a/drivers/net/wireless/ath/ath9k/recv.c +++ b/drivers/net/wireless/ath/ath9k/recv.c | |||
@@ -821,6 +821,265 @@ static struct ath_buf *ath_get_next_rx_buf(struct ath_softc *sc, | |||
821 | return bf; | 821 | return bf; |
822 | } | 822 | } |
823 | 823 | ||
824 | /* Assumes you've already done the endian to CPU conversion */ | ||
825 | static bool ath9k_rx_accept(struct ath_common *common, | ||
826 | struct sk_buff *skb, | ||
827 | struct ieee80211_rx_status *rxs, | ||
828 | struct ath_rx_status *rx_stats, | ||
829 | bool *decrypt_error) | ||
830 | { | ||
831 | struct ath_hw *ah = common->ah; | ||
832 | struct ieee80211_hdr *hdr; | ||
833 | __le16 fc; | ||
834 | |||
835 | hdr = (struct ieee80211_hdr *) skb->data; | ||
836 | fc = hdr->frame_control; | ||
837 | |||
838 | if (!rx_stats->rs_datalen) | ||
839 | return false; | ||
840 | /* | ||
841 | * rs_status follows rs_datalen so if rs_datalen is too large | ||
842 | * we can take a hint that hardware corrupted it, so ignore | ||
843 | * those frames. | ||
844 | */ | ||
845 | if (rx_stats->rs_datalen > common->rx_bufsize) | ||
846 | return false; | ||
847 | |||
848 | /* | ||
849 | * rs_more indicates chained descriptors which can be used | ||
850 | * to link buffers together for a sort of scatter-gather | ||
851 | * operation. | ||
852 | * reject the frame, we don't support scatter-gather yet and | ||
853 | * the frame is probably corrupt anyway | ||
854 | */ | ||
855 | if (rx_stats->rs_more) | ||
856 | return false; | ||
857 | |||
858 | /* | ||
859 | * The rx_stats->rs_status will not be set until the end of the | ||
860 | * chained descriptors so it can be ignored if rs_more is set. The | ||
861 | * rs_more will be false at the last element of the chained | ||
862 | * descriptors. | ||
863 | */ | ||
864 | if (rx_stats->rs_status != 0) { | ||
865 | if (rx_stats->rs_status & ATH9K_RXERR_CRC) | ||
866 | rxs->flag |= RX_FLAG_FAILED_FCS_CRC; | ||
867 | if (rx_stats->rs_status & ATH9K_RXERR_PHY) | ||
868 | return false; | ||
869 | |||
870 | if (rx_stats->rs_status & ATH9K_RXERR_DECRYPT) { | ||
871 | *decrypt_error = true; | ||
872 | } else if (rx_stats->rs_status & ATH9K_RXERR_MIC) { | ||
873 | if (ieee80211_is_ctl(fc)) | ||
874 | /* | ||
875 | * Sometimes, we get invalid | ||
876 | * MIC failures on valid control frames. | ||
877 | * Remove these mic errors. | ||
878 | */ | ||
879 | rx_stats->rs_status &= ~ATH9K_RXERR_MIC; | ||
880 | else | ||
881 | rxs->flag |= RX_FLAG_MMIC_ERROR; | ||
882 | } | ||
883 | /* | ||
884 | * Reject error frames with the exception of | ||
885 | * decryption and MIC failures. For monitor mode, | ||
886 | * we also ignore the CRC error. | ||
887 | */ | ||
888 | if (ah->opmode == NL80211_IFTYPE_MONITOR) { | ||
889 | if (rx_stats->rs_status & | ||
890 | ~(ATH9K_RXERR_DECRYPT | ATH9K_RXERR_MIC | | ||
891 | ATH9K_RXERR_CRC)) | ||
892 | return false; | ||
893 | } else { | ||
894 | if (rx_stats->rs_status & | ||
895 | ~(ATH9K_RXERR_DECRYPT | ATH9K_RXERR_MIC)) { | ||
896 | return false; | ||
897 | } | ||
898 | } | ||
899 | } | ||
900 | return true; | ||
901 | } | ||
902 | |||
903 | static int ath9k_process_rate(struct ath_common *common, | ||
904 | struct ieee80211_hw *hw, | ||
905 | struct ath_rx_status *rx_stats, | ||
906 | struct ieee80211_rx_status *rxs, | ||
907 | struct sk_buff *skb) | ||
908 | { | ||
909 | struct ieee80211_supported_band *sband; | ||
910 | enum ieee80211_band band; | ||
911 | unsigned int i = 0; | ||
912 | |||
913 | band = hw->conf.channel->band; | ||
914 | sband = hw->wiphy->bands[band]; | ||
915 | |||
916 | if (rx_stats->rs_rate & 0x80) { | ||
917 | /* HT rate */ | ||
918 | rxs->flag |= RX_FLAG_HT; | ||
919 | if (rx_stats->rs_flags & ATH9K_RX_2040) | ||
920 | rxs->flag |= RX_FLAG_40MHZ; | ||
921 | if (rx_stats->rs_flags & ATH9K_RX_GI) | ||
922 | rxs->flag |= RX_FLAG_SHORT_GI; | ||
923 | rxs->rate_idx = rx_stats->rs_rate & 0x7f; | ||
924 | return 0; | ||
925 | } | ||
926 | |||
927 | for (i = 0; i < sband->n_bitrates; i++) { | ||
928 | if (sband->bitrates[i].hw_value == rx_stats->rs_rate) { | ||
929 | rxs->rate_idx = i; | ||
930 | return 0; | ||
931 | } | ||
932 | if (sband->bitrates[i].hw_value_short == rx_stats->rs_rate) { | ||
933 | rxs->flag |= RX_FLAG_SHORTPRE; | ||
934 | rxs->rate_idx = i; | ||
935 | return 0; | ||
936 | } | ||
937 | } | ||
938 | |||
939 | /* | ||
940 | * No valid hardware bitrate found -- we should not get here | ||
941 | * because hardware has already validated this frame as OK. | ||
942 | */ | ||
943 | ath_print(common, ATH_DBG_XMIT, "unsupported hw bitrate detected " | ||
944 | "0x%02x using 1 Mbit\n", rx_stats->rs_rate); | ||
945 | if ((common->debug_mask & ATH_DBG_XMIT)) | ||
946 | print_hex_dump_bytes("", DUMP_PREFIX_NONE, skb->data, skb->len); | ||
947 | |||
948 | return -EINVAL; | ||
949 | } | ||
950 | |||
951 | static void ath9k_process_rssi(struct ath_common *common, | ||
952 | struct ieee80211_hw *hw, | ||
953 | struct sk_buff *skb, | ||
954 | struct ath_rx_status *rx_stats) | ||
955 | { | ||
956 | struct ath_hw *ah = common->ah; | ||
957 | struct ieee80211_sta *sta; | ||
958 | struct ieee80211_hdr *hdr; | ||
959 | struct ath_node *an; | ||
960 | int last_rssi = ATH_RSSI_DUMMY_MARKER; | ||
961 | __le16 fc; | ||
962 | |||
963 | hdr = (struct ieee80211_hdr *)skb->data; | ||
964 | fc = hdr->frame_control; | ||
965 | |||
966 | rcu_read_lock(); | ||
967 | /* | ||
968 | * XXX: use ieee80211_find_sta! This requires quite a bit of work | ||
969 | * under the current ath9k virtual wiphy implementation as we have | ||
970 | * no way of tying a vif to wiphy. Typically vifs are attached to | ||
971 | * at least one sdata of a wiphy on mac80211 but with ath9k virtual | ||
972 | * wiphy you'd have to iterate over every wiphy and each sdata. | ||
973 | */ | ||
974 | sta = ieee80211_find_sta_by_hw(hw, hdr->addr2); | ||
975 | if (sta) { | ||
976 | an = (struct ath_node *) sta->drv_priv; | ||
977 | if (rx_stats->rs_rssi != ATH9K_RSSI_BAD && | ||
978 | !rx_stats->rs_moreaggr) | ||
979 | ATH_RSSI_LPF(an->last_rssi, rx_stats->rs_rssi); | ||
980 | last_rssi = an->last_rssi; | ||
981 | } | ||
982 | rcu_read_unlock(); | ||
983 | |||
984 | if (likely(last_rssi != ATH_RSSI_DUMMY_MARKER)) | ||
985 | rx_stats->rs_rssi = ATH_EP_RND(last_rssi, | ||
986 | ATH_RSSI_EP_MULTIPLIER); | ||
987 | if (rx_stats->rs_rssi < 0) | ||
988 | rx_stats->rs_rssi = 0; | ||
989 | |||
990 | /* Update Beacon RSSI, this is used by ANI. */ | ||
991 | if (ieee80211_is_beacon(fc)) | ||
992 | ah->stats.avgbrssi = rx_stats->rs_rssi; | ||
993 | } | ||
994 | |||
995 | /* | ||
996 | * For Decrypt or Demic errors, we only mark packet status here and always push | ||
997 | * up the frame up to let mac80211 handle the actual error case, be it no | ||
998 | * decryption key or real decryption error. This let us keep statistics there. | ||
999 | */ | ||
1000 | static int ath9k_rx_skb_preprocess(struct ath_common *common, | ||
1001 | struct ieee80211_hw *hw, | ||
1002 | struct sk_buff *skb, | ||
1003 | struct ath_rx_status *rx_stats, | ||
1004 | struct ieee80211_rx_status *rx_status, | ||
1005 | bool *decrypt_error) | ||
1006 | { | ||
1007 | struct ath_hw *ah = common->ah; | ||
1008 | |||
1009 | memset(rx_status, 0, sizeof(struct ieee80211_rx_status)); | ||
1010 | |||
1011 | /* | ||
1012 | * everything but the rate is checked here, the rate check is done | ||
1013 | * separately to avoid doing two lookups for a rate for each frame. | ||
1014 | */ | ||
1015 | if (!ath9k_rx_accept(common, skb, rx_status, rx_stats, decrypt_error)) | ||
1016 | return -EINVAL; | ||
1017 | |||
1018 | ath9k_process_rssi(common, hw, skb, rx_stats); | ||
1019 | |||
1020 | if (ath9k_process_rate(common, hw, rx_stats, rx_status, skb)) | ||
1021 | return -EINVAL; | ||
1022 | |||
1023 | rx_status->mactime = ath9k_hw_extend_tsf(ah, rx_stats->rs_tstamp); | ||
1024 | rx_status->band = hw->conf.channel->band; | ||
1025 | rx_status->freq = hw->conf.channel->center_freq; | ||
1026 | rx_status->signal = ATH_DEFAULT_NOISE_FLOOR + rx_stats->rs_rssi; | ||
1027 | rx_status->antenna = rx_stats->rs_antenna; | ||
1028 | rx_status->flag |= RX_FLAG_TSFT; | ||
1029 | |||
1030 | return 0; | ||
1031 | } | ||
1032 | |||
1033 | static void ath9k_rx_skb_postprocess(struct ath_common *common, | ||
1034 | struct sk_buff *skb, | ||
1035 | struct ath_rx_status *rx_stats, | ||
1036 | struct ieee80211_rx_status *rxs, | ||
1037 | bool decrypt_error) | ||
1038 | { | ||
1039 | struct ath_hw *ah = common->ah; | ||
1040 | struct ieee80211_hdr *hdr; | ||
1041 | int hdrlen, padpos, padsize; | ||
1042 | u8 keyix; | ||
1043 | __le16 fc; | ||
1044 | |||
1045 | /* see if any padding is done by the hw and remove it */ | ||
1046 | hdr = (struct ieee80211_hdr *) skb->data; | ||
1047 | hdrlen = ieee80211_get_hdrlen_from_skb(skb); | ||
1048 | fc = hdr->frame_control; | ||
1049 | padpos = ath9k_cmn_padpos(hdr->frame_control); | ||
1050 | |||
1051 | /* The MAC header is padded to have 32-bit boundary if the | ||
1052 | * packet payload is non-zero. The general calculation for | ||
1053 | * padsize would take into account odd header lengths: | ||
1054 | * padsize = (4 - padpos % 4) % 4; However, since only | ||
1055 | * even-length headers are used, padding can only be 0 or 2 | ||
1056 | * bytes and we can optimize this a bit. In addition, we must | ||
1057 | * not try to remove padding from short control frames that do | ||
1058 | * not have payload. */ | ||
1059 | padsize = padpos & 3; | ||
1060 | if (padsize && skb->len>=padpos+padsize+FCS_LEN) { | ||
1061 | memmove(skb->data + padsize, skb->data, padpos); | ||
1062 | skb_pull(skb, padsize); | ||
1063 | } | ||
1064 | |||
1065 | keyix = rx_stats->rs_keyix; | ||
1066 | |||
1067 | if (!(keyix == ATH9K_RXKEYIX_INVALID) && !decrypt_error && | ||
1068 | ieee80211_has_protected(fc)) { | ||
1069 | rxs->flag |= RX_FLAG_DECRYPTED; | ||
1070 | } else if (ieee80211_has_protected(fc) | ||
1071 | && !decrypt_error && skb->len >= hdrlen + 4) { | ||
1072 | keyix = skb->data[hdrlen + 3] >> 6; | ||
1073 | |||
1074 | if (test_bit(keyix, common->keymap)) | ||
1075 | rxs->flag |= RX_FLAG_DECRYPTED; | ||
1076 | } | ||
1077 | if (ah->sw_mgmt_crypto && | ||
1078 | (rxs->flag & RX_FLAG_DECRYPTED) && | ||
1079 | ieee80211_is_mgmt(fc)) | ||
1080 | /* Use software decrypt for management frames. */ | ||
1081 | rxs->flag &= ~RX_FLAG_DECRYPTED; | ||
1082 | } | ||
824 | 1083 | ||
825 | int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp) | 1084 | int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp) |
826 | { | 1085 | { |
@@ -883,8 +1142,8 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp) | |||
883 | if (flush) | 1142 | if (flush) |
884 | goto requeue; | 1143 | goto requeue; |
885 | 1144 | ||
886 | retval = ath9k_cmn_rx_skb_preprocess(common, hw, skb, &rs, | 1145 | retval = ath9k_rx_skb_preprocess(common, hw, skb, &rs, |
887 | rxs, &decrypt_error); | 1146 | rxs, &decrypt_error); |
888 | if (retval) | 1147 | if (retval) |
889 | goto requeue; | 1148 | goto requeue; |
890 | 1149 | ||
@@ -908,8 +1167,8 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp) | |||
908 | if (ah->caps.rx_status_len) | 1167 | if (ah->caps.rx_status_len) |
909 | skb_pull(skb, ah->caps.rx_status_len); | 1168 | skb_pull(skb, ah->caps.rx_status_len); |
910 | 1169 | ||
911 | ath9k_cmn_rx_skb_postprocess(common, skb, &rs, | 1170 | ath9k_rx_skb_postprocess(common, skb, &rs, |
912 | rxs, decrypt_error); | 1171 | rxs, decrypt_error); |
913 | 1172 | ||
914 | /* We will now give hardware our shiny new allocated skb */ | 1173 | /* We will now give hardware our shiny new allocated skb */ |
915 | bf->bf_mpdu = requeue_skb; | 1174 | bf->bf_mpdu = requeue_skb; |