2009-11-05 19:44:39 +03:00
/*
2011-05-17 12:06:18 +04:00
* Copyright ( c ) 2009 - 2011 Atheros Communications Inc .
2009-11-05 19:44:39 +03:00
*
* 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
*/
# include <linux/kernel.h>
# include <linux/module.h>
# include "common.h"
MODULE_AUTHOR ( " Atheros Communications " ) ;
MODULE_DESCRIPTION ( " Shared library for Atheros wireless 802.11n LAN cards. " ) ;
MODULE_LICENSE ( " Dual BSD/GPL " ) ;
2010-03-17 11:55:25 +03:00
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 ) {
2010-08-10 11:46:38 +04:00
switch ( tx_info - > control . hw_key - > cipher ) {
case WLAN_CIPHER_SUITE_WEP40 :
case WLAN_CIPHER_SUITE_WEP104 :
2010-03-17 11:55:25 +03:00
return ATH9K_KEY_TYPE_WEP ;
2010-08-10 11:46:38 +04:00
case WLAN_CIPHER_SUITE_TKIP :
2010-03-17 11:55:25 +03:00
return ATH9K_KEY_TYPE_TKIP ;
2010-08-10 11:46:38 +04:00
case WLAN_CIPHER_SUITE_CCMP :
2010-03-17 11:55:25 +03:00
return ATH9K_KEY_TYPE_AES ;
2010-08-10 11:46:38 +04:00
default :
break ;
}
2010-03-17 11:55:25 +03:00
}
return ATH9K_KEY_TYPE_CLEAR ;
}
EXPORT_SYMBOL ( ath9k_cmn_get_hw_crypto_keytype ) ;
/*
* Update internal channel flags .
*/
2010-10-20 04:09:46 +04:00
void ath9k_cmn_update_ichannel ( struct ath9k_channel * ichan ,
2013-08-16 12:46:04 +04:00
struct cfg80211_chan_def * chandef )
2010-03-17 11:55:25 +03:00
{
2013-10-12 01:30:56 +04:00
struct ieee80211_channel * chan = chandef - > chan ;
u16 flags = 0 ;
ichan - > channel = chan - > center_freq ;
ichan - > chan = chan ;
if ( chan - > band = = IEEE80211_BAND_5GHZ )
flags | = CHANNEL_5GHZ ;
2010-03-17 11:55:25 +03:00
2013-08-16 12:46:04 +04:00
switch ( chandef - > width ) {
case NL80211_CHAN_WIDTH_5 :
2013-10-12 01:30:56 +04:00
flags | = CHANNEL_QUARTER ;
2013-08-16 12:46:04 +04:00
break ;
case NL80211_CHAN_WIDTH_10 :
2013-10-12 01:30:56 +04:00
flags | = CHANNEL_HALF ;
2013-08-16 12:46:04 +04:00
break ;
case NL80211_CHAN_WIDTH_20_NOHT :
break ;
case NL80211_CHAN_WIDTH_20 :
2013-10-12 01:30:56 +04:00
flags | = CHANNEL_HT ;
break ;
2013-08-16 12:46:04 +04:00
case NL80211_CHAN_WIDTH_40 :
2013-10-12 01:30:56 +04:00
if ( chandef - > center_freq1 > chandef - > chan - > center_freq )
flags | = CHANNEL_HT40PLUS | CHANNEL_HT ;
else
flags | = CHANNEL_HT40MINUS | CHANNEL_HT ;
2013-08-16 12:46:04 +04:00
break ;
default :
WARN_ON ( 1 ) ;
}
2013-10-12 01:30:56 +04:00
ichan - > channelFlags = flags ;
2010-03-17 11:55:25 +03:00
}
EXPORT_SYMBOL ( ath9k_cmn_update_ichannel ) ;
/*
* Get the internal channel reference .
*/
struct ath9k_channel * ath9k_cmn_get_curchannel ( struct ieee80211_hw * hw ,
struct ath_hw * ah )
{
2013-03-25 19:26:57 +04:00
struct ieee80211_channel * curchan = hw - > conf . chandef . chan ;
2010-03-17 11:55:25 +03:00
struct ath9k_channel * channel ;
u8 chan_idx ;
chan_idx = curchan - > hw_value ;
channel = & ah - > channels [ chan_idx ] ;
2013-08-16 12:46:04 +04:00
ath9k_cmn_update_ichannel ( channel , & hw - > conf . chandef ) ;
2010-03-17 11:55:25 +03:00
return channel ;
}
EXPORT_SYMBOL ( ath9k_cmn_get_curchannel ) ;
2010-06-02 14:23:37 +04:00
int ath9k_cmn_count_streams ( unsigned int chainmask , int max )
{
int streams = 0 ;
do {
if ( + + streams = = max )
break ;
} while ( ( chainmask = chainmask & ( chainmask - 1 ) ) ) ;
return streams ;
}
EXPORT_SYMBOL ( ath9k_cmn_count_streams ) ;
2011-01-31 21:17:44 +03:00
void ath9k_cmn_update_txpow ( struct ath_hw * ah , u16 cur_txpow ,
u16 new_txpow , u16 * txpower )
{
2011-10-08 22:06:20 +04:00
struct ath_regulatory * reg = ath9k_hw_regulatory ( ah ) ;
if ( reg - > power_limit ! = new_txpow ) {
2011-01-31 21:17:44 +03:00
ath9k_hw_set_txpowerlimit ( ah , new_txpow , false ) ;
/* read back in case value is clamped */
2011-10-08 22:06:20 +04:00
* txpower = reg - > max_power_level ;
2011-01-31 21:17:44 +03:00
}
}
EXPORT_SYMBOL ( ath9k_cmn_update_txpow ) ;
2011-08-13 08:58:15 +04:00
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 ) ;
2009-11-05 19:44:39 +03:00
static int __init ath9k_cmn_init ( void )
{
return 0 ;
}
module_init ( ath9k_cmn_init ) ;
static void __exit ath9k_cmn_exit ( void )
{
return ;
}
module_exit ( ath9k_cmn_exit ) ;