/* * Copyright (c) 2009-2011 Atheros Communications Inc. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/* * Module for common driver code between ath9k and ath9k_htc
*/
/* * Key miss events are only relevant for pairwise keys where the * descriptor does contain a valid key index. This has been observed * mostly with CCMP encryption.
*/ if (rx_stats->rs_keyix == ATH9K_RXKEYIX_INVALID ||
!test_bit(rx_stats->rs_keyix, common->ccmp_keymap))
rx_stats->rs_status &= ~ATH9K_RXERR_KEYMISS;
/* * The rx_stats->rs_status will not be set until the end of the * chained descriptors so it can be ignored if rs_more is set. The * rs_more will be false at the last element of the chained * descriptors.
*/ if (rx_stats->rs_status != 0) {
u8 status_mask;
/* * Reject error frames with the exception of * decryption and MIC failures. For monitor mode, * we also ignore the CRC error.
*/
status_mask = ATH9K_RXERR_DECRYPT | ATH9K_RXERR_MIC |
ATH9K_RXERR_KEYMISS;
if (ah->is_monitoring && (rxfilter & FIF_FCSFAIL))
status_mask |= ATH9K_RXERR_CRC;
if (rx_stats->rs_status & ~status_mask) returnfalse;
}
/* * For unicast frames the MIC error bit can have false positives, * so all MIC error reports need to be validated in software. * False negatives are not common, so skip software verification * if the hardware considers the MIC valid.
*/ if (strip_mic)
rxs->flag |= RX_FLAG_MMIC_STRIPPED; elseif (is_mc && mic_error)
rxs->flag |= RX_FLAG_MMIC_ERROR;
/* see if any padding is done by the hw and remove it */
hdr = (struct ieee80211_hdr *) skb->data;
hdrlen = ieee80211_get_hdrlen_from_skb(skb);
fc = hdr->frame_control;
padpos = ieee80211_hdrlen(fc);
/* The MAC header is padded to have 32-bit boundary if the * packet payload is non-zero. The general calculation for * padsize would take into account odd header lengths: * padsize = (4 - padpos % 4) % 4; However, since only * even-length headers are used, padding can only be 0 or 2 * bytes and we can optimize this a bit. In addition, we must * not try to remove padding from short control frames that do
* not have payload. */
padsize = padpos & 3; if (padsize && skb->len>=padpos+padsize+FCS_LEN) {
memmove(skb->data + padsize, skb->data, padpos);
skb_pull(skb, padsize);
}
void ath9k_cmn_process_rssi(struct ath_common *common, struct ieee80211_hw *hw, struct ath_rx_status *rx_stats, struct ieee80211_rx_status *rxs)
{ struct ath_hw *ah = common->ah; int last_rssi; int rssi = rx_stats->rs_rssi; int i, j;
/* * RSSI is not available for subframes in an A-MPDU.
*/ if (rx_stats->rs_moreaggr) {
rxs->flag |= RX_FLAG_NO_SIGNAL_VAL; return;
}
/* * Check if the RSSI for the last subframe in an A-MPDU * or an unaggregated frame is valid.
*/ if (rx_stats->rs_rssi == ATH9K_RSSI_BAD) {
rxs->flag |= RX_FLAG_NO_SIGNAL_VAL; return;
}
for (i = 0, j = 0; i < ARRAY_SIZE(rx_stats->rs_rssi_ctl); i++) {
s8 rssi;
/* * Update Beacon RSSI, this is used by ANI.
*/ if (rx_stats->is_mybeacon &&
((ah->opmode == NL80211_IFTYPE_STATION) ||
(ah->opmode == NL80211_IFTYPE_ADHOC))) {
ATH_RSSI_LPF(common->last_rssi, rx_stats->rs_rssi);
last_rssi = common->last_rssi;
if (likely(last_rssi != ATH_RSSI_DUMMY_MARKER))
rssi = ATH_EP_RND(last_rssi, ATH_RSSI_EP_MULTIPLIER); if (rssi < 0)
rssi = 0;
int ath9k_cmn_get_hw_crypto_keytype(struct sk_buff *skb)
{ struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
if (tx_info->control.hw_key) { switch (tx_info->control.hw_key->cipher) { case WLAN_CIPHER_SUITE_WEP40: case WLAN_CIPHER_SUITE_WEP104: return ATH9K_KEY_TYPE_WEP; case WLAN_CIPHER_SUITE_TKIP: return ATH9K_KEY_TYPE_TKIP; case WLAN_CIPHER_SUITE_CCMP: return ATH9K_KEY_TYPE_AES; default: break;
}
}
if (ah->curchan && reg->power_limit != new_txpow)
ath9k_hw_set_txpowerlimit(ah, new_txpow, false);
/* read back in case value is clamped */
*txpower = reg->max_power_level;
}
EXPORT_SYMBOL(ath9k_cmn_update_txpow);
void ath9k_cmn_init_crypto(struct ath_hw *ah)
{ struct ath_common *common = ath9k_hw_common(ah); int i = 0;
/* Get the hardware key cache size. */
common->keymax = AR_KEYTABLE_SIZE;
/* * Check whether the separate key cache entries * are required to handle both tx+rx MIC keys. * With split mic keys the number of stations is limited * to 27 otherwise 59.
*/ if (ah->misc_mode & AR_PCU_MIC_NEW_LOC_ENA)
common->crypt_caps |= ATH_CRYPT_CAP_MIC_COMBINED;
/* * Reset the key cache since some parts do not * reset the contents on initial power up.
*/ for (i = 0; i < common->keymax; i++)
ath_hw_keyreset(common, (u16) i);
}
EXPORT_SYMBOL(ath9k_cmn_init_crypto);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.