0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021 #include <linux/kernel.h>
0022 #include <linux/module.h>
0023
0024 #include "common.h"
0025
0026 MODULE_AUTHOR("Atheros Communications");
0027 MODULE_DESCRIPTION("Shared library for Atheros wireless 802.11n LAN cards.");
0028 MODULE_LICENSE("Dual BSD/GPL");
0029
0030
0031 bool ath9k_cmn_rx_accept(struct ath_common *common,
0032 struct ieee80211_hdr *hdr,
0033 struct ieee80211_rx_status *rxs,
0034 struct ath_rx_status *rx_stats,
0035 bool *decrypt_error,
0036 unsigned int rxfilter)
0037 {
0038 struct ath_hw *ah = common->ah;
0039 bool is_mc, is_valid_tkip, strip_mic, mic_error;
0040 __le16 fc;
0041
0042 fc = hdr->frame_control;
0043
0044 is_mc = !!is_multicast_ether_addr(hdr->addr1);
0045 is_valid_tkip = rx_stats->rs_keyix != ATH9K_RXKEYIX_INVALID &&
0046 test_bit(rx_stats->rs_keyix, common->tkip_keymap);
0047 strip_mic = is_valid_tkip && ieee80211_is_data(fc) &&
0048 ieee80211_has_protected(fc) &&
0049 !(rx_stats->rs_status &
0050 (ATH9K_RXERR_DECRYPT | ATH9K_RXERR_CRC | ATH9K_RXERR_MIC |
0051 ATH9K_RXERR_KEYMISS));
0052
0053
0054
0055
0056
0057
0058 if (rx_stats->rs_keyix == ATH9K_RXKEYIX_INVALID ||
0059 !test_bit(rx_stats->rs_keyix, common->ccmp_keymap))
0060 rx_stats->rs_status &= ~ATH9K_RXERR_KEYMISS;
0061
0062 mic_error = is_valid_tkip && !ieee80211_is_ctl(fc) &&
0063 !ieee80211_has_morefrags(fc) &&
0064 !(le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG) &&
0065 (rx_stats->rs_status & ATH9K_RXERR_MIC);
0066
0067
0068
0069
0070
0071
0072
0073 if (rx_stats->rs_status != 0) {
0074 u8 status_mask;
0075
0076 if (rx_stats->rs_status & ATH9K_RXERR_CRC) {
0077 rxs->flag |= RX_FLAG_FAILED_FCS_CRC;
0078 mic_error = false;
0079 }
0080
0081 if ((rx_stats->rs_status & ATH9K_RXERR_DECRYPT) ||
0082 (!is_mc && (rx_stats->rs_status & ATH9K_RXERR_KEYMISS))) {
0083 *decrypt_error = true;
0084 mic_error = false;
0085 }
0086
0087
0088
0089
0090
0091
0092
0093 status_mask = ATH9K_RXERR_DECRYPT | ATH9K_RXERR_MIC |
0094 ATH9K_RXERR_KEYMISS;
0095
0096 if (ah->is_monitoring && (rxfilter & FIF_FCSFAIL))
0097 status_mask |= ATH9K_RXERR_CRC;
0098
0099 if (rx_stats->rs_status & ~status_mask)
0100 return false;
0101 }
0102
0103
0104
0105
0106
0107
0108
0109 if (strip_mic)
0110 rxs->flag |= RX_FLAG_MMIC_STRIPPED;
0111 else if (is_mc && mic_error)
0112 rxs->flag |= RX_FLAG_MMIC_ERROR;
0113
0114 return true;
0115 }
0116 EXPORT_SYMBOL(ath9k_cmn_rx_accept);
0117
0118 void ath9k_cmn_rx_skb_postprocess(struct ath_common *common,
0119 struct sk_buff *skb,
0120 struct ath_rx_status *rx_stats,
0121 struct ieee80211_rx_status *rxs,
0122 bool decrypt_error)
0123 {
0124 struct ath_hw *ah = common->ah;
0125 struct ieee80211_hdr *hdr;
0126 int hdrlen, padpos, padsize;
0127 u8 keyix;
0128 __le16 fc;
0129
0130
0131 hdr = (struct ieee80211_hdr *) skb->data;
0132 hdrlen = ieee80211_get_hdrlen_from_skb(skb);
0133 fc = hdr->frame_control;
0134 padpos = ieee80211_hdrlen(fc);
0135
0136
0137
0138
0139
0140
0141
0142
0143
0144 padsize = padpos & 3;
0145 if (padsize && skb->len>=padpos+padsize+FCS_LEN) {
0146 memmove(skb->data + padsize, skb->data, padpos);
0147 skb_pull(skb, padsize);
0148 }
0149
0150 keyix = rx_stats->rs_keyix;
0151
0152 if (!(keyix == ATH9K_RXKEYIX_INVALID) && !decrypt_error &&
0153 ieee80211_has_protected(fc)) {
0154 rxs->flag |= RX_FLAG_DECRYPTED;
0155 } else if (ieee80211_has_protected(fc)
0156 && !decrypt_error && skb->len >= hdrlen + 4) {
0157 keyix = skb->data[hdrlen + 3] >> 6;
0158
0159 if (test_bit(keyix, common->keymap))
0160 rxs->flag |= RX_FLAG_DECRYPTED;
0161 }
0162 if (ah->sw_mgmt_crypto_rx &&
0163 (rxs->flag & RX_FLAG_DECRYPTED) &&
0164 ieee80211_is_mgmt(fc))
0165
0166 rxs->flag &= ~RX_FLAG_DECRYPTED;
0167 }
0168 EXPORT_SYMBOL(ath9k_cmn_rx_skb_postprocess);
0169
0170 int ath9k_cmn_process_rate(struct ath_common *common,
0171 struct ieee80211_hw *hw,
0172 struct ath_rx_status *rx_stats,
0173 struct ieee80211_rx_status *rxs)
0174 {
0175 struct ieee80211_supported_band *sband;
0176 enum nl80211_band band;
0177 unsigned int i = 0;
0178 struct ath_hw *ah = common->ah;
0179
0180 band = ah->curchan->chan->band;
0181 sband = hw->wiphy->bands[band];
0182
0183 if (IS_CHAN_QUARTER_RATE(ah->curchan))
0184 rxs->bw = RATE_INFO_BW_5;
0185 else if (IS_CHAN_HALF_RATE(ah->curchan))
0186 rxs->bw = RATE_INFO_BW_10;
0187
0188 if (rx_stats->rs_rate & 0x80) {
0189
0190 rxs->encoding = RX_ENC_HT;
0191 rxs->enc_flags |= rx_stats->enc_flags;
0192 rxs->bw = rx_stats->bw;
0193 rxs->rate_idx = rx_stats->rs_rate & 0x7f;
0194 return 0;
0195 }
0196
0197 for (i = 0; i < sband->n_bitrates; i++) {
0198 if (sband->bitrates[i].hw_value == rx_stats->rs_rate) {
0199 rxs->rate_idx = i;
0200 return 0;
0201 }
0202 if (sband->bitrates[i].hw_value_short == rx_stats->rs_rate) {
0203 rxs->enc_flags |= RX_ENC_FLAG_SHORTPRE;
0204 rxs->rate_idx = i;
0205 return 0;
0206 }
0207 }
0208
0209 return -EINVAL;
0210 }
0211 EXPORT_SYMBOL(ath9k_cmn_process_rate);
0212
0213 void ath9k_cmn_process_rssi(struct ath_common *common,
0214 struct ieee80211_hw *hw,
0215 struct ath_rx_status *rx_stats,
0216 struct ieee80211_rx_status *rxs)
0217 {
0218 struct ath_hw *ah = common->ah;
0219 int last_rssi;
0220 int rssi = rx_stats->rs_rssi;
0221 int i, j;
0222
0223
0224
0225
0226 if (rx_stats->rs_moreaggr) {
0227 rxs->flag |= RX_FLAG_NO_SIGNAL_VAL;
0228 return;
0229 }
0230
0231
0232
0233
0234
0235 if (rx_stats->rs_rssi == ATH9K_RSSI_BAD) {
0236 rxs->flag |= RX_FLAG_NO_SIGNAL_VAL;
0237 return;
0238 }
0239
0240 for (i = 0, j = 0; i < ARRAY_SIZE(rx_stats->rs_rssi_ctl); i++) {
0241 s8 rssi;
0242
0243 if (!(ah->rxchainmask & BIT(i)))
0244 continue;
0245
0246 rssi = rx_stats->rs_rssi_ctl[i];
0247 if (rssi != ATH9K_RSSI_BAD) {
0248 rxs->chains |= BIT(j);
0249 rxs->chain_signal[j] = ah->noise + rssi;
0250 }
0251 j++;
0252 }
0253
0254
0255
0256
0257 if (rx_stats->is_mybeacon &&
0258 ((ah->opmode == NL80211_IFTYPE_STATION) ||
0259 (ah->opmode == NL80211_IFTYPE_ADHOC))) {
0260 ATH_RSSI_LPF(common->last_rssi, rx_stats->rs_rssi);
0261 last_rssi = common->last_rssi;
0262
0263 if (likely(last_rssi != ATH_RSSI_DUMMY_MARKER))
0264 rssi = ATH_EP_RND(last_rssi, ATH_RSSI_EP_MULTIPLIER);
0265 if (rssi < 0)
0266 rssi = 0;
0267
0268 ah->stats.avgbrssi = rssi;
0269 }
0270
0271 rxs->signal = ah->noise + rx_stats->rs_rssi;
0272 }
0273 EXPORT_SYMBOL(ath9k_cmn_process_rssi);
0274
0275 int ath9k_cmn_get_hw_crypto_keytype(struct sk_buff *skb)
0276 {
0277 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
0278
0279 if (tx_info->control.hw_key) {
0280 switch (tx_info->control.hw_key->cipher) {
0281 case WLAN_CIPHER_SUITE_WEP40:
0282 case WLAN_CIPHER_SUITE_WEP104:
0283 return ATH9K_KEY_TYPE_WEP;
0284 case WLAN_CIPHER_SUITE_TKIP:
0285 return ATH9K_KEY_TYPE_TKIP;
0286 case WLAN_CIPHER_SUITE_CCMP:
0287 return ATH9K_KEY_TYPE_AES;
0288 default:
0289 break;
0290 }
0291 }
0292
0293 return ATH9K_KEY_TYPE_CLEAR;
0294 }
0295 EXPORT_SYMBOL(ath9k_cmn_get_hw_crypto_keytype);
0296
0297
0298
0299
0300 static void ath9k_cmn_update_ichannel(struct ath9k_channel *ichan,
0301 struct cfg80211_chan_def *chandef)
0302 {
0303 struct ieee80211_channel *chan = chandef->chan;
0304 u16 flags = 0;
0305
0306 ichan->channel = chan->center_freq;
0307 ichan->chan = chan;
0308
0309 if (chan->band == NL80211_BAND_5GHZ)
0310 flags |= CHANNEL_5GHZ;
0311
0312 switch (chandef->width) {
0313 case NL80211_CHAN_WIDTH_5:
0314 flags |= CHANNEL_QUARTER;
0315 break;
0316 case NL80211_CHAN_WIDTH_10:
0317 flags |= CHANNEL_HALF;
0318 break;
0319 case NL80211_CHAN_WIDTH_20_NOHT:
0320 break;
0321 case NL80211_CHAN_WIDTH_20:
0322 flags |= CHANNEL_HT;
0323 break;
0324 case NL80211_CHAN_WIDTH_40:
0325 if (chandef->center_freq1 > chandef->chan->center_freq)
0326 flags |= CHANNEL_HT40PLUS | CHANNEL_HT;
0327 else
0328 flags |= CHANNEL_HT40MINUS | CHANNEL_HT;
0329 break;
0330 default:
0331 WARN_ON(1);
0332 }
0333
0334 ichan->channelFlags = flags;
0335 }
0336
0337
0338
0339
0340 struct ath9k_channel *ath9k_cmn_get_channel(struct ieee80211_hw *hw,
0341 struct ath_hw *ah,
0342 struct cfg80211_chan_def *chandef)
0343 {
0344 struct ieee80211_channel *curchan = chandef->chan;
0345 struct ath9k_channel *channel;
0346
0347 channel = &ah->channels[curchan->hw_value];
0348 ath9k_cmn_update_ichannel(channel, chandef);
0349
0350 return channel;
0351 }
0352 EXPORT_SYMBOL(ath9k_cmn_get_channel);
0353
0354 int ath9k_cmn_count_streams(unsigned int chainmask, int max)
0355 {
0356 int streams = 0;
0357
0358 do {
0359 if (++streams == max)
0360 break;
0361 } while ((chainmask = chainmask & (chainmask - 1)));
0362
0363 return streams;
0364 }
0365 EXPORT_SYMBOL(ath9k_cmn_count_streams);
0366
0367 void ath9k_cmn_update_txpow(struct ath_hw *ah, u16 cur_txpow,
0368 u16 new_txpow, u16 *txpower)
0369 {
0370 struct ath_regulatory *reg = ath9k_hw_regulatory(ah);
0371
0372 if (ah->curchan && reg->power_limit != new_txpow)
0373 ath9k_hw_set_txpowerlimit(ah, new_txpow, false);
0374
0375
0376 *txpower = reg->max_power_level;
0377 }
0378 EXPORT_SYMBOL(ath9k_cmn_update_txpow);
0379
0380 void ath9k_cmn_init_crypto(struct ath_hw *ah)
0381 {
0382 struct ath_common *common = ath9k_hw_common(ah);
0383 int i = 0;
0384
0385
0386 common->keymax = AR_KEYTABLE_SIZE;
0387
0388
0389
0390
0391
0392
0393
0394 if (ah->misc_mode & AR_PCU_MIC_NEW_LOC_ENA)
0395 common->crypt_caps |= ATH_CRYPT_CAP_MIC_COMBINED;
0396
0397
0398
0399
0400
0401 for (i = 0; i < common->keymax; i++)
0402 ath_hw_keyreset(common, (u16) i);
0403 }
0404 EXPORT_SYMBOL(ath9k_cmn_init_crypto);
0405
0406 static int __init ath9k_cmn_init(void)
0407 {
0408 return 0;
0409 }
0410 module_init(ath9k_cmn_init);
0411
0412 static void __exit ath9k_cmn_exit(void)
0413 {
0414 return;
0415 }
0416 module_exit(ath9k_cmn_exit);