0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019 #include "common.h"
0020
0021 #define CHAN2G(_freq, _idx) { \
0022 .band = NL80211_BAND_2GHZ, \
0023 .center_freq = (_freq), \
0024 .hw_value = (_idx), \
0025 .max_power = 20, \
0026 }
0027
0028 #define CHAN5G(_freq, _idx) { \
0029 .band = NL80211_BAND_5GHZ, \
0030 .center_freq = (_freq), \
0031 .hw_value = (_idx), \
0032 .max_power = 20, \
0033 }
0034
0035
0036
0037
0038
0039 static const struct ieee80211_channel ath9k_2ghz_chantable[] = {
0040 CHAN2G(2412, 0),
0041 CHAN2G(2417, 1),
0042 CHAN2G(2422, 2),
0043 CHAN2G(2427, 3),
0044 CHAN2G(2432, 4),
0045 CHAN2G(2437, 5),
0046 CHAN2G(2442, 6),
0047 CHAN2G(2447, 7),
0048 CHAN2G(2452, 8),
0049 CHAN2G(2457, 9),
0050 CHAN2G(2462, 10),
0051 CHAN2G(2467, 11),
0052 CHAN2G(2472, 12),
0053 CHAN2G(2484, 13),
0054 };
0055
0056
0057
0058
0059
0060 static const struct ieee80211_channel ath9k_5ghz_chantable[] = {
0061
0062 CHAN5G(5180, 14),
0063 CHAN5G(5200, 15),
0064 CHAN5G(5220, 16),
0065 CHAN5G(5240, 17),
0066
0067 CHAN5G(5260, 18),
0068 CHAN5G(5280, 19),
0069 CHAN5G(5300, 20),
0070 CHAN5G(5320, 21),
0071
0072 CHAN5G(5500, 22),
0073 CHAN5G(5520, 23),
0074 CHAN5G(5540, 24),
0075 CHAN5G(5560, 25),
0076 CHAN5G(5580, 26),
0077 CHAN5G(5600, 27),
0078 CHAN5G(5620, 28),
0079 CHAN5G(5640, 29),
0080 CHAN5G(5660, 30),
0081 CHAN5G(5680, 31),
0082 CHAN5G(5700, 32),
0083
0084 CHAN5G(5745, 33),
0085 CHAN5G(5765, 34),
0086 CHAN5G(5785, 35),
0087 CHAN5G(5805, 36),
0088 CHAN5G(5825, 37),
0089 };
0090
0091
0092 #define SHPCHECK(__hw_rate, __flags) \
0093 ((__flags & IEEE80211_RATE_SHORT_PREAMBLE) ? (__hw_rate | 0x04 ) : 0)
0094
0095 #define RATE(_bitrate, _hw_rate, _flags) { \
0096 .bitrate = (_bitrate), \
0097 .flags = (_flags), \
0098 .hw_value = (_hw_rate), \
0099 .hw_value_short = (SHPCHECK(_hw_rate, _flags)) \
0100 }
0101
0102 static struct ieee80211_rate ath9k_legacy_rates[] = {
0103 RATE(10, 0x1b, 0),
0104 RATE(20, 0x1a, IEEE80211_RATE_SHORT_PREAMBLE),
0105 RATE(55, 0x19, IEEE80211_RATE_SHORT_PREAMBLE),
0106 RATE(110, 0x18, IEEE80211_RATE_SHORT_PREAMBLE),
0107 RATE(60, 0x0b, (IEEE80211_RATE_SUPPORTS_5MHZ |
0108 IEEE80211_RATE_SUPPORTS_10MHZ)),
0109 RATE(90, 0x0f, (IEEE80211_RATE_SUPPORTS_5MHZ |
0110 IEEE80211_RATE_SUPPORTS_10MHZ)),
0111 RATE(120, 0x0a, (IEEE80211_RATE_SUPPORTS_5MHZ |
0112 IEEE80211_RATE_SUPPORTS_10MHZ)),
0113 RATE(180, 0x0e, (IEEE80211_RATE_SUPPORTS_5MHZ |
0114 IEEE80211_RATE_SUPPORTS_10MHZ)),
0115 RATE(240, 0x09, (IEEE80211_RATE_SUPPORTS_5MHZ |
0116 IEEE80211_RATE_SUPPORTS_10MHZ)),
0117 RATE(360, 0x0d, (IEEE80211_RATE_SUPPORTS_5MHZ |
0118 IEEE80211_RATE_SUPPORTS_10MHZ)),
0119 RATE(480, 0x08, (IEEE80211_RATE_SUPPORTS_5MHZ |
0120 IEEE80211_RATE_SUPPORTS_10MHZ)),
0121 RATE(540, 0x0c, (IEEE80211_RATE_SUPPORTS_5MHZ |
0122 IEEE80211_RATE_SUPPORTS_10MHZ)),
0123 };
0124
0125 int ath9k_cmn_init_channels_rates(struct ath_common *common)
0126 {
0127 struct ath_hw *ah = (struct ath_hw *)common->ah;
0128 void *channels;
0129
0130 BUILD_BUG_ON(ARRAY_SIZE(ath9k_2ghz_chantable) +
0131 ARRAY_SIZE(ath9k_5ghz_chantable) !=
0132 ATH9K_NUM_CHANNELS);
0133
0134 if (ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ) {
0135 channels = devm_kzalloc(ah->dev,
0136 sizeof(ath9k_2ghz_chantable), GFP_KERNEL);
0137 if (!channels)
0138 return -ENOMEM;
0139
0140 memcpy(channels, ath9k_2ghz_chantable,
0141 sizeof(ath9k_2ghz_chantable));
0142 common->sbands[NL80211_BAND_2GHZ].channels = channels;
0143 common->sbands[NL80211_BAND_2GHZ].band = NL80211_BAND_2GHZ;
0144 common->sbands[NL80211_BAND_2GHZ].n_channels =
0145 ARRAY_SIZE(ath9k_2ghz_chantable);
0146 common->sbands[NL80211_BAND_2GHZ].bitrates = ath9k_legacy_rates;
0147 common->sbands[NL80211_BAND_2GHZ].n_bitrates =
0148 ARRAY_SIZE(ath9k_legacy_rates);
0149 }
0150
0151 if (ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ) {
0152 channels = devm_kzalloc(ah->dev,
0153 sizeof(ath9k_5ghz_chantable), GFP_KERNEL);
0154 if (!channels)
0155 return -ENOMEM;
0156
0157 memcpy(channels, ath9k_5ghz_chantable,
0158 sizeof(ath9k_5ghz_chantable));
0159 common->sbands[NL80211_BAND_5GHZ].channels = channels;
0160 common->sbands[NL80211_BAND_5GHZ].band = NL80211_BAND_5GHZ;
0161 common->sbands[NL80211_BAND_5GHZ].n_channels =
0162 ARRAY_SIZE(ath9k_5ghz_chantable);
0163 common->sbands[NL80211_BAND_5GHZ].bitrates =
0164 ath9k_legacy_rates + 4;
0165 common->sbands[NL80211_BAND_5GHZ].n_bitrates =
0166 ARRAY_SIZE(ath9k_legacy_rates) - 4;
0167 }
0168 return 0;
0169 }
0170 EXPORT_SYMBOL(ath9k_cmn_init_channels_rates);
0171
0172 void ath9k_cmn_setup_ht_cap(struct ath_hw *ah,
0173 struct ieee80211_sta_ht_cap *ht_info)
0174 {
0175 struct ath_common *common = ath9k_hw_common(ah);
0176 u8 tx_streams, rx_streams;
0177 int i, max_streams;
0178
0179 ht_info->ht_supported = true;
0180 ht_info->cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 |
0181 IEEE80211_HT_CAP_SM_PS |
0182 IEEE80211_HT_CAP_SGI_40 |
0183 IEEE80211_HT_CAP_DSSSCCK40;
0184
0185 if (ah->caps.hw_caps & ATH9K_HW_CAP_LDPC)
0186 ht_info->cap |= IEEE80211_HT_CAP_LDPC_CODING;
0187
0188 if (ah->caps.hw_caps & ATH9K_HW_CAP_SGI_20)
0189 ht_info->cap |= IEEE80211_HT_CAP_SGI_20;
0190
0191 ht_info->ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
0192 ht_info->ampdu_density = IEEE80211_HT_MPDU_DENSITY_8;
0193
0194 if (AR_SREV_9271(ah) || AR_SREV_9330(ah) || AR_SREV_9485(ah) || AR_SREV_9565(ah))
0195 max_streams = 1;
0196 else if (AR_SREV_9462(ah))
0197 max_streams = 2;
0198 else if (AR_SREV_9300_20_OR_LATER(ah))
0199 max_streams = 3;
0200 else
0201 max_streams = 2;
0202
0203 if (AR_SREV_9280_20_OR_LATER(ah)) {
0204 if (max_streams >= 2)
0205 ht_info->cap |= IEEE80211_HT_CAP_TX_STBC;
0206 ht_info->cap |= (1 << IEEE80211_HT_CAP_RX_STBC_SHIFT);
0207 }
0208
0209
0210 memset(&ht_info->mcs, 0, sizeof(ht_info->mcs));
0211 tx_streams = ath9k_cmn_count_streams(ah->txchainmask, max_streams);
0212 rx_streams = ath9k_cmn_count_streams(ah->rxchainmask, max_streams);
0213
0214 ath_dbg(common, CONFIG, "TX streams %d, RX streams: %d\n",
0215 tx_streams, rx_streams);
0216
0217 if (tx_streams != rx_streams) {
0218 ht_info->mcs.tx_params |= IEEE80211_HT_MCS_TX_RX_DIFF;
0219 ht_info->mcs.tx_params |= ((tx_streams - 1) <<
0220 IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT);
0221 }
0222
0223 for (i = 0; i < rx_streams; i++)
0224 ht_info->mcs.rx_mask[i] = 0xff;
0225
0226 ht_info->mcs.tx_params |= IEEE80211_HT_MCS_TX_DEFINED;
0227 }
0228 EXPORT_SYMBOL(ath9k_cmn_setup_ht_cap);
0229
0230 void ath9k_cmn_reload_chainmask(struct ath_hw *ah)
0231 {
0232 struct ath_common *common = ath9k_hw_common(ah);
0233
0234 if (!(ah->caps.hw_caps & ATH9K_HW_CAP_HT))
0235 return;
0236
0237 if (ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ)
0238 ath9k_cmn_setup_ht_cap(ah,
0239 &common->sbands[NL80211_BAND_2GHZ].ht_cap);
0240 if (ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ)
0241 ath9k_cmn_setup_ht_cap(ah,
0242 &common->sbands[NL80211_BAND_5GHZ].ht_cap);
0243 }
0244 EXPORT_SYMBOL(ath9k_cmn_reload_chainmask);