1db86f07eSLuis R. Rodriguez /* 25b68138eSSujith Manoharan * Copyright (c) 2009-2011 Atheros Communications Inc. 3db86f07eSLuis R. Rodriguez * 4db86f07eSLuis R. Rodriguez * Permission to use, copy, modify, and/or distribute this software for any 5db86f07eSLuis R. Rodriguez * purpose with or without fee is hereby granted, provided that the above 6db86f07eSLuis R. Rodriguez * copyright notice and this permission notice appear in all copies. 7db86f07eSLuis R. Rodriguez * 8db86f07eSLuis R. Rodriguez * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9db86f07eSLuis R. Rodriguez * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10db86f07eSLuis R. Rodriguez * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11db86f07eSLuis R. Rodriguez * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12db86f07eSLuis R. Rodriguez * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13db86f07eSLuis R. Rodriguez * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14db86f07eSLuis R. Rodriguez * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15db86f07eSLuis R. Rodriguez */ 16db86f07eSLuis R. Rodriguez 17db86f07eSLuis R. Rodriguez /* 18db86f07eSLuis R. Rodriguez * Module for common driver code between ath9k and ath9k_htc 19db86f07eSLuis R. Rodriguez */ 20db86f07eSLuis R. Rodriguez 21db86f07eSLuis R. Rodriguez #include <linux/kernel.h> 22db86f07eSLuis R. Rodriguez #include <linux/module.h> 23db86f07eSLuis R. Rodriguez 24db86f07eSLuis R. Rodriguez #include "common.h" 25db86f07eSLuis R. Rodriguez 26db86f07eSLuis R. Rodriguez MODULE_AUTHOR("Atheros Communications"); 27db86f07eSLuis R. Rodriguez MODULE_DESCRIPTION("Shared library for Atheros wireless 802.11n LAN cards."); 28db86f07eSLuis R. Rodriguez MODULE_LICENSE("Dual BSD/GPL"); 29db86f07eSLuis R. Rodriguez 30fb9987d0SSujith int ath9k_cmn_get_hw_crypto_keytype(struct sk_buff *skb) 31fb9987d0SSujith { 32fb9987d0SSujith struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); 33fb9987d0SSujith 34fb9987d0SSujith if (tx_info->control.hw_key) { 3597359d12SJohannes Berg switch (tx_info->control.hw_key->cipher) { 3697359d12SJohannes Berg case WLAN_CIPHER_SUITE_WEP40: 3797359d12SJohannes Berg case WLAN_CIPHER_SUITE_WEP104: 38fb9987d0SSujith return ATH9K_KEY_TYPE_WEP; 3997359d12SJohannes Berg case WLAN_CIPHER_SUITE_TKIP: 40fb9987d0SSujith return ATH9K_KEY_TYPE_TKIP; 4197359d12SJohannes Berg case WLAN_CIPHER_SUITE_CCMP: 42fb9987d0SSujith return ATH9K_KEY_TYPE_AES; 4397359d12SJohannes Berg default: 4497359d12SJohannes Berg break; 4597359d12SJohannes Berg } 46fb9987d0SSujith } 47fb9987d0SSujith 48fb9987d0SSujith return ATH9K_KEY_TYPE_CLEAR; 49fb9987d0SSujith } 50fb9987d0SSujith EXPORT_SYMBOL(ath9k_cmn_get_hw_crypto_keytype); 51fb9987d0SSujith 52fb9987d0SSujith /* 53fb9987d0SSujith * Update internal channel flags. 54fb9987d0SSujith */ 552297f1c7SFelix Fietkau static void ath9k_cmn_update_ichannel(struct ath9k_channel *ichan, 560671894fSSimon Wunderlich struct cfg80211_chan_def *chandef) 57fb9987d0SSujith { 586b21fd20SFelix Fietkau struct ieee80211_channel *chan = chandef->chan; 596b21fd20SFelix Fietkau u16 flags = 0; 60fb9987d0SSujith 616b21fd20SFelix Fietkau ichan->channel = chan->center_freq; 626b21fd20SFelix Fietkau ichan->chan = chan; 636b21fd20SFelix Fietkau 646b21fd20SFelix Fietkau if (chan->band == IEEE80211_BAND_5GHZ) 656b21fd20SFelix Fietkau flags |= CHANNEL_5GHZ; 66fb9987d0SSujith 670671894fSSimon Wunderlich switch (chandef->width) { 680671894fSSimon Wunderlich case NL80211_CHAN_WIDTH_5: 696b21fd20SFelix Fietkau flags |= CHANNEL_QUARTER; 700671894fSSimon Wunderlich break; 710671894fSSimon Wunderlich case NL80211_CHAN_WIDTH_10: 726b21fd20SFelix Fietkau flags |= CHANNEL_HALF; 730671894fSSimon Wunderlich break; 740671894fSSimon Wunderlich case NL80211_CHAN_WIDTH_20_NOHT: 750671894fSSimon Wunderlich break; 760671894fSSimon Wunderlich case NL80211_CHAN_WIDTH_20: 776b21fd20SFelix Fietkau flags |= CHANNEL_HT; 786b21fd20SFelix Fietkau break; 790671894fSSimon Wunderlich case NL80211_CHAN_WIDTH_40: 806b21fd20SFelix Fietkau if (chandef->center_freq1 > chandef->chan->center_freq) 816b21fd20SFelix Fietkau flags |= CHANNEL_HT40PLUS | CHANNEL_HT; 826b21fd20SFelix Fietkau else 836b21fd20SFelix Fietkau flags |= CHANNEL_HT40MINUS | CHANNEL_HT; 840671894fSSimon Wunderlich break; 850671894fSSimon Wunderlich default: 860671894fSSimon Wunderlich WARN_ON(1); 870671894fSSimon Wunderlich } 886b21fd20SFelix Fietkau 896b21fd20SFelix Fietkau ichan->channelFlags = flags; 90fb9987d0SSujith } 91fb9987d0SSujith 92fb9987d0SSujith /* 93fb9987d0SSujith * Get the internal channel reference. 94fb9987d0SSujith */ 952297f1c7SFelix Fietkau struct ath9k_channel *ath9k_cmn_get_channel(struct ieee80211_hw *hw, 962297f1c7SFelix Fietkau struct ath_hw *ah, 972297f1c7SFelix Fietkau struct cfg80211_chan_def *chandef) 98fb9987d0SSujith { 992297f1c7SFelix Fietkau struct ieee80211_channel *curchan = chandef->chan; 100fb9987d0SSujith struct ath9k_channel *channel; 101fb9987d0SSujith 102*f40c4608SFelix Fietkau channel = &ah->channels[curchan->hw_value]; 1032297f1c7SFelix Fietkau ath9k_cmn_update_ichannel(channel, chandef); 104fb9987d0SSujith 105fb9987d0SSujith return channel; 106fb9987d0SSujith } 1072297f1c7SFelix Fietkau EXPORT_SYMBOL(ath9k_cmn_get_channel); 108fb9987d0SSujith 10961389f3eSSujith int ath9k_cmn_count_streams(unsigned int chainmask, int max) 11061389f3eSSujith { 11161389f3eSSujith int streams = 0; 11261389f3eSSujith 11361389f3eSSujith do { 11461389f3eSSujith if (++streams == max) 11561389f3eSSujith break; 11661389f3eSSujith } while ((chainmask = chainmask & (chainmask - 1))); 11761389f3eSSujith 11861389f3eSSujith return streams; 11961389f3eSSujith } 12061389f3eSSujith EXPORT_SYMBOL(ath9k_cmn_count_streams); 12161389f3eSSujith 1225048e8c3SRajkumar Manoharan void ath9k_cmn_update_txpow(struct ath_hw *ah, u16 cur_txpow, 1235048e8c3SRajkumar Manoharan u16 new_txpow, u16 *txpower) 1245048e8c3SRajkumar Manoharan { 125ca2c68ccSFelix Fietkau struct ath_regulatory *reg = ath9k_hw_regulatory(ah); 126ca2c68ccSFelix Fietkau 127ca2c68ccSFelix Fietkau if (reg->power_limit != new_txpow) { 1285048e8c3SRajkumar Manoharan ath9k_hw_set_txpowerlimit(ah, new_txpow, false); 1295048e8c3SRajkumar Manoharan /* read back in case value is clamped */ 130ca2c68ccSFelix Fietkau *txpower = reg->max_power_level; 1315048e8c3SRajkumar Manoharan } 1325048e8c3SRajkumar Manoharan } 1335048e8c3SRajkumar Manoharan EXPORT_SYMBOL(ath9k_cmn_update_txpow); 1345048e8c3SRajkumar Manoharan 135f82b4bdeSRajkumar Manoharan void ath9k_cmn_init_crypto(struct ath_hw *ah) 136f82b4bdeSRajkumar Manoharan { 137f82b4bdeSRajkumar Manoharan struct ath_common *common = ath9k_hw_common(ah); 138f82b4bdeSRajkumar Manoharan int i = 0; 139f82b4bdeSRajkumar Manoharan 140f82b4bdeSRajkumar Manoharan /* Get the hardware key cache size. */ 141f82b4bdeSRajkumar Manoharan common->keymax = AR_KEYTABLE_SIZE; 142f82b4bdeSRajkumar Manoharan 143f82b4bdeSRajkumar Manoharan /* 144f82b4bdeSRajkumar Manoharan * Check whether the separate key cache entries 145f82b4bdeSRajkumar Manoharan * are required to handle both tx+rx MIC keys. 146f82b4bdeSRajkumar Manoharan * With split mic keys the number of stations is limited 147f82b4bdeSRajkumar Manoharan * to 27 otherwise 59. 148f82b4bdeSRajkumar Manoharan */ 149f82b4bdeSRajkumar Manoharan if (ah->misc_mode & AR_PCU_MIC_NEW_LOC_ENA) 150f82b4bdeSRajkumar Manoharan common->crypt_caps |= ATH_CRYPT_CAP_MIC_COMBINED; 151f82b4bdeSRajkumar Manoharan 152f82b4bdeSRajkumar Manoharan /* 153f82b4bdeSRajkumar Manoharan * Reset the key cache since some parts do not 154f82b4bdeSRajkumar Manoharan * reset the contents on initial power up. 155f82b4bdeSRajkumar Manoharan */ 156f82b4bdeSRajkumar Manoharan for (i = 0; i < common->keymax; i++) 157f82b4bdeSRajkumar Manoharan ath_hw_keyreset(common, (u16) i); 158f82b4bdeSRajkumar Manoharan } 159f82b4bdeSRajkumar Manoharan EXPORT_SYMBOL(ath9k_cmn_init_crypto); 160f82b4bdeSRajkumar Manoharan 161db86f07eSLuis R. Rodriguez static int __init ath9k_cmn_init(void) 162db86f07eSLuis R. Rodriguez { 163db86f07eSLuis R. Rodriguez return 0; 164db86f07eSLuis R. Rodriguez } 165db86f07eSLuis R. Rodriguez module_init(ath9k_cmn_init); 166db86f07eSLuis R. Rodriguez 167db86f07eSLuis R. Rodriguez static void __exit ath9k_cmn_exit(void) 168db86f07eSLuis R. Rodriguez { 169db86f07eSLuis R. Rodriguez return; 170db86f07eSLuis R. Rodriguez } 171db86f07eSLuis R. Rodriguez module_exit(ath9k_cmn_exit); 172