diff options
Diffstat (limited to 'drivers/net/wireless/ath/ath9k/common.c')
-rw-r--r-- | drivers/net/wireless/ath/ath9k/common.c | 314 |
1 files changed, 40 insertions, 274 deletions
diff --git a/drivers/net/wireless/ath/ath9k/common.c b/drivers/net/wireless/ath/ath9k/common.c index 7707341cd0d3..16e2849f644d 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; |
@@ -475,10 +211,14 @@ static int ath_reserve_key_cache_slot_tkip(struct ath_common *common) | |||
475 | return -1; | 211 | return -1; |
476 | } | 212 | } |
477 | 213 | ||
478 | static int ath_reserve_key_cache_slot(struct ath_common *common) | 214 | static int ath_reserve_key_cache_slot(struct ath_common *common, |
215 | enum ieee80211_key_alg alg) | ||
479 | { | 216 | { |
480 | int i; | 217 | int i; |
481 | 218 | ||
219 | if (alg == ALG_TKIP) | ||
220 | return ath_reserve_key_cache_slot_tkip(common); | ||
221 | |||
482 | /* First, try to find slots that would not be available for TKIP. */ | 222 | /* First, try to find slots that would not be available for TKIP. */ |
483 | if (common->splitmic) { | 223 | if (common->splitmic) { |
484 | for (i = IEEE80211_WEP_NKID; i < common->keymax / 4; i++) { | 224 | for (i = IEEE80211_WEP_NKID; i < common->keymax / 4; i++) { |
@@ -547,6 +287,7 @@ int ath9k_cmn_key_config(struct ath_common *common, | |||
547 | struct ath_hw *ah = common->ah; | 287 | struct ath_hw *ah = common->ah; |
548 | struct ath9k_keyval hk; | 288 | struct ath9k_keyval hk; |
549 | const u8 *mac = NULL; | 289 | const u8 *mac = NULL; |
290 | u8 gmac[ETH_ALEN]; | ||
550 | int ret = 0; | 291 | int ret = 0; |
551 | int idx; | 292 | int idx; |
552 | 293 | ||
@@ -570,9 +311,23 @@ int ath9k_cmn_key_config(struct ath_common *common, | |||
570 | memcpy(hk.kv_val, key->key, key->keylen); | 311 | memcpy(hk.kv_val, key->key, key->keylen); |
571 | 312 | ||
572 | if (!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) { | 313 | if (!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) { |
573 | /* For now, use the default keys for broadcast keys. This may | 314 | switch (vif->type) { |
574 | * need to change with virtual interfaces. */ | 315 | case NL80211_IFTYPE_AP: |
575 | idx = key->keyidx; | 316 | memcpy(gmac, vif->addr, ETH_ALEN); |
317 | gmac[0] |= 0x01; | ||
318 | mac = gmac; | ||
319 | idx = ath_reserve_key_cache_slot(common, key->alg); | ||
320 | break; | ||
321 | case NL80211_IFTYPE_ADHOC: | ||
322 | memcpy(gmac, sta->addr, ETH_ALEN); | ||
323 | gmac[0] |= 0x01; | ||
324 | mac = gmac; | ||
325 | idx = ath_reserve_key_cache_slot(common, key->alg); | ||
326 | break; | ||
327 | default: | ||
328 | idx = key->keyidx; | ||
329 | break; | ||
330 | } | ||
576 | } else if (key->keyidx) { | 331 | } else if (key->keyidx) { |
577 | if (WARN_ON(!sta)) | 332 | if (WARN_ON(!sta)) |
578 | return -EOPNOTSUPP; | 333 | return -EOPNOTSUPP; |
@@ -589,14 +344,12 @@ int ath9k_cmn_key_config(struct ath_common *common, | |||
589 | return -EOPNOTSUPP; | 344 | return -EOPNOTSUPP; |
590 | mac = sta->addr; | 345 | mac = sta->addr; |
591 | 346 | ||
592 | if (key->alg == ALG_TKIP) | 347 | idx = ath_reserve_key_cache_slot(common, key->alg); |
593 | idx = ath_reserve_key_cache_slot_tkip(common); | ||
594 | else | ||
595 | idx = ath_reserve_key_cache_slot(common); | ||
596 | if (idx < 0) | ||
597 | return -ENOSPC; /* no free key cache entries */ | ||
598 | } | 348 | } |
599 | 349 | ||
350 | if (idx < 0) | ||
351 | return -ENOSPC; /* no free key cache entries */ | ||
352 | |||
600 | if (key->alg == ALG_TKIP) | 353 | if (key->alg == ALG_TKIP) |
601 | ret = ath_setkey_tkip(common, idx, key->key, &hk, mac, | 354 | ret = ath_setkey_tkip(common, idx, key->key, &hk, mac, |
602 | vif->type == NL80211_IFTYPE_AP); | 355 | vif->type == NL80211_IFTYPE_AP); |
@@ -644,6 +397,19 @@ void ath9k_cmn_key_delete(struct ath_common *common, | |||
644 | } | 397 | } |
645 | EXPORT_SYMBOL(ath9k_cmn_key_delete); | 398 | EXPORT_SYMBOL(ath9k_cmn_key_delete); |
646 | 399 | ||
400 | int ath9k_cmn_count_streams(unsigned int chainmask, int max) | ||
401 | { | ||
402 | int streams = 0; | ||
403 | |||
404 | do { | ||
405 | if (++streams == max) | ||
406 | break; | ||
407 | } while ((chainmask = chainmask & (chainmask - 1))); | ||
408 | |||
409 | return streams; | ||
410 | } | ||
411 | EXPORT_SYMBOL(ath9k_cmn_count_streams); | ||
412 | |||
647 | static int __init ath9k_cmn_init(void) | 413 | static int __init ath9k_cmn_init(void) |
648 | { | 414 | { |
649 | return 0; | 415 | return 0; |