Branch data Line data Source code
1 : : /*
2 : : * Copyright (c) 2009-2011 Atheros Communications Inc.
3 : : *
4 : : * Permission to use, copy, modify, and/or distribute this software for any
5 : : * purpose with or without fee is hereby granted, provided that the above
6 : : * copyright notice and this permission notice appear in all copies.
7 : : *
8 : : * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 : : * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 : : * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 : : * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 : : * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 : : * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 : : * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 : : */
16 : :
17 : : /*
18 : : * Module for common driver code between ath9k and ath9k_htc
19 : : */
20 : :
21 : : #include <linux/kernel.h>
22 : : #include <linux/module.h>
23 : :
24 : : #include "common.h"
25 : :
26 : : MODULE_AUTHOR("Atheros Communications");
27 : : MODULE_DESCRIPTION("Shared library for Atheros wireless 802.11n LAN cards.");
28 : : MODULE_LICENSE("Dual BSD/GPL");
29 : :
30 : : /* Assumes you've already done the endian to CPU conversion */
31 : 30 : bool ath9k_cmn_rx_accept(struct ath_common *common,
32 : : struct ieee80211_hdr *hdr,
33 : : struct ieee80211_rx_status *rxs,
34 : : struct ath_rx_status *rx_stats,
35 : : bool *decrypt_error,
36 : : unsigned int rxfilter)
37 : : {
38 : 30 : struct ath_hw *ah = common->ah;
39 : 30 : bool is_mc, is_valid_tkip, strip_mic, mic_error;
40 : 30 : __le16 fc;
41 : :
42 : 30 : fc = hdr->frame_control;
43 : :
44 [ + + ]: 30 : is_mc = !!is_multicast_ether_addr(hdr->addr1);
45 [ + + + - ]: 32 : is_valid_tkip = rx_stats->rs_keyix != ATH9K_RXKEYIX_INVALID &&
46 : 2 : test_bit(rx_stats->rs_keyix, common->tkip_keymap);
47 [ # # # # ]: 0 : strip_mic = is_valid_tkip && ieee80211_is_data(fc) &&
48 [ - + ]: 30 : ieee80211_has_protected(fc) &&
49 [ # # ]: 0 : !(rx_stats->rs_status &
50 : : (ATH9K_RXERR_DECRYPT | ATH9K_RXERR_CRC | ATH9K_RXERR_MIC |
51 : : ATH9K_RXERR_KEYMISS));
52 : :
53 : : /*
54 : : * Key miss events are only relevant for pairwise keys where the
55 : : * descriptor does contain a valid key index. This has been observed
56 : : * mostly with CCMP encryption.
57 : : */
58 [ + + + - ]: 32 : if (rx_stats->rs_keyix == ATH9K_RXKEYIX_INVALID ||
59 : 2 : !test_bit(rx_stats->rs_keyix, common->ccmp_keymap))
60 : 30 : rx_stats->rs_status &= ~ATH9K_RXERR_KEYMISS;
61 : :
62 [ # # # # ]: 0 : mic_error = is_valid_tkip && !ieee80211_is_ctl(fc) &&
63 : 0 : !ieee80211_has_morefrags(fc) &&
64 [ - + - - ]: 30 : !(le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG) &&
65 [ # # ]: 0 : (rx_stats->rs_status & ATH9K_RXERR_MIC);
66 : :
67 : : /*
68 : : * The rx_stats->rs_status will not be set until the end of the
69 : : * chained descriptors so it can be ignored if rs_more is set. The
70 : : * rs_more will be false at the last element of the chained
71 : : * descriptors.
72 : : */
73 [ + + ]: 30 : if (rx_stats->rs_status != 0) {
74 : 20 : u8 status_mask;
75 : :
76 [ + + ]: 20 : if (rx_stats->rs_status & ATH9K_RXERR_CRC) {
77 : 12 : rxs->flag |= RX_FLAG_FAILED_FCS_CRC;
78 : 12 : mic_error = false;
79 : : }
80 : :
81 [ + + + + ]: 20 : if ((rx_stats->rs_status & ATH9K_RXERR_DECRYPT) ||
82 [ - + ]: 9 : (!is_mc && (rx_stats->rs_status & ATH9K_RXERR_KEYMISS))) {
83 : 6 : *decrypt_error = true;
84 : 6 : mic_error = false;
85 : : }
86 : :
87 : :
88 : : /*
89 : : * Reject error frames with the exception of
90 : : * decryption and MIC failures. For monitor mode,
91 : : * we also ignore the CRC error.
92 : : */
93 : 20 : status_mask = ATH9K_RXERR_DECRYPT | ATH9K_RXERR_MIC |
94 : : ATH9K_RXERR_KEYMISS;
95 : :
96 [ - + - - ]: 20 : if (ah->is_monitoring && (rxfilter & FIF_FCSFAIL))
97 : 0 : status_mask |= ATH9K_RXERR_CRC;
98 : :
99 [ + + ]: 20 : if (rx_stats->rs_status & ~status_mask)
100 : : return false;
101 : : }
102 : :
103 : : /*
104 : : * For unicast frames the MIC error bit can have false positives,
105 : : * so all MIC error reports need to be validated in software.
106 : : * False negatives are not common, so skip software verification
107 : : * if the hardware considers the MIC valid.
108 : : */
109 [ - + ]: 18 : if (strip_mic)
110 : 0 : rxs->flag |= RX_FLAG_MMIC_STRIPPED;
111 [ + + - + ]: 18 : else if (is_mc && mic_error)
112 : 0 : rxs->flag |= RX_FLAG_MMIC_ERROR;
113 : :
114 : : return true;
115 : : }
116 : : EXPORT_SYMBOL(ath9k_cmn_rx_accept);
117 : :
118 : 18 : void ath9k_cmn_rx_skb_postprocess(struct ath_common *common,
119 : : struct sk_buff *skb,
120 : : struct ath_rx_status *rx_stats,
121 : : struct ieee80211_rx_status *rxs,
122 : : bool decrypt_error)
123 : : {
124 : 18 : struct ath_hw *ah = common->ah;
125 : 18 : struct ieee80211_hdr *hdr;
126 : 18 : int hdrlen, padpos, padsize;
127 : 18 : u8 keyix;
128 : 18 : __le16 fc;
129 : :
130 : : /* see if any padding is done by the hw and remove it */
131 : 18 : hdr = (struct ieee80211_hdr *) skb->data;
132 : 18 : hdrlen = ieee80211_get_hdrlen_from_skb(skb);
133 : 18 : fc = hdr->frame_control;
134 : 18 : padpos = ieee80211_hdrlen(fc);
135 : :
136 : : /* The MAC header is padded to have 32-bit boundary if the
137 : : * packet payload is non-zero. The general calculation for
138 : : * padsize would take into account odd header lengths:
139 : : * padsize = (4 - padpos % 4) % 4; However, since only
140 : : * even-length headers are used, padding can only be 0 or 2
141 : : * bytes and we can optimize this a bit. In addition, we must
142 : : * not try to remove padding from short control frames that do
143 : : * not have payload. */
144 : 18 : padsize = padpos & 3;
145 [ - + - - ]: 18 : if (padsize && skb->len>=padpos+padsize+FCS_LEN) {
146 : 0 : memmove(skb->data + padsize, skb->data, padpos);
147 : 0 : skb_pull(skb, padsize);
148 : : }
149 : :
150 : 18 : keyix = rx_stats->rs_keyix;
151 : :
152 [ - + - - : 18 : if (!(keyix == ATH9K_RXKEYIX_INVALID) && !decrypt_error &&
- - ]
153 : : ieee80211_has_protected(fc)) {
154 : 0 : rxs->flag |= RX_FLAG_DECRYPTED;
155 [ + - ]: 18 : } else if (ieee80211_has_protected(fc)
156 [ + + + - ]: 18 : && !decrypt_error && skb->len >= hdrlen + 4) {
157 : 12 : keyix = skb->data[hdrlen + 3] >> 6;
158 : :
159 [ - + ]: 12 : if (test_bit(keyix, common->keymap))
160 : 0 : rxs->flag |= RX_FLAG_DECRYPTED;
161 : : }
162 [ + - ]: 18 : if (ah->sw_mgmt_crypto_rx &&
163 [ - + - - ]: 18 : (rxs->flag & RX_FLAG_DECRYPTED) &&
164 : : ieee80211_is_mgmt(fc))
165 : : /* Use software decrypt for management frames. */
166 : 0 : rxs->flag &= ~RX_FLAG_DECRYPTED;
167 : 18 : }
168 : : EXPORT_SYMBOL(ath9k_cmn_rx_skb_postprocess);
169 : :
170 : 18 : int ath9k_cmn_process_rate(struct ath_common *common,
171 : : struct ieee80211_hw *hw,
172 : : struct ath_rx_status *rx_stats,
173 : : struct ieee80211_rx_status *rxs)
174 : : {
175 : 18 : struct ieee80211_supported_band *sband;
176 : 18 : enum nl80211_band band;
177 : 18 : unsigned int i = 0;
178 : 18 : struct ath_hw *ah = common->ah;
179 : :
180 : 18 : band = ah->curchan->chan->band;
181 : 18 : sband = hw->wiphy->bands[band];
182 : :
183 [ - + ]: 18 : if (IS_CHAN_QUARTER_RATE(ah->curchan))
184 : 0 : rxs->bw = RATE_INFO_BW_5;
185 [ - + ]: 18 : else if (IS_CHAN_HALF_RATE(ah->curchan))
186 : 0 : rxs->bw = RATE_INFO_BW_10;
187 : :
188 [ - + ]: 18 : if (rx_stats->rs_rate & 0x80) {
189 : : /* HT rate */
190 : 0 : rxs->encoding = RX_ENC_HT;
191 : 0 : rxs->enc_flags |= rx_stats->enc_flags;
192 : 0 : rxs->bw = rx_stats->bw;
193 : 0 : rxs->rate_idx = rx_stats->rs_rate & 0x7f;
194 : 0 : return 0;
195 : : }
196 : :
197 [ + - ]: 18 : for (i = 0; i < sband->n_bitrates; i++) {
198 [ - + ]: 18 : if (sband->bitrates[i].hw_value == rx_stats->rs_rate) {
199 : 0 : rxs->rate_idx = i;
200 : 0 : return 0;
201 : : }
202 [ + - ]: 18 : if (sband->bitrates[i].hw_value_short == rx_stats->rs_rate) {
203 : 18 : rxs->enc_flags |= RX_ENC_FLAG_SHORTPRE;
204 : 18 : rxs->rate_idx = i;
205 : 18 : return 0;
206 : : }
207 : : }
208 : :
209 : : return -EINVAL;
210 : : }
211 : : EXPORT_SYMBOL(ath9k_cmn_process_rate);
212 : :
213 : 18 : void ath9k_cmn_process_rssi(struct ath_common *common,
214 : : struct ieee80211_hw *hw,
215 : : struct ath_rx_status *rx_stats,
216 : : struct ieee80211_rx_status *rxs)
217 : : {
218 : 18 : struct ath_hw *ah = common->ah;
219 : 18 : int last_rssi;
220 : 18 : int rssi = rx_stats->rs_rssi;
221 : 18 : int i, j;
222 : :
223 : : /*
224 : : * RSSI is not available for subframes in an A-MPDU.
225 : : */
226 [ - + ]: 18 : if (rx_stats->rs_moreaggr) {
227 : 0 : rxs->flag |= RX_FLAG_NO_SIGNAL_VAL;
228 : 0 : return;
229 : : }
230 : :
231 : : /*
232 : : * Check if the RSSI for the last subframe in an A-MPDU
233 : : * or an unaggregated frame is valid.
234 : : */
235 [ + + ]: 18 : if (rx_stats->rs_rssi == ATH9K_RSSI_BAD) {
236 : 4 : rxs->flag |= RX_FLAG_NO_SIGNAL_VAL;
237 : 4 : return;
238 : : }
239 : :
240 [ + + ]: 56 : for (i = 0, j = 0; i < ARRAY_SIZE(rx_stats->rs_rssi_ctl); i++) {
241 : 42 : s8 rssi;
242 : :
243 [ - + ]: 42 : if (!(ah->rxchainmask & BIT(i)))
244 : 0 : continue;
245 : :
246 : 42 : rssi = rx_stats->rs_rssi_ctl[i];
247 [ + - ]: 42 : if (rssi != ATH9K_RSSI_BAD) {
248 : 42 : rxs->chains |= BIT(j);
249 : 42 : rxs->chain_signal[j] = ah->noise + rssi;
250 : : }
251 : 42 : j++;
252 : : }
253 : :
254 : : /*
255 : : * Update Beacon RSSI, this is used by ANI.
256 : : */
257 [ - + ]: 14 : if (rx_stats->is_mybeacon &&
258 [ # # ]: 0 : ((ah->opmode == NL80211_IFTYPE_STATION) ||
259 : : (ah->opmode == NL80211_IFTYPE_ADHOC))) {
260 [ # # # # ]: 0 : ATH_RSSI_LPF(common->last_rssi, rx_stats->rs_rssi);
261 : 0 : last_rssi = common->last_rssi;
262 : :
263 [ # # ]: 0 : if (likely(last_rssi != ATH_RSSI_DUMMY_MARKER))
264 : 0 : rssi = ATH_EP_RND(last_rssi, ATH_RSSI_EP_MULTIPLIER);
265 : 0 : if (rssi < 0)
266 : : rssi = 0;
267 : :
268 : 0 : ah->stats.avgbrssi = rssi;
269 : : }
270 : :
271 : 14 : rxs->signal = ah->noise + rx_stats->rs_rssi;
272 : : }
273 : : EXPORT_SYMBOL(ath9k_cmn_process_rssi);
274 : :
275 : 0 : int ath9k_cmn_get_hw_crypto_keytype(struct sk_buff *skb)
276 : : {
277 [ # # ]: 0 : struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
278 : :
279 [ # # ]: 0 : if (tx_info->control.hw_key) {
280 [ # # ]: 0 : switch (tx_info->control.hw_key->cipher) {
281 : : case WLAN_CIPHER_SUITE_WEP40:
282 : : case WLAN_CIPHER_SUITE_WEP104:
283 : : return ATH9K_KEY_TYPE_WEP;
284 : : case WLAN_CIPHER_SUITE_TKIP:
285 : : return ATH9K_KEY_TYPE_TKIP;
286 : : case WLAN_CIPHER_SUITE_CCMP:
287 : : return ATH9K_KEY_TYPE_AES;
288 : : default:
289 : : break;
290 : : }
291 : 0 : }
292 : :
293 : : return ATH9K_KEY_TYPE_CLEAR;
294 : : }
295 : : EXPORT_SYMBOL(ath9k_cmn_get_hw_crypto_keytype);
296 : :
297 : : /*
298 : : * Update internal channel flags.
299 : : */
300 : 192 : static void ath9k_cmn_update_ichannel(struct ath9k_channel *ichan,
301 : : struct cfg80211_chan_def *chandef)
302 : : {
303 : 192 : struct ieee80211_channel *chan = chandef->chan;
304 : 192 : u16 flags = 0;
305 : :
306 : 192 : ichan->channel = chan->center_freq;
307 : 192 : ichan->chan = chan;
308 : :
309 [ + + ]: 192 : if (chan->band == NL80211_BAND_5GHZ)
310 : 96 : flags |= CHANNEL_5GHZ;
311 : :
312 [ - - + - : 192 : switch (chandef->width) {
- + ]
313 : 0 : case NL80211_CHAN_WIDTH_5:
314 : 0 : flags |= CHANNEL_QUARTER;
315 : 0 : break;
316 : 0 : case NL80211_CHAN_WIDTH_10:
317 : 0 : flags |= CHANNEL_HALF;
318 : 0 : break;
319 : : case NL80211_CHAN_WIDTH_20_NOHT:
320 : : break;
321 : 186 : case NL80211_CHAN_WIDTH_20:
322 : 186 : flags |= CHANNEL_HT;
323 : 186 : break;
324 : 0 : case NL80211_CHAN_WIDTH_40:
325 [ # # ]: 0 : if (chandef->center_freq1 > chandef->chan->center_freq)
326 : 0 : flags |= CHANNEL_HT40PLUS | CHANNEL_HT;
327 : : else
328 : 0 : flags |= CHANNEL_HT40MINUS | CHANNEL_HT;
329 : : break;
330 : : default:
331 : 0 : WARN_ON(1);
332 : : }
333 : :
334 : 192 : ichan->channelFlags = flags;
335 : 192 : }
336 : :
337 : : /*
338 : : * Get the internal channel reference.
339 : : */
340 : 192 : struct ath9k_channel *ath9k_cmn_get_channel(struct ieee80211_hw *hw,
341 : : struct ath_hw *ah,
342 : : struct cfg80211_chan_def *chandef)
343 : : {
344 : 192 : struct ieee80211_channel *curchan = chandef->chan;
345 : 192 : struct ath9k_channel *channel;
346 : :
347 : 192 : channel = &ah->channels[curchan->hw_value];
348 : 192 : ath9k_cmn_update_ichannel(channel, chandef);
349 : :
350 : 192 : return channel;
351 : : }
352 : : EXPORT_SYMBOL(ath9k_cmn_get_channel);
353 : :
354 : 20 : int ath9k_cmn_count_streams(unsigned int chainmask, int max)
355 : : {
356 : 20 : int streams = 0;
357 : :
358 : 48 : do {
359 [ + + ]: 48 : if (++streams == max)
360 : : break;
361 [ + + ]: 32 : } while ((chainmask = chainmask & (chainmask - 1)));
362 : :
363 : 20 : return streams;
364 : : }
365 : : EXPORT_SYMBOL(ath9k_cmn_count_streams);
366 : :
367 : 59 : void ath9k_cmn_update_txpow(struct ath_hw *ah, u16 cur_txpow,
368 : : u16 new_txpow, u16 *txpower)
369 : : {
370 [ + - ]: 59 : struct ath_regulatory *reg = ath9k_hw_regulatory(ah);
371 : :
372 [ + - + + ]: 59 : if (ah->curchan && reg->power_limit != new_txpow)
373 : 6 : ath9k_hw_set_txpowerlimit(ah, new_txpow, false);
374 : :
375 : : /* read back in case value is clamped */
376 : 59 : *txpower = reg->max_power_level;
377 : 59 : }
378 : : EXPORT_SYMBOL(ath9k_cmn_update_txpow);
379 : :
380 : 12 : void ath9k_cmn_init_crypto(struct ath_hw *ah)
381 : : {
382 [ + - ]: 12 : struct ath_common *common = ath9k_hw_common(ah);
383 : 12 : int i = 0;
384 : :
385 : : /* Get the hardware key cache size. */
386 : 12 : common->keymax = AR_KEYTABLE_SIZE;
387 : :
388 : : /*
389 : : * Check whether the separate key cache entries
390 : : * are required to handle both tx+rx MIC keys.
391 : : * With split mic keys the number of stations is limited
392 : : * to 27 otherwise 59.
393 : : */
394 [ + - ]: 12 : if (ah->misc_mode & AR_PCU_MIC_NEW_LOC_ENA)
395 : 12 : common->crypt_caps |= ATH_CRYPT_CAP_MIC_COMBINED;
396 : :
397 : : /*
398 : : * Reset the key cache since some parts do not
399 : : * reset the contents on initial power up.
400 : : */
401 [ + + ]: 1548 : for (i = 0; i < common->keymax; i++)
402 : 1536 : ath_hw_keyreset(common, (u16) i);
403 : 12 : }
404 : : EXPORT_SYMBOL(ath9k_cmn_init_crypto);
405 : :
406 : 30 : static int __init ath9k_cmn_init(void)
407 : : {
408 : 30 : return 0;
409 : : }
410 : : module_init(ath9k_cmn_init);
411 : :
412 : 0 : static void __exit ath9k_cmn_exit(void)
413 : : {
414 : 0 : return;
415 : : }
416 : : module_exit(ath9k_cmn_exit);
|