aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2009-02-15 02:06:44 -0500
committerDavid S. Miller <davem@davemloft.net>2009-02-15 02:06:44 -0500
commitac178ef0ae9eb44fd527d87aa9b6394e05f56e1f (patch)
tree5d6bd46ecf9ce989134d3c460e1ecf5dd1fceadc /drivers/net/wireless
parentf3a7c66b5ce0b75a9774a50b5dcce93e5ba28370 (diff)
parent6d08b9b9c6eb2414c4a037407dd121298a74fb36 (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6
Diffstat (limited to 'drivers/net/wireless')
-rw-r--r--drivers/net/wireless/ath5k/ath5k.h73
-rw-r--r--drivers/net/wireless/ath5k/attach.c18
-rw-r--r--drivers/net/wireless/ath5k/base.c15
-rw-r--r--drivers/net/wireless/ath5k/eeprom.c18
-rw-r--r--drivers/net/wireless/ath5k/eeprom.h1
-rw-r--r--drivers/net/wireless/ath5k/initvals.c1575
-rw-r--r--drivers/net/wireless/ath5k/phy.c2029
-rw-r--r--drivers/net/wireless/ath5k/reg.h124
-rw-r--r--drivers/net/wireless/ath5k/reset.c948
-rw-r--r--drivers/net/wireless/ath5k/rfbuffer.h1181
-rw-r--r--drivers/net/wireless/ath5k/rfgain.h516
-rw-r--r--drivers/net/wireless/ath9k/ahb.c16
-rw-r--r--drivers/net/wireless/ath9k/ani.c263
-rw-r--r--drivers/net/wireless/ath9k/ani.h138
-rw-r--r--drivers/net/wireless/ath9k/ath9k.h1640
-rw-r--r--drivers/net/wireless/ath9k/beacon.c96
-rw-r--r--drivers/net/wireless/ath9k/calib.c190
-rw-r--r--drivers/net/wireless/ath9k/calib.h124
-rw-r--r--drivers/net/wireless/ath9k/core.h816
-rw-r--r--drivers/net/wireless/ath9k/debug.c149
-rw-r--r--drivers/net/wireless/ath9k/debug.h153
-rw-r--r--drivers/net/wireless/ath9k/eeprom.c2922
-rw-r--r--drivers/net/wireless/ath9k/eeprom.h473
-rw-r--r--drivers/net/wireless/ath9k/hw.c1181
-rw-r--r--drivers/net/wireless/ath9k/hw.h1568
-rw-r--r--drivers/net/wireless/ath9k/mac.c175
-rw-r--r--drivers/net/wireless/ath9k/mac.h676
-rw-r--r--drivers/net/wireless/ath9k/main.c479
-rw-r--r--drivers/net/wireless/ath9k/pci.c20
-rw-r--r--drivers/net/wireless/ath9k/phy.c221
-rw-r--r--drivers/net/wireless/ath9k/phy.h14
-rw-r--r--drivers/net/wireless/ath9k/rc.c16
-rw-r--r--drivers/net/wireless/ath9k/rc.h17
-rw-r--r--drivers/net/wireless/ath9k/recv.c51
-rw-r--r--drivers/net/wireless/ath9k/reg.h53
-rw-r--r--drivers/net/wireless/ath9k/regd.c70
-rw-r--r--drivers/net/wireless/ath9k/regd.h26
-rw-r--r--drivers/net/wireless/ath9k/xmit.c51
-rw-r--r--drivers/net/wireless/b43/b43.h3
-rw-r--r--drivers/net/wireless/b43/phy_lp.c177
-rw-r--r--drivers/net/wireless/b43/phy_lp.h16
-rw-r--r--drivers/net/wireless/b43/tables_lpphy.c61
-rw-r--r--drivers/net/wireless/b43/tables_lpphy.h8
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945-hw.h6
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945.c23
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965-hw.h7
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965.c21
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-5000.c13
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.c18
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.c1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.h8
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-eeprom.c8
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-eeprom.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-power.c6
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-scan.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl3945-base.c17
-rw-r--r--drivers/net/wireless/orinoco/Makefile3
-rw-r--r--drivers/net/wireless/orinoco/airport.c2
-rw-r--r--drivers/net/wireless/orinoco/fw.c340
-rw-r--r--drivers/net/wireless/orinoco/fw.h16
-rw-r--r--drivers/net/wireless/orinoco/hermes.c18
-rw-r--r--drivers/net/wireless/orinoco/hermes_dld.c33
-rw-r--r--drivers/net/wireless/orinoco/hw.c586
-rw-r--r--drivers/net/wireless/orinoco/hw.h47
-rw-r--r--drivers/net/wireless/orinoco/main.c2654
-rw-r--r--drivers/net/wireless/orinoco/main.h63
-rw-r--r--drivers/net/wireless/orinoco/mic.c79
-rw-r--r--drivers/net/wireless/orinoco/mic.h22
-rw-r--r--drivers/net/wireless/orinoco/orinoco.c6153
-rw-r--r--drivers/net/wireless/orinoco/orinoco_cs.c2
-rw-r--r--drivers/net/wireless/orinoco/orinoco_pci.h2
-rw-r--r--drivers/net/wireless/orinoco/orinoco_tmd.c2
-rw-r--r--drivers/net/wireless/orinoco/scan.c233
-rw-r--r--drivers/net/wireless/orinoco/scan.h29
-rw-r--r--drivers/net/wireless/orinoco/spectrum_cs.c4
-rw-r--r--drivers/net/wireless/orinoco/wext.c2325
-rw-r--r--drivers/net/wireless/orinoco/wext.h13
-rw-r--r--drivers/net/wireless/zd1211rw/zd_def.h5
-rw-r--r--drivers/net/wireless/zd1211rw/zd_mac.c23
79 files changed, 16176 insertions, 14971 deletions
diff --git a/drivers/net/wireless/ath5k/ath5k.h b/drivers/net/wireless/ath5k/ath5k.h
index 0eda785fe62f..b9af2b84c05f 100644
--- a/drivers/net/wireless/ath5k/ath5k.h
+++ b/drivers/net/wireless/ath5k/ath5k.h
@@ -165,9 +165,6 @@
165#define AR5K_INI_VAL_XR 0 165#define AR5K_INI_VAL_XR 0
166#define AR5K_INI_VAL_MAX 5 166#define AR5K_INI_VAL_MAX 5
167 167
168#define AR5K_RF5111_INI_RF_MAX_BANKS AR5K_MAX_RF_BANKS
169#define AR5K_RF5112_INI_RF_MAX_BANKS AR5K_MAX_RF_BANKS
170
171/* Used for BSSID etc manipulation */ 168/* Used for BSSID etc manipulation */
172#define AR5K_LOW_ID(_a)( \ 169#define AR5K_LOW_ID(_a)( \
173(_a)[0] | (_a)[1] << 8 | (_a)[2] << 16 | (_a)[3] << 24 \ 170(_a)[0] | (_a)[1] << 8 | (_a)[2] << 16 | (_a)[3] << 24 \
@@ -225,6 +222,7 @@
225#endif 222#endif
226 223
227/* Initial values */ 224/* Initial values */
225#define AR5K_INIT_CYCRSSI_THR1 2
228#define AR5K_INIT_TX_LATENCY 502 226#define AR5K_INIT_TX_LATENCY 502
229#define AR5K_INIT_USEC 39 227#define AR5K_INIT_USEC 39
230#define AR5K_INIT_USEC_TURBO 79 228#define AR5K_INIT_USEC_TURBO 79
@@ -316,7 +314,7 @@ struct ath5k_srev_name {
316#define AR5K_SREV_AR5424 0x90 /* Condor */ 314#define AR5K_SREV_AR5424 0x90 /* Condor */
317#define AR5K_SREV_AR5413 0xa4 /* Eagle lite */ 315#define AR5K_SREV_AR5413 0xa4 /* Eagle lite */
318#define AR5K_SREV_AR5414 0xa0 /* Eagle */ 316#define AR5K_SREV_AR5414 0xa0 /* Eagle */
319#define AR5K_SREV_AR2415 0xb0 /* Cobra */ 317#define AR5K_SREV_AR2415 0xb0 /* Talon */
320#define AR5K_SREV_AR5416 0xc0 /* PCI-E */ 318#define AR5K_SREV_AR5416 0xc0 /* PCI-E */
321#define AR5K_SREV_AR5418 0xca /* PCI-E */ 319#define AR5K_SREV_AR5418 0xca /* PCI-E */
322#define AR5K_SREV_AR2425 0xe0 /* Swan */ 320#define AR5K_SREV_AR2425 0xe0 /* Swan */
@@ -334,7 +332,7 @@ struct ath5k_srev_name {
334#define AR5K_SREV_RAD_2112B 0x46 332#define AR5K_SREV_RAD_2112B 0x46
335#define AR5K_SREV_RAD_2413 0x50 333#define AR5K_SREV_RAD_2413 0x50
336#define AR5K_SREV_RAD_5413 0x60 334#define AR5K_SREV_RAD_5413 0x60
337#define AR5K_SREV_RAD_2316 0x70 335#define AR5K_SREV_RAD_2316 0x70 /* Cobra SoC */
338#define AR5K_SREV_RAD_2317 0x80 336#define AR5K_SREV_RAD_2317 0x80
339#define AR5K_SREV_RAD_5424 0xa0 /* Mostly same as 5413 */ 337#define AR5K_SREV_RAD_5424 0xa0 /* Mostly same as 5413 */
340#define AR5K_SREV_RAD_2425 0xa2 338#define AR5K_SREV_RAD_2425 0xa2
@@ -342,7 +340,8 @@ struct ath5k_srev_name {
342 340
343#define AR5K_SREV_PHY_5211 0x30 341#define AR5K_SREV_PHY_5211 0x30
344#define AR5K_SREV_PHY_5212 0x41 342#define AR5K_SREV_PHY_5212 0x41
345#define AR5K_SREV_PHY_2112B 0x43 343#define AR5K_SREV_PHY_5212A 0x42
344#define AR5K_SREV_PHY_5212B 0x43
346#define AR5K_SREV_PHY_2413 0x45 345#define AR5K_SREV_PHY_2413 0x45
347#define AR5K_SREV_PHY_5413 0x61 346#define AR5K_SREV_PHY_5413 0x61
348#define AR5K_SREV_PHY_2425 0x70 347#define AR5K_SREV_PHY_2425 0x70
@@ -649,49 +648,21 @@ struct ath5k_beacon_state {
649 648
650enum ath5k_rfgain { 649enum ath5k_rfgain {
651 AR5K_RFGAIN_INACTIVE = 0, 650 AR5K_RFGAIN_INACTIVE = 0,
651 AR5K_RFGAIN_ACTIVE,
652 AR5K_RFGAIN_READ_REQUESTED, 652 AR5K_RFGAIN_READ_REQUESTED,
653 AR5K_RFGAIN_NEED_CHANGE, 653 AR5K_RFGAIN_NEED_CHANGE,
654}; 654};
655 655
656#define AR5K_GAIN_CRN_FIX_BITS_5111 4
657#define AR5K_GAIN_CRN_FIX_BITS_5112 7
658#define AR5K_GAIN_CRN_MAX_FIX_BITS AR5K_GAIN_CRN_FIX_BITS_5112
659#define AR5K_GAIN_DYN_ADJUST_HI_MARGIN 15
660#define AR5K_GAIN_DYN_ADJUST_LO_MARGIN 20
661#define AR5K_GAIN_CCK_PROBE_CORR 5
662#define AR5K_GAIN_CCK_OFDM_GAIN_DELTA 15
663#define AR5K_GAIN_STEP_COUNT 10
664#define AR5K_GAIN_PARAM_TX_CLIP 0
665#define AR5K_GAIN_PARAM_PD_90 1
666#define AR5K_GAIN_PARAM_PD_84 2
667#define AR5K_GAIN_PARAM_GAIN_SEL 3
668#define AR5K_GAIN_PARAM_MIX_ORN 0
669#define AR5K_GAIN_PARAM_PD_138 1
670#define AR5K_GAIN_PARAM_PD_137 2
671#define AR5K_GAIN_PARAM_PD_136 3
672#define AR5K_GAIN_PARAM_PD_132 4
673#define AR5K_GAIN_PARAM_PD_131 5
674#define AR5K_GAIN_PARAM_PD_130 6
675#define AR5K_GAIN_CHECK_ADJUST(_g) \
676 ((_g)->g_current <= (_g)->g_low || (_g)->g_current >= (_g)->g_high)
677
678struct ath5k_gain_opt_step {
679 s16 gos_param[AR5K_GAIN_CRN_MAX_FIX_BITS];
680 s32 gos_gain;
681};
682
683struct ath5k_gain { 656struct ath5k_gain {
684 u32 g_step_idx; 657 u8 g_step_idx;
685 u32 g_current; 658 u8 g_current;
686 u32 g_target; 659 u8 g_target;
687 u32 g_low; 660 u8 g_low;
688 u32 g_high; 661 u8 g_high;
689 u32 g_f_corr; 662 u8 g_f_corr;
690 u32 g_active; 663 u8 g_state;
691 const struct ath5k_gain_opt_step *g_step;
692}; 664};
693 665
694
695/********************\ 666/********************\
696 COMMON DEFINITIONS 667 COMMON DEFINITIONS
697\********************/ 668\********************/
@@ -1053,7 +1024,6 @@ struct ath5k_hw {
1053 bool ah_running; 1024 bool ah_running;
1054 bool ah_single_chip; 1025 bool ah_single_chip;
1055 bool ah_combined_mic; 1026 bool ah_combined_mic;
1056 enum ath5k_rfgain ah_rf_gain;
1057 1027
1058 u32 ah_mac_srev; 1028 u32 ah_mac_srev;
1059 u16 ah_mac_version; 1029 u16 ah_mac_version;
@@ -1061,7 +1031,6 @@ struct ath5k_hw {
1061 u16 ah_phy_revision; 1031 u16 ah_phy_revision;
1062 u16 ah_radio_5ghz_revision; 1032 u16 ah_radio_5ghz_revision;
1063 u16 ah_radio_2ghz_revision; 1033 u16 ah_radio_2ghz_revision;
1064 u32 ah_phy_spending;
1065 1034
1066 enum ath5k_version ah_version; 1035 enum ath5k_version ah_version;
1067 enum ath5k_radio ah_radio; 1036 enum ath5k_radio ah_radio;
@@ -1112,8 +1081,9 @@ struct ath5k_hw {
1112 u32 ah_txq_isr; 1081 u32 ah_txq_isr;
1113 u32 *ah_rf_banks; 1082 u32 *ah_rf_banks;
1114 size_t ah_rf_banks_size; 1083 size_t ah_rf_banks_size;
1084 size_t ah_rf_regs_count;
1115 struct ath5k_gain ah_gain; 1085 struct ath5k_gain ah_gain;
1116 u32 ah_offset[AR5K_MAX_RF_BANKS]; 1086 u8 ah_offset[AR5K_MAX_RF_BANKS];
1117 1087
1118 struct { 1088 struct {
1119 u16 txp_pcdac[AR5K_EEPROM_POWER_TABLE_SIZE]; 1089 u16 txp_pcdac[AR5K_EEPROM_POWER_TABLE_SIZE];
@@ -1186,6 +1156,7 @@ extern void ath5k_hw_update_mib_counters(struct ath5k_hw *ah, struct ieee80211_l
1186/* EEPROM access functions */ 1156/* EEPROM access functions */
1187extern int ath5k_eeprom_init(struct ath5k_hw *ah); 1157extern int ath5k_eeprom_init(struct ath5k_hw *ah);
1188extern int ath5k_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac); 1158extern int ath5k_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac);
1159extern bool ath5k_eeprom_is_hb63(struct ath5k_hw *ah);
1189 1160
1190/* Protocol Control Unit Functions */ 1161/* Protocol Control Unit Functions */
1191extern int ath5k_hw_set_opmode(struct ath5k_hw *ah); 1162extern int ath5k_hw_set_opmode(struct ath5k_hw *ah);
@@ -1261,10 +1232,12 @@ extern int ath5k_hw_disable_pspoll(struct ath5k_hw *ah);
1261extern int ath5k_hw_write_initvals(struct ath5k_hw *ah, u8 mode, bool change_channel); 1232extern int ath5k_hw_write_initvals(struct ath5k_hw *ah, u8 mode, bool change_channel);
1262 1233
1263/* Initialize RF */ 1234/* Initialize RF */
1264extern int ath5k_hw_rfregs(struct ath5k_hw *ah, struct ieee80211_channel *channel, unsigned int mode); 1235extern int ath5k_hw_rfregs_init(struct ath5k_hw *ah,
1265extern int ath5k_hw_rfgain(struct ath5k_hw *ah, unsigned int freq); 1236 struct ieee80211_channel *channel,
1266extern enum ath5k_rfgain ath5k_hw_get_rf_gain(struct ath5k_hw *ah); 1237 unsigned int mode);
1267extern int ath5k_hw_set_rfgain_opt(struct ath5k_hw *ah); 1238extern int ath5k_hw_rfgain_init(struct ath5k_hw *ah, unsigned int freq);
1239extern enum ath5k_rfgain ath5k_hw_gainf_calibrate(struct ath5k_hw *ah);
1240extern int ath5k_hw_rfgain_opt_init(struct ath5k_hw *ah);
1268/* PHY/RF channel functions */ 1241/* PHY/RF channel functions */
1269extern bool ath5k_channel_ok(struct ath5k_hw *ah, u16 freq, unsigned int flags); 1242extern bool ath5k_channel_ok(struct ath5k_hw *ah, u16 freq, unsigned int flags);
1270extern int ath5k_hw_channel(struct ath5k_hw *ah, struct ieee80211_channel *channel); 1243extern int ath5k_hw_channel(struct ath5k_hw *ah, struct ieee80211_channel *channel);
@@ -1286,6 +1259,7 @@ extern int ath5k_hw_set_txpower_limit(struct ath5k_hw *ah, unsigned int power);
1286 1259
1287/* 1260/*
1288 * Translate usec to hw clock units 1261 * Translate usec to hw clock units
1262 * TODO: Half/quarter rate
1289 */ 1263 */
1290static inline unsigned int ath5k_hw_htoclock(unsigned int usec, bool turbo) 1264static inline unsigned int ath5k_hw_htoclock(unsigned int usec, bool turbo)
1291{ 1265{
@@ -1294,6 +1268,7 @@ static inline unsigned int ath5k_hw_htoclock(unsigned int usec, bool turbo)
1294 1268
1295/* 1269/*
1296 * Translate hw clock units to usec 1270 * Translate hw clock units to usec
1271 * TODO: Half/quarter rate
1297 */ 1272 */
1298static inline unsigned int ath5k_hw_clocktoh(unsigned int clock, bool turbo) 1273static inline unsigned int ath5k_hw_clocktoh(unsigned int clock, bool turbo)
1299{ 1274{
diff --git a/drivers/net/wireless/ath5k/attach.c b/drivers/net/wireless/ath5k/attach.c
index dea378f76731..05bc5cb44e88 100644
--- a/drivers/net/wireless/ath5k/attach.c
+++ b/drivers/net/wireless/ath5k/attach.c
@@ -169,7 +169,6 @@ struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc, u8 mac_version)
169 ah->ah_single_chip = false; 169 ah->ah_single_chip = false;
170 ah->ah_radio_2ghz_revision = ath5k_hw_radio_revision(ah, 170 ah->ah_radio_2ghz_revision = ath5k_hw_radio_revision(ah,
171 CHANNEL_2GHZ); 171 CHANNEL_2GHZ);
172 ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5111;
173 break; 172 break;
174 case AR5K_SREV_RAD_5112: 173 case AR5K_SREV_RAD_5112:
175 case AR5K_SREV_RAD_2112: 174 case AR5K_SREV_RAD_2112:
@@ -177,38 +176,31 @@ struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc, u8 mac_version)
177 ah->ah_single_chip = false; 176 ah->ah_single_chip = false;
178 ah->ah_radio_2ghz_revision = ath5k_hw_radio_revision(ah, 177 ah->ah_radio_2ghz_revision = ath5k_hw_radio_revision(ah,
179 CHANNEL_2GHZ); 178 CHANNEL_2GHZ);
180 ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5112;
181 break; 179 break;
182 case AR5K_SREV_RAD_2413: 180 case AR5K_SREV_RAD_2413:
183 ah->ah_radio = AR5K_RF2413; 181 ah->ah_radio = AR5K_RF2413;
184 ah->ah_single_chip = true; 182 ah->ah_single_chip = true;
185 ah->ah_phy_spending = AR5K_PHY_SPENDING_RF2413;
186 break; 183 break;
187 case AR5K_SREV_RAD_5413: 184 case AR5K_SREV_RAD_5413:
188 ah->ah_radio = AR5K_RF5413; 185 ah->ah_radio = AR5K_RF5413;
189 ah->ah_single_chip = true; 186 ah->ah_single_chip = true;
190 ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5413;
191 break; 187 break;
192 case AR5K_SREV_RAD_2316: 188 case AR5K_SREV_RAD_2316:
193 ah->ah_radio = AR5K_RF2316; 189 ah->ah_radio = AR5K_RF2316;
194 ah->ah_single_chip = true; 190 ah->ah_single_chip = true;
195 ah->ah_phy_spending = AR5K_PHY_SPENDING_RF2316;
196 break; 191 break;
197 case AR5K_SREV_RAD_2317: 192 case AR5K_SREV_RAD_2317:
198 ah->ah_radio = AR5K_RF2317; 193 ah->ah_radio = AR5K_RF2317;
199 ah->ah_single_chip = true; 194 ah->ah_single_chip = true;
200 ah->ah_phy_spending = AR5K_PHY_SPENDING_RF2317;
201 break; 195 break;
202 case AR5K_SREV_RAD_5424: 196 case AR5K_SREV_RAD_5424:
203 if (ah->ah_mac_version == AR5K_SREV_AR2425 || 197 if (ah->ah_mac_version == AR5K_SREV_AR2425 ||
204 ah->ah_mac_version == AR5K_SREV_AR2417){ 198 ah->ah_mac_version == AR5K_SREV_AR2417){
205 ah->ah_radio = AR5K_RF2425; 199 ah->ah_radio = AR5K_RF2425;
206 ah->ah_single_chip = true; 200 ah->ah_single_chip = true;
207 ah->ah_phy_spending = AR5K_PHY_SPENDING_RF2425;
208 } else { 201 } else {
209 ah->ah_radio = AR5K_RF5413; 202 ah->ah_radio = AR5K_RF5413;
210 ah->ah_single_chip = true; 203 ah->ah_single_chip = true;
211 ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5413;
212 } 204 }
213 break; 205 break;
214 default: 206 default:
@@ -227,29 +219,25 @@ struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc, u8 mac_version)
227 ah->ah_radio = AR5K_RF2425; 219 ah->ah_radio = AR5K_RF2425;
228 ah->ah_single_chip = true; 220 ah->ah_single_chip = true;
229 ah->ah_radio_5ghz_revision = AR5K_SREV_RAD_2425; 221 ah->ah_radio_5ghz_revision = AR5K_SREV_RAD_2425;
230 ah->ah_phy_spending = AR5K_PHY_SPENDING_RF2425;
231 } else if (srev == AR5K_SREV_AR5213A && 222 } else if (srev == AR5K_SREV_AR5213A &&
232 ah->ah_phy_revision == AR5K_SREV_PHY_2112B) { 223 ah->ah_phy_revision == AR5K_SREV_PHY_5212B) {
233 ah->ah_radio = AR5K_RF5112; 224 ah->ah_radio = AR5K_RF5112;
234 ah->ah_single_chip = false; 225 ah->ah_single_chip = false;
235 ah->ah_radio_5ghz_revision = AR5K_SREV_RAD_2112B; 226 ah->ah_radio_5ghz_revision = AR5K_SREV_RAD_5112B;
236 } else if (ah->ah_mac_version == (AR5K_SREV_AR2415 >> 4)) { 227 } else if (ah->ah_mac_version == (AR5K_SREV_AR2415 >> 4)) {
237 ah->ah_radio = AR5K_RF2316; 228 ah->ah_radio = AR5K_RF2316;
238 ah->ah_single_chip = true; 229 ah->ah_single_chip = true;
239 ah->ah_radio_5ghz_revision = AR5K_SREV_RAD_2316; 230 ah->ah_radio_5ghz_revision = AR5K_SREV_RAD_2316;
240 ah->ah_phy_spending = AR5K_PHY_SPENDING_RF2316;
241 } else if (ah->ah_mac_version == (AR5K_SREV_AR5414 >> 4) || 231 } else if (ah->ah_mac_version == (AR5K_SREV_AR5414 >> 4) ||
242 ah->ah_phy_revision == AR5K_SREV_PHY_5413) { 232 ah->ah_phy_revision == AR5K_SREV_PHY_5413) {
243 ah->ah_radio = AR5K_RF5413; 233 ah->ah_radio = AR5K_RF5413;
244 ah->ah_single_chip = true; 234 ah->ah_single_chip = true;
245 ah->ah_radio_5ghz_revision = AR5K_SREV_RAD_5413; 235 ah->ah_radio_5ghz_revision = AR5K_SREV_RAD_5413;
246 ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5413;
247 } else if (ah->ah_mac_version == (AR5K_SREV_AR2414 >> 4) || 236 } else if (ah->ah_mac_version == (AR5K_SREV_AR2414 >> 4) ||
248 ah->ah_phy_revision == AR5K_SREV_PHY_2413) { 237 ah->ah_phy_revision == AR5K_SREV_PHY_2413) {
249 ah->ah_radio = AR5K_RF2413; 238 ah->ah_radio = AR5K_RF2413;
250 ah->ah_single_chip = true; 239 ah->ah_single_chip = true;
251 ah->ah_radio_5ghz_revision = AR5K_SREV_RAD_2413; 240 ah->ah_radio_5ghz_revision = AR5K_SREV_RAD_2413;
252 ah->ah_phy_spending = AR5K_PHY_SPENDING_RF2413;
253 } else { 241 } else {
254 ATH5K_ERR(sc, "Couldn't identify radio revision.\n"); 242 ATH5K_ERR(sc, "Couldn't identify radio revision.\n");
255 ret = -ENODEV; 243 ret = -ENODEV;
@@ -331,7 +319,7 @@ struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc, u8 mac_version)
331 ath5k_hw_set_associd(ah, ah->ah_bssid, 0); 319 ath5k_hw_set_associd(ah, ah->ah_bssid, 0);
332 ath5k_hw_set_opmode(ah); 320 ath5k_hw_set_opmode(ah);
333 321
334 ath5k_hw_set_rfgain_opt(ah); 322 ath5k_hw_rfgain_opt_init(ah);
335 323
336 return ah; 324 return ah;
337err_free: 325err_free:
diff --git a/drivers/net/wireless/ath5k/base.c b/drivers/net/wireless/ath5k/base.c
index f9d486ff04f2..6837ca9f3831 100644
--- a/drivers/net/wireless/ath5k/base.c
+++ b/drivers/net/wireless/ath5k/base.c
@@ -2209,10 +2209,6 @@ ath5k_beacon_update_timers(struct ath5k_softc *sc, u64 bc_tsf)
2209 * 2209 *
2210 * @sc: struct ath5k_softc pointer we are operating on 2210 * @sc: struct ath5k_softc pointer we are operating on
2211 * 2211 *
2212 * When operating in station mode we want to receive a BMISS interrupt when we
2213 * stop seeing beacons from the AP we've associated with so we can look for
2214 * another AP to associate with.
2215 *
2216 * In IBSS mode we use a self-linked tx descriptor if possible. We enable SWBA 2212 * In IBSS mode we use a self-linked tx descriptor if possible. We enable SWBA
2217 * interrupts to detect TSF updates only. 2213 * interrupts to detect TSF updates only.
2218 */ 2214 */
@@ -2225,9 +2221,7 @@ ath5k_beacon_config(struct ath5k_softc *sc)
2225 sc->bmisscount = 0; 2221 sc->bmisscount = 0;
2226 sc->imask &= ~(AR5K_INT_BMISS | AR5K_INT_SWBA); 2222 sc->imask &= ~(AR5K_INT_BMISS | AR5K_INT_SWBA);
2227 2223
2228 if (sc->opmode == NL80211_IFTYPE_STATION) { 2224 if (sc->opmode == NL80211_IFTYPE_ADHOC ||
2229 sc->imask |= AR5K_INT_BMISS;
2230 } else if (sc->opmode == NL80211_IFTYPE_ADHOC ||
2231 sc->opmode == NL80211_IFTYPE_MESH_POINT || 2225 sc->opmode == NL80211_IFTYPE_MESH_POINT ||
2232 sc->opmode == NL80211_IFTYPE_AP) { 2226 sc->opmode == NL80211_IFTYPE_AP) {
2233 /* 2227 /*
@@ -2479,6 +2473,7 @@ ath5k_intr(int irq, void *dev_id)
2479 | AR5K_INT_TXERR | AR5K_INT_TXEOL)) 2473 | AR5K_INT_TXERR | AR5K_INT_TXEOL))
2480 tasklet_schedule(&sc->txtq); 2474 tasklet_schedule(&sc->txtq);
2481 if (status & AR5K_INT_BMISS) { 2475 if (status & AR5K_INT_BMISS) {
2476 /* TODO */
2482 } 2477 }
2483 if (status & AR5K_INT_MIB) { 2478 if (status & AR5K_INT_MIB) {
2484 /* 2479 /*
@@ -2518,7 +2513,7 @@ ath5k_calibrate(unsigned long data)
2518 ieee80211_frequency_to_channel(sc->curchan->center_freq), 2513 ieee80211_frequency_to_channel(sc->curchan->center_freq),
2519 sc->curchan->hw_value); 2514 sc->curchan->hw_value);
2520 2515
2521 if (ath5k_hw_get_rf_gain(ah) == AR5K_RFGAIN_NEED_CHANGE) { 2516 if (ath5k_hw_gainf_calibrate(ah) == AR5K_RFGAIN_NEED_CHANGE) {
2522 /* 2517 /*
2523 * Rfgain is out of bounds, reset the chip 2518 * Rfgain is out of bounds, reset the chip
2524 * to load new gain values. 2519 * to load new gain values.
@@ -2889,7 +2884,7 @@ ath5k_config_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
2889{ 2884{
2890 struct ath5k_softc *sc = hw->priv; 2885 struct ath5k_softc *sc = hw->priv;
2891 struct ath5k_hw *ah = sc->ah; 2886 struct ath5k_hw *ah = sc->ah;
2892 int ret; 2887 int ret = 0;
2893 2888
2894 mutex_lock(&sc->lock); 2889 mutex_lock(&sc->lock);
2895 if (sc->vif != vif) { 2890 if (sc->vif != vif) {
@@ -2915,9 +2910,7 @@ ath5k_config_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
2915 } 2910 }
2916 ath5k_beacon_update(sc, beacon); 2911 ath5k_beacon_update(sc, beacon);
2917 } 2912 }
2918 mutex_unlock(&sc->lock);
2919 2913
2920 return ath5k_reset_wake(sc);
2921unlock: 2914unlock:
2922 mutex_unlock(&sc->lock); 2915 mutex_unlock(&sc->lock);
2923 return ret; 2916 return ret;
diff --git a/drivers/net/wireless/ath5k/eeprom.c b/drivers/net/wireless/ath5k/eeprom.c
index b4ec539c464b..a54ee7e4967b 100644
--- a/drivers/net/wireless/ath5k/eeprom.c
+++ b/drivers/net/wireless/ath5k/eeprom.c
@@ -204,7 +204,7 @@ static int ath5k_eeprom_read_ants(struct ath5k_hw *ah, u32 *offset,
204 204
205 /* Get antenna modes */ 205 /* Get antenna modes */
206 ah->ah_antenna[mode][0] = 206 ah->ah_antenna[mode][0] =
207 (ee->ee_ant_control[mode][0] << 4) | 0x1; 207 (ee->ee_ant_control[mode][0] << 4);
208 ah->ah_antenna[mode][AR5K_ANT_FIXED_A] = 208 ah->ah_antenna[mode][AR5K_ANT_FIXED_A] =
209 ee->ee_ant_control[mode][1] | 209 ee->ee_ant_control[mode][1] |
210 (ee->ee_ant_control[mode][2] << 6) | 210 (ee->ee_ant_control[mode][2] << 6) |
@@ -517,9 +517,9 @@ ath5k_eeprom_init_modes(struct ath5k_hw *ah)
517static inline void 517static inline void
518ath5k_get_pcdac_intercepts(struct ath5k_hw *ah, u8 min, u8 max, u8 *vp) 518ath5k_get_pcdac_intercepts(struct ath5k_hw *ah, u8 min, u8 max, u8 *vp)
519{ 519{
520 const static u16 intercepts3[] = 520 static const u16 intercepts3[] =
521 { 0, 5, 10, 20, 30, 50, 70, 85, 90, 95, 100 }; 521 { 0, 5, 10, 20, 30, 50, 70, 85, 90, 95, 100 };
522 const static u16 intercepts3_2[] = 522 static const u16 intercepts3_2[] =
523 { 0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100 }; 523 { 0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100 };
524 const u16 *ip; 524 const u16 *ip;
525 int i; 525 int i;
@@ -1412,6 +1412,7 @@ ath5k_eeprom_init(struct ath5k_hw *ah)
1412 1412
1413 return 0; 1413 return 0;
1414} 1414}
1415
1415/* 1416/*
1416 * Read the MAC address from eeprom 1417 * Read the MAC address from eeprom
1417 */ 1418 */
@@ -1448,3 +1449,14 @@ int ath5k_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac)
1448 return 0; 1449 return 0;
1449} 1450}
1450 1451
1452bool ath5k_eeprom_is_hb63(struct ath5k_hw *ah)
1453{
1454 u16 data;
1455
1456 ath5k_hw_eeprom_read(ah, AR5K_EEPROM_IS_HB63, &data);
1457
1458 if ((ah->ah_mac_version == (AR5K_SREV_AR2425 >> 4)) && data)
1459 return true;
1460 else
1461 return false;
1462}
diff --git a/drivers/net/wireless/ath5k/eeprom.h b/drivers/net/wireless/ath5k/eeprom.h
index 09eb7d0176a4..1deebc0257d4 100644
--- a/drivers/net/wireless/ath5k/eeprom.h
+++ b/drivers/net/wireless/ath5k/eeprom.h
@@ -25,6 +25,7 @@
25#define AR5K_EEPROM_MAGIC_5211 0x0000145b /* 5211 */ 25#define AR5K_EEPROM_MAGIC_5211 0x0000145b /* 5211 */
26#define AR5K_EEPROM_MAGIC_5210 0x0000145a /* 5210 */ 26#define AR5K_EEPROM_MAGIC_5210 0x0000145a /* 5210 */
27 27
28#define AR5K_EEPROM_IS_HB63 0x000b /* Talon detect */
28#define AR5K_EEPROM_REG_DOMAIN 0x00bf /* EEPROM regdom */ 29#define AR5K_EEPROM_REG_DOMAIN 0x00bf /* EEPROM regdom */
29#define AR5K_EEPROM_CHECKSUM 0x00c0 /* EEPROM checksum */ 30#define AR5K_EEPROM_CHECKSUM 0x00c0 /* EEPROM checksum */
30#define AR5K_EEPROM_INFO_BASE 0x00c0 /* EEPROM header */ 31#define AR5K_EEPROM_INFO_BASE 0x00c0 /* EEPROM header */
diff --git a/drivers/net/wireless/ath5k/initvals.c b/drivers/net/wireless/ath5k/initvals.c
index 450bd6e945ff..44886434187b 100644
--- a/drivers/net/wireless/ath5k/initvals.c
+++ b/drivers/net/wireless/ath5k/initvals.c
@@ -2,7 +2,7 @@
2 * Initial register settings functions 2 * Initial register settings functions
3 * 3 *
4 * Copyright (c) 2004-2007 Reyk Floeter <reyk@openbsd.org> 4 * Copyright (c) 2004-2007 Reyk Floeter <reyk@openbsd.org>
5 * Copyright (c) 2006-2007 Nick Kossifidis <mickflemm@gmail.com> 5 * Copyright (c) 2006-2009 Nick Kossifidis <mickflemm@gmail.com>
6 * Copyright (c) 2007-2008 Jiri Slaby <jirislaby@gmail.com> 6 * Copyright (c) 2007-2008 Jiri Slaby <jirislaby@gmail.com>
7 * 7 *
8 * Permission to use, copy, modify, and distribute this software for any 8 * Permission to use, copy, modify, and distribute this software for any
@@ -340,7 +340,7 @@ static const struct ath5k_ini ar5211_ini[] = {
340 * common on all cards/modes. 340 * common on all cards/modes.
341 * Note: Table is rewritten during 341 * Note: Table is rewritten during
342 * txpower setup later using calibration 342 * txpower setup later using calibration
343 * data etc. so next write is non-common 343 * data etc. so next write is non-common */
344 { AR5K_PHY_PCDAC_TXPOWER(1), 0x06ff05ff }, 344 { AR5K_PHY_PCDAC_TXPOWER(1), 0x06ff05ff },
345 { AR5K_PHY_PCDAC_TXPOWER(2), 0x07ff07ff }, 345 { AR5K_PHY_PCDAC_TXPOWER(2), 0x07ff07ff },
346 { AR5K_PHY_PCDAC_TXPOWER(3), 0x08ff08ff }, 346 { AR5K_PHY_PCDAC_TXPOWER(3), 0x08ff08ff },
@@ -371,7 +371,7 @@ static const struct ath5k_ini ar5211_ini[] = {
371 { AR5K_PHY_PCDAC_TXPOWER(28), 0x3aff3aff }, 371 { AR5K_PHY_PCDAC_TXPOWER(28), 0x3aff3aff },
372 { AR5K_PHY_PCDAC_TXPOWER(29), 0x3aff3aff }, 372 { AR5K_PHY_PCDAC_TXPOWER(29), 0x3aff3aff },
373 { AR5K_PHY_PCDAC_TXPOWER(30), 0x3aff3aff }, 373 { AR5K_PHY_PCDAC_TXPOWER(30), 0x3aff3aff },
374 { AR5K_PHY_PCDAC_TXPOWER(31), 0x3aff3aff },*/ 374 { AR5K_PHY_PCDAC_TXPOWER(31), 0x3aff3aff },
375 { AR5K_PHY_CCKTXCTL, 0x00000000 }, 375 { AR5K_PHY_CCKTXCTL, 0x00000000 },
376 { AR5K_PHY(642), 0x503e4646 }, 376 { AR5K_PHY(642), 0x503e4646 },
377 { AR5K_PHY_GAIN_2GHZ, 0x6480416c }, 377 { AR5K_PHY_GAIN_2GHZ, 0x6480416c },
@@ -386,85 +386,85 @@ static const struct ath5k_ini ar5211_ini[] = {
386}; 386};
387 387
388/* Initial mode-specific settings for AR5211 388/* Initial mode-specific settings for AR5211
389 * XXX: how about g / gTurbo ? RF5111 supports it, how about AR5211 ? 389 * 5211 supports OFDM-only g (draft g) but we
390 * Maybe 5211 supports OFDM-only g but we need to test it ! 390 * need to test it !
391 */ 391 */
392static const struct ath5k_ini_mode ar5211_ini_mode[] = { 392static const struct ath5k_ini_mode ar5211_ini_mode[] = {
393 { AR5K_TXCFG, 393 { AR5K_TXCFG,
394 /* a aTurbo b */ 394 /* a aTurbo b g (OFDM) */
395 { 0x00000015, 0x00000015, 0x0000001d } }, 395 { 0x00000015, 0x00000015, 0x0000001d, 0x00000015 } },
396 { AR5K_QUEUE_DFS_LOCAL_IFS(0), 396 { AR5K_QUEUE_DFS_LOCAL_IFS(0),
397 { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f } }, 397 { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
398 { AR5K_QUEUE_DFS_LOCAL_IFS(1), 398 { AR5K_QUEUE_DFS_LOCAL_IFS(1),
399 { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f } }, 399 { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
400 { AR5K_QUEUE_DFS_LOCAL_IFS(2), 400 { AR5K_QUEUE_DFS_LOCAL_IFS(2),
401 { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f } }, 401 { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
402 { AR5K_QUEUE_DFS_LOCAL_IFS(3), 402 { AR5K_QUEUE_DFS_LOCAL_IFS(3),
403 { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f } }, 403 { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
404 { AR5K_QUEUE_DFS_LOCAL_IFS(4), 404 { AR5K_QUEUE_DFS_LOCAL_IFS(4),
405 { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f } }, 405 { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
406 { AR5K_QUEUE_DFS_LOCAL_IFS(5), 406 { AR5K_QUEUE_DFS_LOCAL_IFS(5),
407 { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f } }, 407 { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
408 { AR5K_QUEUE_DFS_LOCAL_IFS(6), 408 { AR5K_QUEUE_DFS_LOCAL_IFS(6),
409 { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f } }, 409 { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
410 { AR5K_QUEUE_DFS_LOCAL_IFS(7), 410 { AR5K_QUEUE_DFS_LOCAL_IFS(7),
411 { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f } }, 411 { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
412 { AR5K_QUEUE_DFS_LOCAL_IFS(8), 412 { AR5K_QUEUE_DFS_LOCAL_IFS(8),
413 { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f } }, 413 { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
414 { AR5K_QUEUE_DFS_LOCAL_IFS(9), 414 { AR5K_QUEUE_DFS_LOCAL_IFS(9),
415 { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f } }, 415 { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
416 { AR5K_DCU_GBL_IFS_SLOT, 416 { AR5K_DCU_GBL_IFS_SLOT,
417 { 0x00000168, 0x000001e0, 0x000001b8 } }, 417 { 0x00000168, 0x000001e0, 0x000001b8, 0x00000168 } },
418 { AR5K_DCU_GBL_IFS_SIFS, 418 { AR5K_DCU_GBL_IFS_SIFS,
419 { 0x00000230, 0x000001e0, 0x000000b0 } }, 419 { 0x00000230, 0x000001e0, 0x000000b0, 0x00000230 } },
420 { AR5K_DCU_GBL_IFS_EIFS, 420 { AR5K_DCU_GBL_IFS_EIFS,
421 { 0x00000d98, 0x00001180, 0x00001f48 } }, 421 { 0x00000d98, 0x00001180, 0x00001f48, 0x00000d98 } },
422 { AR5K_DCU_GBL_IFS_MISC, 422 { AR5K_DCU_GBL_IFS_MISC,
423 { 0x0000a0e0, 0x00014068, 0x00005880 } }, 423 { 0x0000a0e0, 0x00014068, 0x00005880, 0x0000a0e0 } },
424 { AR5K_TIME_OUT, 424 { AR5K_TIME_OUT,
425 { 0x04000400, 0x08000800, 0x20003000 } }, 425 { 0x04000400, 0x08000800, 0x20003000, 0x04000400 } },
426 { AR5K_USEC_5211, 426 { AR5K_USEC_5211,
427 { 0x0e8d8fa7, 0x0e8d8fcf, 0x01608f95 } }, 427 { 0x0e8d8fa7, 0x0e8d8fcf, 0x01608f95, 0x0e8d8fa7 } },
428 { AR5K_PHY_TURBO, 428 { AR5K_PHY_TURBO,
429 { 0x00000000, 0x00000003, 0x00000000 } }, 429 { 0x00000000, 0x00000003, 0x00000000, 0x00000000 } },
430 { AR5K_PHY(8), 430 { AR5K_PHY(8),
431 { 0x02020200, 0x02020200, 0x02010200 } }, 431 { 0x02020200, 0x02020200, 0x02010200, 0x02020200 } },
432 { AR5K_PHY(9), 432 { AR5K_PHY(9),
433 { 0x00000e0e, 0x00000e0e, 0x00000707 } }, 433 { 0x00000e0e, 0x00000e0e, 0x00000707, 0x00000e0e } },
434 { AR5K_PHY(10), 434 { AR5K_PHY(10),
435 { 0x0a020001, 0x0a020001, 0x05010000 } }, 435 { 0x0a020001, 0x0a020001, 0x05010000, 0x0a020001 } },
436 { AR5K_PHY(13), 436 { AR5K_PHY(13),
437 { 0x00000e0e, 0x00000e0e, 0x00000e0e } }, 437 { 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e } },
438 { AR5K_PHY(14), 438 { AR5K_PHY(14),
439 { 0x00000007, 0x00000007, 0x0000000b } }, 439 { 0x00000007, 0x00000007, 0x0000000b, 0x0000000b } },
440 { AR5K_PHY(17), 440 { AR5K_PHY(17),
441 { 0x1372169c, 0x137216a5, 0x137216a8 } }, 441 { 0x1372169c, 0x137216a5, 0x137216a8, 0x1372169c } },
442 { AR5K_PHY(18), 442 { AR5K_PHY(18),
443 { 0x0018ba67, 0x0018ba67, 0x0018ba69 } }, 443 { 0x0018ba67, 0x0018ba67, 0x0018ba69, 0x0018ba69 } },
444 { AR5K_PHY(20), 444 { AR5K_PHY(20),
445 { 0x0c28b4e0, 0x0c28b4e0, 0x0c28b4e0 } }, 445 { 0x0c28b4e0, 0x0c28b4e0, 0x0c28b4e0, 0x0c28b4e0 } },
446 { AR5K_PHY_SIG, 446 { AR5K_PHY_SIG,
447 { 0x7e800d2e, 0x7e800d2e, 0x7ec00d2e } }, 447 { 0x7e800d2e, 0x7e800d2e, 0x7ec00d2e, 0x7e800d2e } },
448 { AR5K_PHY_AGCCOARSE, 448 { AR5K_PHY_AGCCOARSE,
449 { 0x31375d5e, 0x31375d5e, 0x313a5d5e } }, 449 { 0x31375d5e, 0x31375d5e, 0x313a5d5e, 0x31375d5e } },
450 { AR5K_PHY_AGCCTL, 450 { AR5K_PHY_AGCCTL,
451 { 0x0000bd10, 0x0000bd10, 0x0000bd38 } }, 451 { 0x0000bd10, 0x0000bd10, 0x0000bd38, 0x0000bd10 } },
452 { AR5K_PHY_NF, 452 { AR5K_PHY_NF,
453 { 0x0001ce00, 0x0001ce00, 0x0001ce00 } }, 453 { 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00 } },
454 { AR5K_PHY_RX_DELAY, 454 { AR5K_PHY_RX_DELAY,
455 { 0x00002710, 0x00002710, 0x0000157c } }, 455 { 0x00002710, 0x00002710, 0x0000157c, 0x00002710 } },
456 { AR5K_PHY(70), 456 { AR5K_PHY(70),
457 { 0x00000190, 0x00000190, 0x00000084 } }, 457 { 0x00000190, 0x00000190, 0x00000084, 0x00000190 } },
458 { AR5K_PHY_FRAME_CTL_5211, 458 { AR5K_PHY_FRAME_CTL_5211,
459 { 0x6fe01020, 0x6fe01020, 0x6fe00920 } }, 459 { 0x6fe01020, 0x6fe01020, 0x6fe00920, 0x6fe01020 } },
460 { AR5K_PHY_PCDAC_TXPOWER_BASE_5211, 460 { AR5K_PHY_PCDAC_TXPOWER_BASE,
461 { 0x05ff14ff, 0x05ff14ff, 0x05ff14ff } }, 461 { 0x05ff14ff, 0x05ff14ff, 0x05ff14ff, 0x05ff19ff } },
462 { AR5K_RF_BUFFER_CONTROL_4, 462 { AR5K_RF_BUFFER_CONTROL_4,
463 { 0x00000010, 0x00000014, 0x00000010 } }, 463 { 0x00000010, 0x00000014, 0x00000010, 0x00000010 } },
464}; 464};
465 465
466/* Initial register settings for AR5212 */ 466/* Initial register settings for AR5212 */
467static const struct ath5k_ini ar5212_ini[] = { 467static const struct ath5k_ini ar5212_ini_common_start[] = {
468 { AR5K_RXDP, 0x00000000 }, 468 { AR5K_RXDP, 0x00000000 },
469 { AR5K_RXCFG, 0x00000005 }, 469 { AR5K_RXCFG, 0x00000005 },
470 { AR5K_MIBC, 0x00000000 }, 470 { AR5K_MIBC, 0x00000000 },
@@ -485,91 +485,83 @@ static const struct ath5k_ini ar5212_ini[] = {
485 { AR5K_QUEUE_TXDP(9), 0x00000000 }, 485 { AR5K_QUEUE_TXDP(9), 0x00000000 },
486 { AR5K_DCU_FP, 0x00000000 }, 486 { AR5K_DCU_FP, 0x00000000 },
487 { AR5K_DCU_TXP, 0x00000000 }, 487 { AR5K_DCU_TXP, 0x00000000 },
488 { AR5K_DCU_TX_FILTER_0_BASE, 0x00000000 }, 488 /* Tx filter table 0 (32 entries) */
489 /* Unknown table */ 489 { AR5K_DCU_TX_FILTER_0(0), 0x00000000 }, /* DCU 0 */
490 { 0x1078, 0x00000000 }, 490 { AR5K_DCU_TX_FILTER_0(1), 0x00000000 },
491 { 0x10b8, 0x00000000 }, 491 { AR5K_DCU_TX_FILTER_0(2), 0x00000000 },
492 { 0x10f8, 0x00000000 }, 492 { AR5K_DCU_TX_FILTER_0(3), 0x00000000 },
493 { 0x1138, 0x00000000 }, 493 { AR5K_DCU_TX_FILTER_0(4), 0x00000000 }, /* DCU 1 */
494 { 0x1178, 0x00000000 }, 494 { AR5K_DCU_TX_FILTER_0(5), 0x00000000 },
495 { 0x11b8, 0x00000000 }, 495 { AR5K_DCU_TX_FILTER_0(6), 0x00000000 },
496 { 0x11f8, 0x00000000 }, 496 { AR5K_DCU_TX_FILTER_0(7), 0x00000000 },
497 { 0x1238, 0x00000000 }, 497 { AR5K_DCU_TX_FILTER_0(8), 0x00000000 }, /* DCU 2 */
498 { 0x1278, 0x00000000 }, 498 { AR5K_DCU_TX_FILTER_0(9), 0x00000000 },
499 { 0x12b8, 0x00000000 }, 499 { AR5K_DCU_TX_FILTER_0(10), 0x00000000 },
500 { 0x12f8, 0x00000000 }, 500 { AR5K_DCU_TX_FILTER_0(11), 0x00000000 },
501 { 0x1338, 0x00000000 }, 501 { AR5K_DCU_TX_FILTER_0(12), 0x00000000 }, /* DCU 3 */
502 { 0x1378, 0x00000000 }, 502 { AR5K_DCU_TX_FILTER_0(13), 0x00000000 },
503 { 0x13b8, 0x00000000 }, 503 { AR5K_DCU_TX_FILTER_0(14), 0x00000000 },
504 { 0x13f8, 0x00000000 }, 504 { AR5K_DCU_TX_FILTER_0(15), 0x00000000 },
505 { 0x1438, 0x00000000 }, 505 { AR5K_DCU_TX_FILTER_0(16), 0x00000000 }, /* DCU 4 */
506 { 0x1478, 0x00000000 }, 506 { AR5K_DCU_TX_FILTER_0(17), 0x00000000 },
507 { 0x14b8, 0x00000000 }, 507 { AR5K_DCU_TX_FILTER_0(18), 0x00000000 },
508 { 0x14f8, 0x00000000 }, 508 { AR5K_DCU_TX_FILTER_0(19), 0x00000000 },
509 { 0x1538, 0x00000000 }, 509 { AR5K_DCU_TX_FILTER_0(20), 0x00000000 }, /* DCU 5 */
510 { 0x1578, 0x00000000 }, 510 { AR5K_DCU_TX_FILTER_0(21), 0x00000000 },
511 { 0x15b8, 0x00000000 }, 511 { AR5K_DCU_TX_FILTER_0(22), 0x00000000 },
512 { 0x15f8, 0x00000000 }, 512 { AR5K_DCU_TX_FILTER_0(23), 0x00000000 },
513 { 0x1638, 0x00000000 }, 513 { AR5K_DCU_TX_FILTER_0(24), 0x00000000 }, /* DCU 6 */
514 { 0x1678, 0x00000000 }, 514 { AR5K_DCU_TX_FILTER_0(25), 0x00000000 },
515 { 0x16b8, 0x00000000 }, 515 { AR5K_DCU_TX_FILTER_0(26), 0x00000000 },
516 { 0x16f8, 0x00000000 }, 516 { AR5K_DCU_TX_FILTER_0(27), 0x00000000 },
517 { 0x1738, 0x00000000 }, 517 { AR5K_DCU_TX_FILTER_0(28), 0x00000000 }, /* DCU 7 */
518 { 0x1778, 0x00000000 }, 518 { AR5K_DCU_TX_FILTER_0(29), 0x00000000 },
519 { 0x17b8, 0x00000000 }, 519 { AR5K_DCU_TX_FILTER_0(30), 0x00000000 },
520 { 0x17f8, 0x00000000 }, 520 { AR5K_DCU_TX_FILTER_0(31), 0x00000000 },
521 { 0x103c, 0x00000000 }, 521 /* Tx filter table 1 (16 entries) */
522 { 0x107c, 0x00000000 }, 522 { AR5K_DCU_TX_FILTER_1(0), 0x00000000 },
523 { 0x10bc, 0x00000000 }, 523 { AR5K_DCU_TX_FILTER_1(1), 0x00000000 },
524 { 0x10fc, 0x00000000 }, 524 { AR5K_DCU_TX_FILTER_1(2), 0x00000000 },
525 { 0x113c, 0x00000000 }, 525 { AR5K_DCU_TX_FILTER_1(3), 0x00000000 },
526 { 0x117c, 0x00000000 }, 526 { AR5K_DCU_TX_FILTER_1(4), 0x00000000 },
527 { 0x11bc, 0x00000000 }, 527 { AR5K_DCU_TX_FILTER_1(5), 0x00000000 },
528 { 0x11fc, 0x00000000 }, 528 { AR5K_DCU_TX_FILTER_1(6), 0x00000000 },
529 { 0x123c, 0x00000000 }, 529 { AR5K_DCU_TX_FILTER_1(7), 0x00000000 },
530 { 0x127c, 0x00000000 }, 530 { AR5K_DCU_TX_FILTER_1(8), 0x00000000 },
531 { 0x12bc, 0x00000000 }, 531 { AR5K_DCU_TX_FILTER_1(9), 0x00000000 },
532 { 0x12fc, 0x00000000 }, 532 { AR5K_DCU_TX_FILTER_1(10), 0x00000000 },
533 { 0x133c, 0x00000000 }, 533 { AR5K_DCU_TX_FILTER_1(11), 0x00000000 },
534 { 0x137c, 0x00000000 }, 534 { AR5K_DCU_TX_FILTER_1(12), 0x00000000 },
535 { 0x13bc, 0x00000000 }, 535 { AR5K_DCU_TX_FILTER_1(13), 0x00000000 },
536 { 0x13fc, 0x00000000 }, 536 { AR5K_DCU_TX_FILTER_1(14), 0x00000000 },
537 { 0x143c, 0x00000000 }, 537 { AR5K_DCU_TX_FILTER_1(15), 0x00000000 },
538 { 0x147c, 0x00000000 }, 538 { AR5K_DCU_TX_FILTER_CLR, 0x00000000 },
539 { AR5K_DCU_TX_FILTER_SET, 0x00000000 },
539 { AR5K_DCU_TX_FILTER_CLR, 0x00000000 }, 540 { AR5K_DCU_TX_FILTER_CLR, 0x00000000 },
540 { AR5K_DCU_TX_FILTER_SET, 0x00000000 }, 541 { AR5K_DCU_TX_FILTER_SET, 0x00000000 },
541 { AR5K_STA_ID1, 0x00000000 }, 542 { AR5K_STA_ID1, 0x00000000 },
542 { AR5K_BSS_ID0, 0x00000000 }, 543 { AR5K_BSS_ID0, 0x00000000 },
543 { AR5K_BSS_ID1, 0x00000000 }, 544 { AR5K_BSS_ID1, 0x00000000 },
544 /*{ AR5K_RSSI_THR, 0x00000000 },*/ /* Found on SuperAG cards */ 545 { AR5K_BEACON_5211, 0x00000000 },
545 { AR5K_BEACON_5211, 0x00000000 }, /* Found on SuperAG cards */ 546 { AR5K_CFP_PERIOD_5211, 0x00000000 },
546 { AR5K_CFP_PERIOD_5211, 0x00000000 }, /* Found on SuperAG cards */ 547 { AR5K_TIMER0_5211, 0x00000030 },
547 { AR5K_TIMER0_5211, 0x00000030 }, /* Found on SuperAG cards */ 548 { AR5K_TIMER1_5211, 0x0007ffff },
548 { AR5K_TIMER1_5211, 0x0007ffff }, /* Found on SuperAG cards */ 549 { AR5K_TIMER2_5211, 0x01ffffff },
549 { AR5K_TIMER2_5211, 0x01ffffff }, /* Found on SuperAG cards */ 550 { AR5K_TIMER3_5211, 0x00000031 },
550 { AR5K_TIMER3_5211, 0x00000031 }, /* Found on SuperAG cards */ 551 { AR5K_CFP_DUR_5211, 0x00000000 },
551 { AR5K_CFP_DUR_5211, 0x00000000 }, /* Found on SuperAG cards */
552 { AR5K_RX_FILTER_5211, 0x00000000 }, 552 { AR5K_RX_FILTER_5211, 0x00000000 },
553 { AR5K_DIAG_SW_5211, 0x00000000 }, 553 { AR5K_DIAG_SW_5211, 0x00000000 },
554 { AR5K_ADDAC_TEST, 0x00000000 }, 554 { AR5K_ADDAC_TEST, 0x00000000 },
555 { AR5K_DEFAULT_ANTENNA, 0x00000000 }, 555 { AR5K_DEFAULT_ANTENNA, 0x00000000 },
556 { 0x8080, 0x00000000 }, 556 { AR5K_FRAME_CTL_QOSM, 0x000fc78f },
557 /*{ 0x805c, 0xffffc7ff },*/ /* Old value */
558 { 0x805c, 0x000fc78f },
559 { AR5K_NAV_5211, 0x00000000 }, /* Not found on recent */
560 { AR5K_RTS_OK_5211, 0x00000000 }, /* dumps but it makes */
561 { AR5K_RTS_FAIL_5211, 0x00000000 }, /* sense to reset counters */
562 { AR5K_ACK_FAIL_5211, 0x00000000 }, /* since pcu registers */
563 { AR5K_FCS_FAIL_5211, 0x00000000 }, /* are skiped during chan*/
564 { AR5K_BEACON_CNT_5211, 0x00000000 }, /* change */
565 { AR5K_XRMODE, 0x2a82301a }, 557 { AR5K_XRMODE, 0x2a82301a },
566 { AR5K_XRDELAY, 0x05dc01e0 }, 558 { AR5K_XRDELAY, 0x05dc01e0 },
567 { AR5K_XRTIMEOUT, 0x1f402710 }, 559 { AR5K_XRTIMEOUT, 0x1f402710 },
568 { AR5K_XRCHIRP, 0x01f40000 }, 560 { AR5K_XRCHIRP, 0x01f40000 },
569 { AR5K_XRSTOMP, 0x00001e1c }, 561 { AR5K_XRSTOMP, 0x00001e1c },
570 { AR5K_SLEEP0, 0x0002aaaa }, /* Found on SuperAG cards */ 562 { AR5K_SLEEP0, 0x0002aaaa },
571 { AR5K_SLEEP1, 0x02005555 }, /* Found on SuperAG cards */ 563 { AR5K_SLEEP1, 0x02005555 },
572 { AR5K_SLEEP2, 0x00000000 }, /* Found on SuperAG cards */ 564 { AR5K_SLEEP2, 0x00000000 },
573 { AR5K_BSS_IDM0, 0xffffffff }, 565 { AR5K_BSS_IDM0, 0xffffffff },
574 { AR5K_BSS_IDM1, 0x0000ffff }, 566 { AR5K_BSS_IDM1, 0x0000ffff },
575 { AR5K_TXPC, 0x00000000 }, 567 { AR5K_TXPC, 0x00000000 },
@@ -577,7 +569,8 @@ static const struct ath5k_ini ar5212_ini[] = {
577 { AR5K_PROFCNT_RX, 0x00000000 }, 569 { AR5K_PROFCNT_RX, 0x00000000 },
578 { AR5K_PROFCNT_RXCLR, 0x00000000 }, 570 { AR5K_PROFCNT_RXCLR, 0x00000000 },
579 { AR5K_PROFCNT_CYCLE, 0x00000000 }, 571 { AR5K_PROFCNT_CYCLE, 0x00000000 },
580 { 0x80fc, 0x00000088 }, 572 { AR5K_QUIET_CTL1, 0x00000088 },
573 /* Initial rate duration table (32 entries )*/
581 { AR5K_RATE_DUR(0), 0x00000000 }, 574 { AR5K_RATE_DUR(0), 0x00000000 },
582 { AR5K_RATE_DUR(1), 0x0000008c }, 575 { AR5K_RATE_DUR(1), 0x0000008c },
583 { AR5K_RATE_DUR(2), 0x000000e4 }, 576 { AR5K_RATE_DUR(2), 0x000000e4 },
@@ -610,881 +603,625 @@ static const struct ath5k_ini ar5212_ini[] = {
610 { AR5K_RATE_DUR(29), 0x0000007f }, 603 { AR5K_RATE_DUR(29), 0x0000007f },
611 { AR5K_RATE_DUR(30), 0x000000a2 }, 604 { AR5K_RATE_DUR(30), 0x000000a2 },
612 { AR5K_RATE_DUR(31), 0x00000000 }, 605 { AR5K_RATE_DUR(31), 0x00000000 },
613 { 0x8100, 0x00010002}, 606 { AR5K_QUIET_CTL2, 0x00010002 },
614 { AR5K_TSF_PARM, 0x00000001 }, 607 { AR5K_TSF_PARM, 0x00000001 },
615 { 0x8108, 0x000000c0 }, 608 { AR5K_QOS_NOACK, 0x000000c0 },
616 { AR5K_PHY_ERR_FIL, 0x00000000 }, 609 { AR5K_PHY_ERR_FIL, 0x00000000 },
617 { 0x8110, 0x00000168 }, 610 { AR5K_XRLAT_TX, 0x00000168 },
618 { 0x8114, 0x00000000 }, 611 { AR5K_ACKSIFS, 0x00000000 },
619 /* Some kind of table 612 /* Rate -> db table
620 * also notice ...03<-02<-01<-00) */ 613 * notice ...03<-02<-01<-00 ! */
621 { 0x87c0, 0x03020100 }, 614 { AR5K_RATE2DB(0), 0x03020100 },
622 { 0x87c4, 0x07060504 }, 615 { AR5K_RATE2DB(1), 0x07060504 },
623 { 0x87c8, 0x0b0a0908 }, 616 { AR5K_RATE2DB(2), 0x0b0a0908 },
624 { 0x87cc, 0x0f0e0d0c }, 617 { AR5K_RATE2DB(3), 0x0f0e0d0c },
625 { 0x87d0, 0x13121110 }, 618 { AR5K_RATE2DB(4), 0x13121110 },
626 { 0x87d4, 0x17161514 }, 619 { AR5K_RATE2DB(5), 0x17161514 },
627 { 0x87d8, 0x1b1a1918 }, 620 { AR5K_RATE2DB(6), 0x1b1a1918 },
628 { 0x87dc, 0x1f1e1d1c }, 621 { AR5K_RATE2DB(7), 0x1f1e1d1c },
629 /* loop ? */ 622 /* Db -> Rate table */
630 { 0x87e0, 0x03020100 }, 623 { AR5K_DB2RATE(0), 0x03020100 },
631 { 0x87e4, 0x07060504 }, 624 { AR5K_DB2RATE(1), 0x07060504 },
632 { 0x87e8, 0x0b0a0908 }, 625 { AR5K_DB2RATE(2), 0x0b0a0908 },
633 { 0x87ec, 0x0f0e0d0c }, 626 { AR5K_DB2RATE(3), 0x0f0e0d0c },
634 { 0x87f0, 0x13121110 }, 627 { AR5K_DB2RATE(4), 0x13121110 },
635 { 0x87f4, 0x17161514 }, 628 { AR5K_DB2RATE(5), 0x17161514 },
636 { 0x87f8, 0x1b1a1918 }, 629 { AR5K_DB2RATE(6), 0x1b1a1918 },
637 { 0x87fc, 0x1f1e1d1c }, 630 { AR5K_DB2RATE(7), 0x1f1e1d1c },
638 /* PHY registers */ 631 /* PHY registers (Common settings
639 /*{ AR5K_PHY_AGC, 0x00000000 },*/ 632 * for all chips/modes) */
640 { AR5K_PHY(3), 0xad848e19 }, 633 { AR5K_PHY(3), 0xad848e19 },
641 { AR5K_PHY(4), 0x7d28e000 }, 634 { AR5K_PHY(4), 0x7d28e000 },
642 { AR5K_PHY_TIMING_3, 0x9c0a9f6b }, 635 { AR5K_PHY_TIMING_3, 0x9c0a9f6b },
643 { AR5K_PHY_ACT, 0x00000000 }, 636 { AR5K_PHY_ACT, 0x00000000 },
644 /*{ AR5K_PHY(11), 0x00022ffe },*/ 637 { AR5K_PHY(16), 0x206a017a },
645 /*{ AR5K_PHY(15), 0x00020100 },*/ 638 { AR5K_PHY(21), 0x00000859 },
646 { AR5K_PHY(16), 0x206a017a }, 639 { AR5K_PHY_BIN_MASK_1, 0x00000000 },
647 /*{ AR5K_PHY(19), 0x1284613c },*/ 640 { AR5K_PHY_BIN_MASK_2, 0x00000000 },
648 { AR5K_PHY(21), 0x00000859 }, 641 { AR5K_PHY_BIN_MASK_3, 0x00000000 },
649 { AR5K_PHY(64), 0x00000000 }, 642 { AR5K_PHY_BIN_MASK_CTL, 0x00800000 },
650 { AR5K_PHY(65), 0x00000000 }, 643 { AR5K_PHY_ANT_CTL, 0x00000001 },
651 { AR5K_PHY(66), 0x00000000 },
652 { AR5K_PHY(67), 0x00800000 },
653 { AR5K_PHY(68), 0x00000001 },
654 /*{ AR5K_PHY(71), 0x0000092a },*/ /* Old value */ 644 /*{ AR5K_PHY(71), 0x0000092a },*/ /* Old value */
655 { AR5K_PHY(71), 0x00000c80 }, 645 { AR5K_PHY_MAX_RX_LEN, 0x00000c80 },
656 { AR5K_PHY_IQ, 0x05100000 }, 646 { AR5K_PHY_IQ, 0x05100000 },
657 { AR5K_PHY(74), 0x00000001 }, 647 { AR5K_PHY_WARM_RESET, 0x00000001 },
658 { AR5K_PHY(75), 0x00000004 }, 648 { AR5K_PHY_CTL, 0x00000004 },
659 { AR5K_PHY_TXPOWER_RATE1, 0x1e1f2022 }, 649 { AR5K_PHY_TXPOWER_RATE1, 0x1e1f2022 },
660 { AR5K_PHY_TXPOWER_RATE2, 0x0a0b0c0d }, 650 { AR5K_PHY_TXPOWER_RATE2, 0x0a0b0c0d },
661 { AR5K_PHY_TXPOWER_RATE_MAX, 0x0000003f }, 651 { AR5K_PHY_TXPOWER_RATE_MAX, 0x0000003f },
662 /*{ AR5K_PHY(80), 0x00000004 },*/ 652 { AR5K_PHY(82), 0x9280b212 },
663 { AR5K_PHY(82), 0x9280b212 }, 653 { AR5K_PHY_RADAR, 0x5d50e188 },
664 { AR5K_PHY_RADAR, 0x5d50e188 },
665 /*{ AR5K_PHY(86), 0x000000ff },*/ 654 /*{ AR5K_PHY(86), 0x000000ff },*/
666 { AR5K_PHY(87), 0x004b6a8e }, 655 { AR5K_PHY(87), 0x004b6a8e },
667 { AR5K_PHY(90), 0x000003ce }, 656 { AR5K_PHY_NFTHRES, 0x000003ce },
668 { AR5K_PHY(92), 0x192fb515 }, 657 { AR5K_PHY_RESTART, 0x192fb515 },
669 /*{ AR5K_PHY(93), 0x00000000 },*/ 658 { AR5K_PHY(94), 0x00000001 },
670 { AR5K_PHY(94), 0x00000001 }, 659 { AR5K_PHY_RFBUS_REQ, 0x00000000 },
671 { AR5K_PHY(95), 0x00000000 },
672 /*{ AR5K_PHY(644), 0x0080a333 },*/ /* Old value */ 660 /*{ AR5K_PHY(644), 0x0080a333 },*/ /* Old value */
673 /*{ AR5K_PHY(645), 0x00206c10 },*/ /* Old value */ 661 /*{ AR5K_PHY(645), 0x00206c10 },*/ /* Old value */
674 { AR5K_PHY(644), 0x00806333 }, 662 { AR5K_PHY(644), 0x00806333 },
675 { AR5K_PHY(645), 0x00106c10 }, 663 { AR5K_PHY(645), 0x00106c10 },
676 { AR5K_PHY(646), 0x009c4060 }, 664 { AR5K_PHY(646), 0x009c4060 },
677 { AR5K_PHY(647), 0x1483800a }, 665 /* { AR5K_PHY(647), 0x1483800a }, */
678 /* { AR5K_PHY(648), 0x018830c6 },*/ /* 2413/2425 */ 666 /* { AR5K_PHY(648), 0x01831061 }, */ /* Old value */
679 { AR5K_PHY(648), 0x01831061 }, 667 { AR5K_PHY(648), 0x018830c6 },
680 { AR5K_PHY(649), 0x00000400 }, 668 { AR5K_PHY(649), 0x00000400 },
681 /*{ AR5K_PHY(650), 0x000001b5 },*/ 669 /*{ AR5K_PHY(650), 0x000001b5 },*/
682 { AR5K_PHY(651), 0x00000000 }, 670 { AR5K_PHY(651), 0x00000000 },
683 { AR5K_PHY_TXPOWER_RATE3, 0x20202020 }, 671 { AR5K_PHY_TXPOWER_RATE3, 0x20202020 },
684 { AR5K_PHY_TXPOWER_RATE2, 0x20202020 }, 672 { AR5K_PHY_TXPOWER_RATE2, 0x20202020 },
685 /*{ AR5K_PHY(655), 0x13c889af },*/ 673 /*{ AR5K_PHY(655), 0x13c889af },*/
686 { AR5K_PHY(656), 0x38490a20 }, 674 { AR5K_PHY(656), 0x38490a20 },
687 { AR5K_PHY(657), 0x00007bb6 }, 675 { AR5K_PHY(657), 0x00007bb6 },
688 { AR5K_PHY(658), 0x0fff3ffc }, 676 { AR5K_PHY(658), 0x0fff3ffc },
689 /*{ AR5K_PHY_CCKTXCTL, 0x00000000 },*/
690}; 677};
691 678
692/* Initial mode-specific settings for AR5212 (Written before ar5212_ini) */ 679/* Initial mode-specific settings for AR5212 (Written before ar5212_ini) */
693static const struct ath5k_ini_mode ar5212_ini_mode_start[] = { 680static const struct ath5k_ini_mode ar5212_ini_mode_start[] = {
694 { AR5K_PHY(640),
695 /* a/XR aTurbo b g (DYN) gTurbo */
696 { 0x00000008, 0x00000008, 0x0000000b, 0x0000000e, 0x0000000e } },
697 { AR5K_PHY(0),
698 { 0x00000007, 0x00000007, 0x00000007, 0x00000007, 0x00000007 } },
699 { AR5K_QUEUE_DFS_LOCAL_IFS(0), 681 { AR5K_QUEUE_DFS_LOCAL_IFS(0),
700 { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } }, 682 /* a/XR aTurbo b g (DYN) gTurbo */
683 { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
701 { AR5K_QUEUE_DFS_LOCAL_IFS(1), 684 { AR5K_QUEUE_DFS_LOCAL_IFS(1),
702 { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } }, 685 { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
703 { AR5K_QUEUE_DFS_LOCAL_IFS(2), 686 { AR5K_QUEUE_DFS_LOCAL_IFS(2),
704 { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } }, 687 { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
705 { AR5K_QUEUE_DFS_LOCAL_IFS(3), 688 { AR5K_QUEUE_DFS_LOCAL_IFS(3),
706 { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } }, 689 { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
707 { AR5K_QUEUE_DFS_LOCAL_IFS(4), 690 { AR5K_QUEUE_DFS_LOCAL_IFS(4),
708 { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } }, 691 { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
709 { AR5K_QUEUE_DFS_LOCAL_IFS(5), 692 { AR5K_QUEUE_DFS_LOCAL_IFS(5),
710 { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } }, 693 { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
711 { AR5K_QUEUE_DFS_LOCAL_IFS(6), 694 { AR5K_QUEUE_DFS_LOCAL_IFS(6),
712 { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } }, 695 { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
713 { AR5K_QUEUE_DFS_LOCAL_IFS(7), 696 { AR5K_QUEUE_DFS_LOCAL_IFS(7),
714 { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } }, 697 { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
715 { AR5K_QUEUE_DFS_LOCAL_IFS(8), 698 { AR5K_QUEUE_DFS_LOCAL_IFS(8),
716 { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } }, 699 { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
717 { AR5K_QUEUE_DFS_LOCAL_IFS(9), 700 { AR5K_QUEUE_DFS_LOCAL_IFS(9),
718 { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } }, 701 { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
719 { AR5K_DCU_GBL_IFS_SIFS, 702 { AR5K_DCU_GBL_IFS_SIFS,
720 { 0x00000230, 0x000001e0, 0x000000b0, 0x00000160, 0x000001e0 } }, 703 { 0x00000230, 0x000001e0, 0x000000b0, 0x00000160, 0x000001e0 } },
721 { AR5K_DCU_GBL_IFS_SLOT, 704 { AR5K_DCU_GBL_IFS_SLOT,
722 { 0x00000168, 0x000001e0, 0x000001b8, 0x0000018c, 0x000001e0 } }, 705 { 0x00000168, 0x000001e0, 0x000001b8, 0x0000018c, 0x000001e0 } },
723 { AR5K_DCU_GBL_IFS_EIFS, 706 { AR5K_DCU_GBL_IFS_EIFS,
724 { 0x00000e60, 0x00001180, 0x00001f1c, 0x00003e38, 0x00001180 } }, 707 { 0x00000e60, 0x00001180, 0x00001f1c, 0x00003e38, 0x00001180 } },
725 { AR5K_DCU_GBL_IFS_MISC, 708 { AR5K_DCU_GBL_IFS_MISC,
726 { 0x0000a0e0, 0x00014068, 0x00005880, 0x0000b0e0, 0x00014068 } }, 709 { 0x0000a0e0, 0x00014068, 0x00005880, 0x0000b0e0, 0x00014068 } },
727 { AR5K_TIME_OUT, 710 { AR5K_TIME_OUT,
728 { 0x03e803e8, 0x06e006e0, 0x04200420, 0x08400840, 0x06e006e0 } }, 711 { 0x03e803e8, 0x06e006e0, 0x04200420, 0x08400840, 0x06e006e0 } },
729 { AR5K_PHY_TURBO, 712 { AR5K_PHY_TURBO,
730 { 0x00000000, 0x00000003, 0x00000000, 0x00000000, 0x00000003 } }, 713 { 0x00000000, 0x00000003, 0x00000000, 0x00000000, 0x00000003 } },
731 { AR5K_PHY(8), 714 { AR5K_PHY(8),
732 { 0x02020200, 0x02020200, 0x02010200, 0x02020200, 0x02020200 } }, 715 { 0x02020200, 0x02020200, 0x02010200, 0x02020200, 0x02020200 } },
733 { AR5K_PHY(9), 716 { AR5K_PHY_RF_CTL2,
734 { 0x00000e0e, 0x00000e0e, 0x00000707, 0x00000e0e, 0x00000e0e } }, 717 { 0x00000e0e, 0x00000e0e, 0x00000707, 0x00000e0e, 0x00000e0e } },
735 { AR5K_PHY(17), 718 { AR5K_PHY_SETTLING,
736 { 0x1372161c, 0x13721c25, 0x13721722, 0x137216a2, 0x13721c25 } }, 719 { 0x1372161c, 0x13721c25, 0x13721722, 0x137216a2, 0x13721c25 } },
737 { AR5K_PHY_AGCCTL, 720 { AR5K_PHY_AGCCTL,
738 { 0x00009d10, 0x00009d10, 0x00009d18, 0x00009d18, 0x00009d18 } }, 721 { 0x00009d10, 0x00009d10, 0x00009d18, 0x00009d18, 0x00009d18 } },
739 { AR5K_PHY_NF, 722 { AR5K_PHY_NF,
740 { 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00 } }, 723 { 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00 } },
741 { AR5K_PHY(26), 724 { AR5K_PHY_WEAK_OFDM_HIGH_THR,
742 { 0x409a4190, 0x409a4190, 0x409a4190, 0x409a4190, 0x409a4190 } }, 725 { 0x409a4190, 0x409a4190, 0x409a4190, 0x409a4190, 0x409a4190 } },
743 { AR5K_PHY(70), 726 { AR5K_PHY(70),
744 { 0x000001b8, 0x000001b8, 0x00000084, 0x00000108, 0x000001b8 } }, 727 { 0x000001b8, 0x000001b8, 0x00000084, 0x00000108, 0x000001b8 } },
745 { AR5K_PHY(73), 728 { AR5K_PHY_OFDM_SELFCORR,
746 { 0x10058a05, 0x10058a05, 0x10058a05, 0x10058a05, 0x10058a05 } }, 729 { 0x10058a05, 0x10058a05, 0x10058a05, 0x10058a05, 0x10058a05 } },
747 { 0xa230, 730 { 0xa230,
748 { 0x00000000, 0x00000000, 0x00000000, 0x00000108, 0x00000000 } }, 731 { 0x00000000, 0x00000000, 0x00000000, 0x00000108, 0x00000000 } },
749}; 732};
750 733
751/* Initial mode-specific settings for AR5212 + RF5111 (Written after ar5212_ini) */ 734/* Initial mode-specific settings for AR5212 + RF5111 (Written after ar5212_ini) */
752/* New dump pending */ 735static const struct ath5k_ini_mode rf5111_ini_mode_end[] = {
753static const struct ath5k_ini_mode ar5212_rf5111_ini_mode_end[] = {
754 { AR5K_PHY(640), /* This one differs from ar5212_ini_mode_start ! */
755 /* a/XR aTurbo b g (DYN) gTurbo */
756 { 0x00000000, 0x00000000, 0x00000003, 0x00000006, 0x00000006 } },
757 { AR5K_TXCFG, 736 { AR5K_TXCFG,
758 { 0x00008015, 0x00008015, 0x00008015, 0x00008015, 0x00008015 } }, 737 /* a/XR aTurbo b g (DYN) gTurbo */
738 { 0x00008015, 0x00008015, 0x00008015, 0x00008015, 0x00008015 } },
759 { AR5K_USEC_5211, 739 { AR5K_USEC_5211,
760 { 0x128d8fa7, 0x09880fcf, 0x04e00f95, 0x12e00fab, 0x09880fcf } }, 740 { 0x128d8fa7, 0x09880fcf, 0x04e00f95, 0x12e00fab, 0x09880fcf } },
761 { AR5K_PHY(10), 741 { AR5K_PHY_RF_CTL3,
762 { 0x0a020001, 0x0a020001, 0x05010100, 0x0a020001, 0x0a020001 } }, 742 { 0x0a020001, 0x0a020001, 0x05010100, 0x0a020001, 0x0a020001 } },
763 { AR5K_PHY(13), 743 { AR5K_PHY_RF_CTL4,
764 { 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e } }, 744 { 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e } },
765 { AR5K_PHY(14), 745 { AR5K_PHY_PA_CTL,
766 { 0x00000007, 0x00000007, 0x0000000b, 0x0000000b, 0x0000000b } }, 746 { 0x00000007, 0x00000007, 0x0000000b, 0x0000000b, 0x0000000b } },
767 { AR5K_PHY(18), 747 { AR5K_PHY_GAIN,
768 { 0x0018da5a, 0x0018da5a, 0x0018ca69, 0x0018ca69, 0x0018ca69 } }, 748 { 0x0018da5a, 0x0018da5a, 0x0018ca69, 0x0018ca69, 0x0018ca69 } },
769 { AR5K_PHY(20), 749 { AR5K_PHY_DESIRED_SIZE,
770 { 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0 } }, 750 { 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0 } },
771 { AR5K_PHY_SIG, 751 { AR5K_PHY_SIG,
772 { 0x7e800d2e, 0x7e800d2e, 0x7ee84d2e, 0x7ee84d2e, 0x7e800d2e } }, 752 { 0x7e800d2e, 0x7e800d2e, 0x7ee84d2e, 0x7ee84d2e, 0x7e800d2e } },
773 { AR5K_PHY_AGCCOARSE, 753 { AR5K_PHY_AGCCOARSE,
774 { 0x3137665e, 0x3137665e, 0x3137665e, 0x3137665e, 0x3137615e } }, 754 { 0x3137665e, 0x3137665e, 0x3137665e, 0x3137665e, 0x3137615e } },
775 { AR5K_PHY(27), 755 { AR5K_PHY_WEAK_OFDM_LOW_THR,
776 { 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb080, 0x050cb080 } }, 756 { 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb080, 0x050cb080 } },
777 { AR5K_PHY_RX_DELAY, 757 { AR5K_PHY_RX_DELAY,
778 { 0x00002710, 0x00002710, 0x0000157c, 0x00002af8, 0x00002710 } }, 758 { 0x00002710, 0x00002710, 0x0000157c, 0x00002af8, 0x00002710 } },
779 { AR5K_PHY_FRAME_CTL_5211, 759 { AR5K_PHY_FRAME_CTL_5211,
780 { 0xf7b81020, 0xf7b81020, 0xf7b80d20, 0xf7b81020, 0xf7b81020 } }, 760 { 0xf7b81020, 0xf7b81020, 0xf7b80d20, 0xf7b81020, 0xf7b81020 } },
781 { AR5K_PHY_GAIN_2GHZ, 761 { AR5K_PHY_GAIN_2GHZ,
782 { 0x642c416a, 0x642c416a, 0x6440416a, 0x6440416a, 0x6440416a } }, 762 { 0x642c416a, 0x642c416a, 0x6440416a, 0x6440416a, 0x6440416a } },
783 { 0xa21c, 763 { AR5K_PHY_CCK_RX_CTL_4,
784 { 0x1883800a, 0x1883800a, 0x1873800a, 0x1883800a, 0x1883800a } }, 764 { 0x1883800a, 0x1883800a, 0x1873800a, 0x1883800a, 0x1883800a } },
785 { AR5K_DCU_FP, 765};
786 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, 766
787 { AR5K_PHY_AGC, 767static const struct ath5k_ini rf5111_ini_common_end[] = {
788 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, 768 { AR5K_DCU_FP, 0x00000000 },
789 { AR5K_PHY(11), 769 { AR5K_PHY_AGC, 0x00000000 },
790 { 0x00022ffe, 0x00022ffe, 0x00022ffe, 0x00022ffe, 0x00022ffe } }, 770 { AR5K_PHY_ADC_CTL, 0x00022ffe },
791 { AR5K_PHY(15), 771 { 0x983c, 0x00020100 },
792 { 0x00020100, 0x00020100, 0x00020100, 0x00020100, 0x00020100 } }, 772 { AR5K_PHY_GAIN_OFFSET, 0x1284613c },
793 { AR5K_PHY(19), 773 { AR5K_PHY_PAPD_PROBE, 0x00004883 },
794 { 0x1284613c, 0x1284613c, 0x1284613c, 0x1284613c, 0x1284613c } }, 774 { 0x9940, 0x00000004 },
795 { AR5K_PHY_PAPD_PROBE, 775 { 0x9958, 0x000000ff },
796 { 0x00004883, 0x00004883, 0x00004883, 0x00004883, 0x00004883 } }, 776 { 0x9974, 0x00000000 },
797 { AR5K_PHY(80), 777 { AR5K_PHY_SPENDING, 0x00000018 },
798 { 0x00000004, 0x00000004, 0x00000004, 0x00000004, 0x00000004 } }, 778 { AR5K_PHY_CCKTXCTL, 0x00000000 },
799 { AR5K_PHY(86), 779 { AR5K_PHY_CCK_CROSSCORR, 0xd03e6788 },
800 { 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff } }, 780 { AR5K_PHY_DAG_CCK_CTL, 0x000001b5 },
801 { AR5K_PHY(93), 781 { 0xa23c, 0x13c889af },
802 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
803 { AR5K_PHY_SPENDING,
804 { 0x00000018, 0x00000018, 0x00000018, 0x00000018, 0x00000018 } },
805 { AR5K_PHY_CCKTXCTL,
806 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
807 { AR5K_PHY(642),
808 { 0xd03e6788, 0xd03e6788, 0xd03e6788, 0xd03e6788, 0xd03e6788 } },
809 { 0xa228,
810 { 0x000001b5, 0x000001b5, 0x000001b5, 0x000001b5, 0x000001b5 } },
811 { 0xa23c,
812 { 0x13c889af, 0x13c889af, 0x13c889af, 0x13c889af, 0x13c889af } },
813}; 782};
814 783
815/* Initial mode-specific settings for AR5212 + RF5112 (Written after ar5212_ini) */ 784/* Initial mode-specific settings for AR5212 + RF5112 (Written after ar5212_ini) */
816/* XXX: No dumps for turbog yet, but i found settings from old values so it should be ok */ 785static const struct ath5k_ini_mode rf5112_ini_mode_end[] = {
817static const struct ath5k_ini_mode ar5212_rf5112_ini_mode_end[] = {
818 { AR5K_TXCFG, 786 { AR5K_TXCFG,
819 /* a/XR aTurbo b g (DYN) gTurbo */ 787 /* a/XR aTurbo b g (DYN) gTurbo */
820 { 0x00008015, 0x00008015, 0x00008015, 0x00008015, 0x00008015 } }, 788 { 0x00008015, 0x00008015, 0x00008015, 0x00008015, 0x00008015 } },
821 { AR5K_USEC_5211, 789 { AR5K_USEC_5211,
822 { 0x128d93a7, 0x098813cf, 0x04e01395, 0x12e013ab, 0x098813cf } }, 790 { 0x128d93a7, 0x098813cf, 0x04e01395, 0x12e013ab, 0x098813cf } },
823 { AR5K_PHY(10), 791 { AR5K_PHY_RF_CTL3,
824 { 0x0a020001, 0x0a020001, 0x05020100, 0x0a020001, 0x0a020001 } }, 792 { 0x0a020001, 0x0a020001, 0x05020100, 0x0a020001, 0x0a020001 } },
825 { AR5K_PHY(13), 793 { AR5K_PHY_RF_CTL4,
826 { 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e } }, 794 { 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e } },
827 { AR5K_PHY(14), 795 { AR5K_PHY_PA_CTL,
828 { 0x00000007, 0x00000007, 0x0000000b, 0x0000000b, 0x0000000b } }, 796 { 0x00000007, 0x00000007, 0x0000000b, 0x0000000b, 0x0000000b } },
829 { AR5K_PHY(18), 797 { AR5K_PHY_GAIN,
830 { 0x0018da6d, 0x0018da6d, 0x0018ca75, 0x0018ca75, 0x0018ca75 } }, 798 { 0x0018da6d, 0x0018da6d, 0x0018ca75, 0x0018ca75, 0x0018ca75 } },
831 { AR5K_PHY(20), 799 { AR5K_PHY_DESIRED_SIZE,
832 { 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0 } }, 800 { 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0 } },
833 { AR5K_PHY_SIG, 801 { AR5K_PHY_SIG,
834 { 0x7e800d2e, 0x7e800d2e, 0x7ee80d2e, 0x7ee80d2e, 0x7ee80d2e } }, 802 { 0x7e800d2e, 0x7e800d2e, 0x7ee80d2e, 0x7ee80d2e, 0x7ee80d2e } },
835 { AR5K_PHY_AGCCOARSE, 803 { AR5K_PHY_AGCCOARSE,
836 { 0x3137665e, 0x3137665e, 0x3137665e, 0x3137665e, 0x3137665e } }, 804 { 0x3137665e, 0x3137665e, 0x3137665e, 0x3137665e, 0x3137665e } },
837 { AR5K_PHY(27), 805 { AR5K_PHY_WEAK_OFDM_LOW_THR,
838 { 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081 } }, 806 { 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081 } },
839 { AR5K_PHY_RX_DELAY, 807 { AR5K_PHY_RX_DELAY,
840 { 0x000007d0, 0x000007d0, 0x0000044c, 0x00000898, 0x000007d0 } }, 808 { 0x000007d0, 0x000007d0, 0x0000044c, 0x00000898, 0x000007d0 } },
841 { AR5K_PHY_FRAME_CTL_5211, 809 { AR5K_PHY_FRAME_CTL_5211,
842 { 0xf7b81020, 0xf7b81020, 0xf7b80d10, 0xf7b81010, 0xf7b81010 } }, 810 { 0xf7b81020, 0xf7b81020, 0xf7b80d10, 0xf7b81010, 0xf7b81010 } },
843 { AR5K_PHY_CCKTXCTL, 811 { AR5K_PHY_CCKTXCTL,
844 { 0x00000000, 0x00000000, 0x00000008, 0x00000008, 0x00000008 } }, 812 { 0x00000000, 0x00000000, 0x00000008, 0x00000008, 0x00000008 } },
845 { AR5K_PHY(642), 813 { AR5K_PHY_CCK_CROSSCORR,
846 { 0xd6be6788, 0xd6be6788, 0xd03e6788, 0xd03e6788, 0xd03e6788 } }, 814 { 0xd6be6788, 0xd6be6788, 0xd03e6788, 0xd03e6788, 0xd03e6788 } },
847 { AR5K_PHY_GAIN_2GHZ, 815 { AR5K_PHY_GAIN_2GHZ,
848 { 0x642c0140, 0x642c0140, 0x6442c160, 0x6442c160, 0x6442c160 } }, 816 { 0x642c0140, 0x642c0140, 0x6442c160, 0x6442c160, 0x6442c160 } },
849 { 0xa21c, 817 { AR5K_PHY_CCK_RX_CTL_4,
850 { 0x1883800a, 0x1883800a, 0x1873800a, 0x1883800a, 0x1883800a } }, 818 { 0x1883800a, 0x1883800a, 0x1873800a, 0x1883800a, 0x1883800a } },
851 { AR5K_DCU_FP, 819};
852 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, 820
853 { AR5K_PHY_AGC, 821static const struct ath5k_ini rf5112_ini_common_end[] = {
854 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, 822 { AR5K_DCU_FP, 0x00000000 },
855 { AR5K_PHY(11), 823 { AR5K_PHY_AGC, 0x00000000 },
856 { 0x00022ffe, 0x00022ffe, 0x00022ffe, 0x00022ffe, 0x00022ffe } }, 824 { AR5K_PHY_ADC_CTL, 0x00022ffe },
857 { AR5K_PHY(15), 825 { 0x983c, 0x00020100 },
858 { 0x00020100, 0x00020100, 0x00020100, 0x00020100, 0x00020100 } }, 826 { AR5K_PHY_GAIN_OFFSET, 0x1284613c },
859 { AR5K_PHY(19), 827 { AR5K_PHY_PAPD_PROBE, 0x00004882 },
860 { 0x1284613c, 0x1284613c, 0x1284613c, 0x1284613c, 0x1284613c } }, 828 { 0x9940, 0x00000004 },
861 { AR5K_PHY_PAPD_PROBE, 829 { 0x9958, 0x000000ff },
862 { 0x00004882, 0x00004882, 0x00004882, 0x00004882, 0x00004882 } }, 830 { 0x9974, 0x00000000 },
863 { AR5K_PHY(80), 831 { AR5K_PHY_DAG_CCK_CTL, 0x000001b5 },
864 { 0x00000004, 0x00000004, 0x00000004, 0x00000004, 0x00000004 } }, 832 { 0xa23c, 0x13c889af },
865 { AR5K_PHY(86),
866 { 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff } },
867 { AR5K_PHY(93),
868 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
869 { 0xa228,
870 { 0x000001b5, 0x000001b5, 0x000001b5, 0x000001b5, 0x000001b5 } },
871 { 0xa23c,
872 { 0x13c889af, 0x13c889af, 0x13c889af, 0x13c889af, 0x13c889af } },
873}; 833};
874 834
875/* Initial mode-specific settings for RF5413/5414 (Written after ar5212_ini) */ 835/* Initial mode-specific settings for RF5413/5414 (Written after ar5212_ini) */
876/* XXX: No dumps for turbog yet, so turbog is the same with g here with some
877 * minor tweaking based on dumps from other chips */
878static const struct ath5k_ini_mode rf5413_ini_mode_end[] = { 836static const struct ath5k_ini_mode rf5413_ini_mode_end[] = {
879 { AR5K_TXCFG, 837 { AR5K_TXCFG,
880 /* a/XR aTurbo b g gTurbo */ 838 /* a/XR aTurbo b g (DYN) gTurbo */
881 { 0x00000015, 0x00000015, 0x00000015, 0x00000015, 0x00000015 } }, 839 { 0x00000015, 0x00000015, 0x00000015, 0x00000015, 0x00000015 } },
882 { AR5K_USEC_5211, 840 { AR5K_USEC_5211,
883 { 0x128d93a7, 0x098813cf, 0x04e01395, 0x12e013ab, 0x098813cf } }, 841 { 0x128d93a7, 0x098813cf, 0x04e01395, 0x12e013ab, 0x098813cf } },
884 { AR5K_PHY(10), 842 { AR5K_PHY_RF_CTL3,
885 { 0x0a020001, 0x0a020001, 0x05020100, 0x0a020001, 0x0a020001 } }, 843 { 0x0a020001, 0x0a020001, 0x05020100, 0x0a020001, 0x0a020001 } },
886 { AR5K_PHY(13), 844 { AR5K_PHY_RF_CTL4,
887 { 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e } }, 845 { 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e } },
888 { AR5K_PHY(14), 846 { AR5K_PHY_PA_CTL,
889 { 0x00000007, 0x00000007, 0x0000000b, 0x0000000b, 0x0000000b } }, 847 { 0x00000007, 0x00000007, 0x0000000b, 0x0000000b, 0x0000000b } },
890 { AR5K_PHY(18), 848 { AR5K_PHY_GAIN,
891 { 0x0018fa61, 0x0018fa61, 0x001a1a63, 0x001a1a63, 0x001a1a63 } }, 849 { 0x0018fa61, 0x0018fa61, 0x001a1a63, 0x001a1a63, 0x001a1a63 } },
892 { AR5K_PHY(20), 850 { AR5K_PHY_DESIRED_SIZE,
893 { 0x0c98b4e0, 0x0c98b4e0, 0x0c98b0da, 0x0c98b0da, 0x0c98b0da } }, 851 { 0x0c98b4e0, 0x0c98b4e0, 0x0c98b0da, 0x0c98b0da, 0x0c98b0da } },
894 { AR5K_PHY_SIG, 852 { AR5K_PHY_SIG,
895 { 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e } }, 853 { 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e } },
896 { AR5K_PHY_AGCCOARSE, 854 { AR5K_PHY_AGCCOARSE,
897 { 0x3139605e, 0x3139605e, 0x3139605e, 0x3139605e, 0x3139605e } }, 855 { 0x3139605e, 0x3139605e, 0x3139605e, 0x3139605e, 0x3139605e } },
898 { AR5K_PHY(27), 856 { AR5K_PHY_WEAK_OFDM_LOW_THR,
899 { 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081 } }, 857 { 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081 } },
900 { AR5K_PHY_RX_DELAY, 858 { AR5K_PHY_RX_DELAY,
901 { 0x000007d0, 0x000007d0, 0x0000044c, 0x00000898, 0x000007d0 } }, 859 { 0x000007d0, 0x000007d0, 0x0000044c, 0x00000898, 0x000007d0 } },
902 { AR5K_PHY_FRAME_CTL_5211, 860 { AR5K_PHY_FRAME_CTL_5211,
903 { 0xf7b81000, 0xf7b81000, 0xf7b80d00, 0xf7b81000, 0xf7b81000 } }, 861 { 0xf7b81000, 0xf7b81000, 0xf7b80d00, 0xf7b81000, 0xf7b81000 } },
904 { AR5K_PHY_CCKTXCTL, 862 { AR5K_PHY_CCKTXCTL,
905 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, 863 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
906 { AR5K_PHY(642), 864 { AR5K_PHY_CCK_CROSSCORR,
907 { 0xd6be6788, 0xd6be6788, 0xd03e6788, 0xd03e6788, 0xd03e6788 } }, 865 { 0xd6be6788, 0xd6be6788, 0xd03e6788, 0xd03e6788, 0xd03e6788 } },
908 { AR5K_PHY_GAIN_2GHZ, 866 { AR5K_PHY_GAIN_2GHZ,
909 { 0x002ec1e0, 0x002ec1e0, 0x002ac120, 0x002ac120, 0x002ac120 } }, 867 { 0x002ec1e0, 0x002ec1e0, 0x002ac120, 0x002ac120, 0x002ac120 } },
910 { 0xa21c, 868 { AR5K_PHY_CCK_RX_CTL_4,
911 { 0x1883800a, 0x1883800a, 0x1863800a, 0x1883800a, 0x1883800a } }, 869 { 0x1883800a, 0x1883800a, 0x1863800a, 0x1883800a, 0x1883800a } },
912 { 0xa300, 870 { 0xa300,
913 { 0x18010000, 0x18010000, 0x18010000, 0x18010000, 0x18010000 } }, 871 { 0x18010000, 0x18010000, 0x18010000, 0x18010000, 0x18010000 } },
914 { 0xa304, 872 { 0xa304,
915 { 0x30032602, 0x30032602, 0x30032602, 0x30032602, 0x30032602 } }, 873 { 0x30032602, 0x30032602, 0x30032602, 0x30032602, 0x30032602 } },
916 { 0xa308, 874 { 0xa308,
917 { 0x48073e06, 0x48073e06, 0x48073e06, 0x48073e06, 0x48073e06 } }, 875 { 0x48073e06, 0x48073e06, 0x48073e06, 0x48073e06, 0x48073e06 } },
918 { 0xa30c, 876 { 0xa30c,
919 { 0x560b4c0a, 0x560b4c0a, 0x560b4c0a, 0x560b4c0a, 0x560b4c0a } }, 877 { 0x560b4c0a, 0x560b4c0a, 0x560b4c0a, 0x560b4c0a, 0x560b4c0a } },
920 { 0xa310, 878 { 0xa310,
921 { 0x641a600f, 0x641a600f, 0x641a600f, 0x641a600f, 0x641a600f } }, 879 { 0x641a600f, 0x641a600f, 0x641a600f, 0x641a600f, 0x641a600f } },
922 { 0xa314, 880 { 0xa314,
923 { 0x784f6e1b, 0x784f6e1b, 0x784f6e1b, 0x784f6e1b, 0x784f6e1b } }, 881 { 0x784f6e1b, 0x784f6e1b, 0x784f6e1b, 0x784f6e1b, 0x784f6e1b } },
924 { 0xa318, 882 { 0xa318,
925 { 0x868f7c5a, 0x868f7c5a, 0x868f7c5a, 0x868f7c5a, 0x868f7c5a } }, 883 { 0x868f7c5a, 0x868f7c5a, 0x868f7c5a, 0x868f7c5a, 0x868f7c5a } },
926 { 0xa31c, 884 { 0xa31c,
927 { 0x90cf865b, 0x90cf865b, 0x8ecf865b, 0x8ecf865b, 0x8ecf865b } }, 885 { 0x90cf865b, 0x90cf865b, 0x8ecf865b, 0x8ecf865b, 0x8ecf865b } },
928 { 0xa320, 886 { 0xa320,
929 { 0x9d4f970f, 0x9d4f970f, 0x9b4f970f, 0x9b4f970f, 0x9b4f970f } }, 887 { 0x9d4f970f, 0x9d4f970f, 0x9b4f970f, 0x9b4f970f, 0x9b4f970f } },
930 { 0xa324, 888 { 0xa324,
931 { 0xa7cfa38f, 0xa7cfa38f, 0xa3cf9f8f, 0xa3cf9f8f, 0xa3cf9f8f } }, 889 { 0xa7cfa38f, 0xa7cfa38f, 0xa3cf9f8f, 0xa3cf9f8f, 0xa3cf9f8f } },
932 { 0xa328, 890 { 0xa328,
933 { 0xb55faf1f, 0xb55faf1f, 0xb35faf1f, 0xb35faf1f, 0xb35faf1f } }, 891 { 0xb55faf1f, 0xb55faf1f, 0xb35faf1f, 0xb35faf1f, 0xb35faf1f } },
934 { 0xa32c, 892 { 0xa32c,
935 { 0xbddfb99f, 0xbddfb99f, 0xbbdfb99f, 0xbbdfb99f, 0xbbdfb99f } }, 893 { 0xbddfb99f, 0xbddfb99f, 0xbbdfb99f, 0xbbdfb99f, 0xbbdfb99f } },
936 { 0xa330, 894 { 0xa330,
937 { 0xcb7fc53f, 0xcb7fc53f, 0xcb7fc73f, 0xcb7fc73f, 0xcb7fc73f } }, 895 { 0xcb7fc53f, 0xcb7fc53f, 0xcb7fc73f, 0xcb7fc73f, 0xcb7fc73f } },
938 { 0xa334, 896 { 0xa334,
939 { 0xd5ffd1bf, 0xd5ffd1bf, 0xd3ffd1bf, 0xd3ffd1bf, 0xd3ffd1bf } }, 897 { 0xd5ffd1bf, 0xd5ffd1bf, 0xd3ffd1bf, 0xd3ffd1bf, 0xd3ffd1bf } },
940 { AR5K_DCU_FP, 898};
941 { 0x000003e0, 0x000003e0, 0x000003e0, 0x000003e0, 0x000003e0 } }, 899
942 { 0x4068, 900static const struct ath5k_ini rf5413_ini_common_end[] = {
943 { 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010 } }, 901 { AR5K_DCU_FP, 0x000003e0 },
944 { 0x8060, 902 { AR5K_5414_CBCFG, 0x00000010 },
945 { 0x0000000f, 0x0000000f, 0x0000000f, 0x0000000f, 0x0000000f } }, 903 { AR5K_SEQ_MASK, 0x0000000f },
946 { 0x809c, 904 { 0x809c, 0x00000000 },
947 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, 905 { 0x80a0, 0x00000000 },
948 { 0x80a0, 906 { AR5K_MIC_QOS_CTL, 0x00000000 },
949 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, 907 { AR5K_MIC_QOS_SEL, 0x00000000 },
950 { 0x8118, 908 { AR5K_MISC_MODE, 0x00000000 },
951 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, 909 { AR5K_OFDM_FIL_CNT, 0x00000000 },
952 { 0x811c, 910 { AR5K_CCK_FIL_CNT, 0x00000000 },
953 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, 911 { AR5K_PHYERR_CNT1, 0x00000000 },
954 { 0x8120, 912 { AR5K_PHYERR_CNT1_MASK, 0x00000000 },
955 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, 913 { AR5K_PHYERR_CNT2, 0x00000000 },
956 { 0x8124, 914 { AR5K_PHYERR_CNT2_MASK, 0x00000000 },
957 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, 915 { AR5K_TSF_THRES, 0x00000000 },
958 { 0x8128, 916 { 0x8140, 0x800003f9 },
959 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, 917 { 0x8144, 0x00000000 },
960 { 0x812c, 918 { AR5K_PHY_AGC, 0x00000000 },
961 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, 919 { AR5K_PHY_ADC_CTL, 0x0000a000 },
962 { 0x8130, 920 { 0x983c, 0x00200400 },
963 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, 921 { AR5K_PHY_GAIN_OFFSET, 0x1284233c },
964 { 0x8134, 922 { AR5K_PHY_SCR, 0x0000001f },
965 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, 923 { AR5K_PHY_SLMT, 0x00000080 },
966 { 0x8138, 924 { AR5K_PHY_SCAL, 0x0000000e },
967 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, 925 { 0x9958, 0x00081fff },
968 { 0x813c, 926 { AR5K_PHY_TIMING_7, 0x00000000 },
969 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, 927 { AR5K_PHY_TIMING_8, 0x02800000 },
970 { 0x8140, 928 { AR5K_PHY_TIMING_11, 0x00000000 },
971 { 0x800003f9, 0x800003f9, 0x800003f9, 0x800003f9, 0x800003f9 } }, 929 { AR5K_PHY_HEAVY_CLIP_ENABLE, 0x00000000 },
972 { 0x8144, 930 { 0x99e4, 0xaaaaaaaa },
973 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, 931 { 0x99e8, 0x3c466478 },
974 { AR5K_PHY_AGC, 932 { 0x99ec, 0x000000aa },
975 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, 933 { AR5K_PHY_SCLOCK, 0x0000000c },
976 { AR5K_PHY(11), 934 { AR5K_PHY_SDELAY, 0x000000ff },
977 { 0x0000a000, 0x0000a000, 0x0000a000, 0x0000a000, 0x0000a000 } }, 935 { AR5K_PHY_SPENDING, 0x00000014 },
978 { AR5K_PHY(15), 936 { AR5K_PHY_DAG_CCK_CTL, 0x000009b5 },
979 { 0x00200400, 0x00200400, 0x00200400, 0x00200400, 0x00200400 } }, 937 { 0xa23c, 0x93c889af },
980 { AR5K_PHY(19), 938 { AR5K_PHY_FAST_ADC, 0x00000001 },
981 { 0x1284233c, 0x1284233c, 0x1284233c, 0x1284233c, 0x1284233c } }, 939 { 0xa250, 0x0000a000 },
982 { AR5K_PHY_SCR, 940 { AR5K_PHY_BLUETOOTH, 0x00000000 },
983 { 0x0000001f, 0x0000001f, 0x0000001f, 0x0000001f, 0x0000001f } }, 941 { AR5K_PHY_TPC_RG1, 0x0cc75380 },
984 { AR5K_PHY_SLMT, 942 { 0xa25c, 0x0f0f0f01 },
985 { 0x00000080, 0x00000080, 0x00000080, 0x00000080, 0x00000080 } }, 943 { 0xa260, 0x5f690f01 },
986 { AR5K_PHY_SCAL, 944 { 0xa264, 0x00418a11 },
987 { 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e } }, 945 { 0xa268, 0x00000000 },
988 { AR5K_PHY(86), 946 { AR5K_PHY_TPC_RG5, 0x0c30c16a },
989 { 0x00081fff, 0x00081fff, 0x00081fff, 0x00081fff, 0x00081fff } }, 947 { 0xa270, 0x00820820 },
990 { AR5K_PHY(96), 948 { 0xa274, 0x081b7caa },
991 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, 949 { 0xa278, 0x1ce739ce },
992 { AR5K_PHY(97), 950 { 0xa27c, 0x051701ce },
993 { 0x02800000, 0x02800000, 0x02800000, 0x02800000, 0x02800000 } }, 951 { 0xa338, 0x00000000 },
994 { AR5K_PHY(104), 952 { 0xa33c, 0x00000000 },
995 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, 953 { 0xa340, 0x00000000 },
996 { AR5K_PHY(120), 954 { 0xa344, 0x00000000 },
997 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, 955 { 0xa348, 0x3fffffff },
998 { AR5K_PHY(121), 956 { 0xa34c, 0x3fffffff },
999 { 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa } }, 957 { 0xa350, 0x3fffffff },
1000 { AR5K_PHY(122), 958 { 0xa354, 0x0003ffff },
1001 { 0x3c466478, 0x3c466478, 0x3c466478, 0x3c466478, 0x3c466478 } }, 959 { 0xa358, 0x79a8aa1f },
1002 { AR5K_PHY(123), 960 { 0xa35c, 0x066c420f },
1003 { 0x000000aa, 0x000000aa, 0x000000aa, 0x000000aa, 0x000000aa } }, 961 { 0xa360, 0x0f282207 },
1004 { AR5K_PHY_SCLOCK, 962 { 0xa364, 0x17601685 },
1005 { 0x0000000c, 0x0000000c, 0x0000000c, 0x0000000c, 0x0000000c } }, 963 { 0xa368, 0x1f801104 },
1006 { AR5K_PHY_SDELAY, 964 { 0xa36c, 0x37a00c03 },
1007 { 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff } }, 965 { 0xa370, 0x3fc40883 },
1008 { AR5K_PHY_SPENDING, 966 { 0xa374, 0x57c00803 },
1009 { 0x00000014, 0x00000014, 0x00000014, 0x00000014, 0x00000014 } }, 967 { 0xa378, 0x5fd80682 },
1010 { 0xa228, 968 { 0xa37c, 0x7fe00482 },
1011 { 0x000009b5, 0x000009b5, 0x000009b5, 0x000009b5, 0x000009b5 } }, 969 { 0xa380, 0x7f3c7bba },
1012 { 0xa23c, 970 { 0xa384, 0xf3307ff0 },
1013 { 0x93c889af, 0x93c889af, 0x93c889af, 0x93c889af, 0x93c889af } },
1014 { 0xa24c,
1015 { 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001 } },
1016 { 0xa250,
1017 { 0x0000a000, 0x0000a000, 0x0000a000, 0x0000a000, 0x0000a000 } },
1018 { 0xa254,
1019 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
1020 { 0xa258,
1021 { 0x0cc75380, 0x0cc75380, 0x0cc75380, 0x0cc75380, 0x0cc75380 } },
1022 { 0xa25c,
1023 { 0x0f0f0f01, 0x0f0f0f01, 0x0f0f0f01, 0x0f0f0f01, 0x0f0f0f01 } },
1024 { 0xa260,
1025 { 0x5f690f01, 0x5f690f01, 0x5f690f01, 0x5f690f01, 0x5f690f01 } },
1026 { 0xa264,
1027 { 0x00418a11, 0x00418a11, 0x00418a11, 0x00418a11, 0x00418a11 } },
1028 { 0xa268,
1029 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
1030 { 0xa26c,
1031 { 0x0c30c16a, 0x0c30c16a, 0x0c30c16a, 0x0c30c16a, 0x0c30c16a } },
1032 { 0xa270,
1033 { 0x00820820, 0x00820820, 0x00820820, 0x00820820, 0x00820820 } },
1034 { 0xa274,
1035 { 0x081b7caa, 0x081b7caa, 0x081b7caa, 0x081b7caa, 0x081b7caa } },
1036 { 0xa278,
1037 { 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce } },
1038 { 0xa27c,
1039 { 0x051701ce, 0x051701ce, 0x051701ce, 0x051701ce, 0x051701ce } },
1040 { 0xa338,
1041 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
1042 { 0xa33c,
1043 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
1044 { 0xa340,
1045 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
1046 { 0xa344,
1047 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
1048 { 0xa348,
1049 { 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff } },
1050 { 0xa34c,
1051 { 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff } },
1052 { 0xa350,
1053 { 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff } },
1054 { 0xa354,
1055 { 0x0003ffff, 0x0003ffff, 0x0003ffff, 0x0003ffff, 0x0003ffff } },
1056 { 0xa358,
1057 { 0x79a8aa1f, 0x79a8aa1f, 0x79a8aa1f, 0x79a8aa1f, 0x79a8aa1f } },
1058 { 0xa35c,
1059 { 0x066c420f, 0x066c420f, 0x066c420f, 0x066c420f, 0x066c420f } },
1060 { 0xa360,
1061 { 0x0f282207, 0x0f282207, 0x0f282207, 0x0f282207, 0x0f282207 } },
1062 { 0xa364,
1063 { 0x17601685, 0x17601685, 0x17601685, 0x17601685, 0x17601685 } },
1064 { 0xa368,
1065 { 0x1f801104, 0x1f801104, 0x1f801104, 0x1f801104, 0x1f801104 } },
1066 { 0xa36c,
1067 { 0x37a00c03, 0x37a00c03, 0x37a00c03, 0x37a00c03, 0x37a00c03 } },
1068 { 0xa370,
1069 { 0x3fc40883, 0x3fc40883, 0x3fc40883, 0x3fc40883, 0x3fc40883 } },
1070 { 0xa374,
1071 { 0x57c00803, 0x57c00803, 0x57c00803, 0x57c00803, 0x57c00803 } },
1072 { 0xa378,
1073 { 0x5fd80682, 0x5fd80682, 0x5fd80682, 0x5fd80682, 0x5fd80682 } },
1074 { 0xa37c,
1075 { 0x7fe00482, 0x7fe00482, 0x7fe00482, 0x7fe00482, 0x7fe00482 } },
1076 { 0xa380,
1077 { 0x7f3c7bba, 0x7f3c7bba, 0x7f3c7bba, 0x7f3c7bba, 0x7f3c7bba } },
1078 { 0xa384,
1079 { 0xf3307ff0, 0xf3307ff0, 0xf3307ff0, 0xf3307ff0, 0xf3307ff0 } },
1080}; 971};
1081 972
1082/* Initial mode-specific settings for RF2413/2414 (Written after ar5212_ini) */ 973/* Initial mode-specific settings for RF2413/2414 (Written after ar5212_ini) */
1083/* XXX: No dumps for turbog yet, so turbog is the same with g here with some 974/* XXX: a mode ? */
1084 * minor tweaking based on dumps from other chips */
1085static const struct ath5k_ini_mode rf2413_ini_mode_end[] = { 975static const struct ath5k_ini_mode rf2413_ini_mode_end[] = {
1086 { AR5K_TXCFG, 976 { AR5K_TXCFG,
1087 /* b g gTurbo */ 977 /* a/XR aTurbo b g (DYN) gTurbo */
1088 { 0x00000015, 0x00000015, 0x00000015 } }, 978 { 0x00000015, 0x00000015, 0x00000015, 0x00000015, 0x00000015 } },
1089 { AR5K_USEC_5211, 979 { AR5K_USEC_5211,
1090 { 0x04e01395, 0x12e013ab, 0x098813cf } }, 980 { 0x128d93a7, 0x098813cf, 0x04e01395, 0x12e013ab, 0x098813cf } },
1091 { AR5K_PHY(10), 981 { AR5K_PHY_RF_CTL3,
1092 { 0x05020000, 0x0a020001, 0x0a020001 } }, 982 { 0x0a020001, 0x0a020001, 0x05020000, 0x0a020001, 0x0a020001 } },
1093 { AR5K_PHY(13), 983 { AR5K_PHY_RF_CTL4,
1094 { 0x00000e00, 0x00000e00, 0x00000e00 } }, 984 { 0x00000e00, 0x00000e00, 0x00000e00, 0x00000e00, 0x00000e00 } },
1095 { AR5K_PHY(14), 985 { AR5K_PHY_PA_CTL,
1096 { 0x0000000a, 0x0000000a, 0x0000000a } }, 986 { 0x00000002, 0x00000002, 0x0000000a, 0x0000000a, 0x0000000a } },
1097 { AR5K_PHY(18), 987 { AR5K_PHY_GAIN,
1098 { 0x001a6a64, 0x001a6a64, 0x001a6a64 } }, 988 { 0x0018da6d, 0x0018da6d, 0x001a6a64, 0x001a6a64, 0x001a6a64 } },
1099 { AR5K_PHY(20), 989 { AR5K_PHY_DESIRED_SIZE,
1100 { 0x0de8b0da, 0x0c98b0da, 0x0c98b0da } }, 990 { 0x0de8b4e0, 0x0de8b4e0, 0x0de8b0da, 0x0c98b0da, 0x0de8b0da } },
1101 { AR5K_PHY_SIG, 991 { AR5K_PHY_SIG,
1102 { 0x7ee80d2e, 0x7ec80d2e, 0x7ec80d2e } }, 992 { 0x7e800d2e, 0x7e800d2e, 0x7ee80d2e, 0x7ec80d2e, 0x7e800d2e } },
1103 { AR5K_PHY_AGCCOARSE, 993 { AR5K_PHY_AGCCOARSE,
1104 { 0x3137665e, 0x3139605e, 0x3139605e } }, 994 { 0x3137665e, 0x3137665e, 0x3137665e, 0x3139605e, 0x3137665e } },
1105 { AR5K_PHY(27), 995 { AR5K_PHY_WEAK_OFDM_LOW_THR,
1106 { 0x050cb081, 0x050cb081, 0x050cb081 } }, 996 { 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081 } },
1107 { AR5K_PHY_RX_DELAY, 997 { AR5K_PHY_RX_DELAY,
1108 { 0x0000044c, 0x00000898, 0x000007d0 } }, 998 { 0x000007d0, 0x000007d0, 0x0000044c, 0x00000898, 0x000007d0 } },
1109 { AR5K_PHY_FRAME_CTL_5211, 999 { AR5K_PHY_FRAME_CTL_5211,
1110 { 0xf7b80d00, 0xf7b81000, 0xf7b81000 } }, 1000 { 0xf7b81000, 0xf7b81000, 0xf7b80d00, 0xf7b81000, 0xf7b81000 } },
1111 { AR5K_PHY_CCKTXCTL, 1001 { AR5K_PHY_CCKTXCTL,
1112 { 0x00000000, 0x00000000, 0x00000000 } }, 1002 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
1113 { AR5K_PHY(642), 1003 { AR5K_PHY_CCK_CROSSCORR,
1114 { 0xd03e6788, 0xd03e6788, 0xd03e6788 } }, 1004 { 0xd6be6788, 0xd6be6788, 0xd03e6788, 0xd03e6788, 0xd03e6788 } },
1115 { AR5K_PHY_GAIN_2GHZ, 1005 { AR5K_PHY_GAIN_2GHZ,
1116 { 0x0042c140, 0x0042c140, 0x0042c140 } }, 1006 { 0x002c0140, 0x002c0140, 0x0042c140, 0x0042c140, 0x0042c140 } },
1117 { 0xa21c, 1007 { AR5K_PHY_CCK_RX_CTL_4,
1118 { 0x1863800a, 0x1883800a, 0x1883800a } }, 1008 { 0x1883800a, 0x1883800a, 0x1863800a, 0x1883800a, 0x1883800a } },
1119 { AR5K_DCU_FP, 1009};
1120 { 0x000003e0, 0x000003e0, 0x000003e0 } }, 1010
1121 { 0x8060, 1011static const struct ath5k_ini rf2413_ini_common_end[] = {
1122 { 0x0000000f, 0x0000000f, 0x0000000f } }, 1012 { AR5K_DCU_FP, 0x000003e0 },
1123 { 0x8118, 1013 { AR5K_SEQ_MASK, 0x0000000f },
1124 { 0x00000000, 0x00000000, 0x00000000 } }, 1014 { AR5K_MIC_QOS_CTL, 0x00000000 },
1125 { 0x811c, 1015 { AR5K_MIC_QOS_SEL, 0x00000000 },
1126 { 0x00000000, 0x00000000, 0x00000000 } }, 1016 { AR5K_MISC_MODE, 0x00000000 },
1127 { 0x8120, 1017 { AR5K_OFDM_FIL_CNT, 0x00000000 },
1128 { 0x00000000, 0x00000000, 0x00000000 } }, 1018 { AR5K_CCK_FIL_CNT, 0x00000000 },
1129 { 0x8124, 1019 { AR5K_PHYERR_CNT1, 0x00000000 },
1130 { 0x00000000, 0x00000000, 0x00000000 } }, 1020 { AR5K_PHYERR_CNT1_MASK, 0x00000000 },
1131 { 0x8128, 1021 { AR5K_PHYERR_CNT2, 0x00000000 },
1132 { 0x00000000, 0x00000000, 0x00000000 } }, 1022 { AR5K_PHYERR_CNT2_MASK, 0x00000000 },
1133 { 0x812c, 1023 { AR5K_TSF_THRES, 0x00000000 },
1134 { 0x00000000, 0x00000000, 0x00000000 } }, 1024 { 0x8140, 0x800000a8 },
1135 { 0x8130, 1025 { 0x8144, 0x00000000 },
1136 { 0x00000000, 0x00000000, 0x00000000 } }, 1026 { AR5K_PHY_AGC, 0x00000000 },
1137 { 0x8134, 1027 { AR5K_PHY_ADC_CTL, 0x0000a000 },
1138 { 0x00000000, 0x00000000, 0x00000000 } }, 1028 { 0x983c, 0x00200400 },
1139 { 0x8138, 1029 { AR5K_PHY_GAIN_OFFSET, 0x1284233c },
1140 { 0x00000000, 0x00000000, 0x00000000 } }, 1030 { AR5K_PHY_SCR, 0x0000001f },
1141 { 0x813c, 1031 { AR5K_PHY_SLMT, 0x00000080 },
1142 { 0x00000000, 0x00000000, 0x00000000 } }, 1032 { AR5K_PHY_SCAL, 0x0000000e },
1143 { 0x8140, 1033 { 0x9958, 0x000000ff },
1144 { 0x800000a8, 0x800000a8, 0x800000a8 } }, 1034 { AR5K_PHY_TIMING_7, 0x00000000 },
1145 { 0x8144, 1035 { AR5K_PHY_TIMING_8, 0x02800000 },
1146 { 0x00000000, 0x00000000, 0x00000000 } }, 1036 { AR5K_PHY_TIMING_11, 0x00000000 },
1147 { AR5K_PHY_AGC, 1037 { AR5K_PHY_HEAVY_CLIP_ENABLE, 0x00000000 },
1148 { 0x00000000, 0x00000000, 0x00000000 } }, 1038 { 0x99e4, 0xaaaaaaaa },
1149 { AR5K_PHY(11), 1039 { 0x99e8, 0x3c466478 },
1150 { 0x0000a000, 0x0000a000, 0x0000a000 } }, 1040 { 0x99ec, 0x000000aa },
1151 { AR5K_PHY(15), 1041 { AR5K_PHY_SCLOCK, 0x0000000c },
1152 { 0x00200400, 0x00200400, 0x00200400 } }, 1042 { AR5K_PHY_SDELAY, 0x000000ff },
1153 { AR5K_PHY(19), 1043 { AR5K_PHY_SPENDING, 0x00000014 },
1154 { 0x1284233c, 0x1284233c, 0x1284233c } }, 1044 { AR5K_PHY_DAG_CCK_CTL, 0x000009b5 },
1155 { AR5K_PHY_SCR, 1045 { 0xa23c, 0x93c889af },
1156 { 0x0000001f, 0x0000001f, 0x0000001f } }, 1046 { AR5K_PHY_FAST_ADC, 0x00000001 },
1157 { AR5K_PHY_SLMT, 1047 { 0xa250, 0x0000a000 },
1158 { 0x00000080, 0x00000080, 0x00000080 } }, 1048 { AR5K_PHY_BLUETOOTH, 0x00000000 },
1159 { AR5K_PHY_SCAL, 1049 { AR5K_PHY_TPC_RG1, 0x0cc75380 },
1160 { 0x0000000e, 0x0000000e, 0x0000000e } }, 1050 { 0xa25c, 0x0f0f0f01 },
1161 { AR5K_PHY(86), 1051 { 0xa260, 0x5f690f01 },
1162 { 0x000000ff, 0x000000ff, 0x000000ff } }, 1052 { 0xa264, 0x00418a11 },
1163 { AR5K_PHY(96), 1053 { 0xa268, 0x00000000 },
1164 { 0x00000000, 0x00000000, 0x00000000 } }, 1054 { AR5K_PHY_TPC_RG5, 0x0c30c16a },
1165 { AR5K_PHY(97), 1055 { 0xa270, 0x00820820 },
1166 { 0x02800000, 0x02800000, 0x02800000 } }, 1056 { 0xa274, 0x001b7caa },
1167 { AR5K_PHY(104), 1057 { 0xa278, 0x1ce739ce },
1168 { 0x00000000, 0x00000000, 0x00000000 } }, 1058 { 0xa27c, 0x051701ce },
1169 { AR5K_PHY(120), 1059 { 0xa300, 0x18010000 },
1170 { 0x00000000, 0x00000000, 0x00000000 } }, 1060 { 0xa304, 0x30032602 },
1171 { AR5K_PHY(121), 1061 { 0xa308, 0x48073e06 },
1172 { 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa } }, 1062 { 0xa30c, 0x560b4c0a },
1173 { AR5K_PHY(122), 1063 { 0xa310, 0x641a600f },
1174 { 0x3c466478, 0x3c466478, 0x3c466478 } }, 1064 { 0xa314, 0x784f6e1b },
1175 { AR5K_PHY(123), 1065 { 0xa318, 0x868f7c5a },
1176 { 0x000000aa, 0x000000aa, 0x000000aa } }, 1066 { 0xa31c, 0x8ecf865b },
1177 { AR5K_PHY_SCLOCK, 1067 { 0xa320, 0x9d4f970f },
1178 { 0x0000000c, 0x0000000c, 0x0000000c } }, 1068 { 0xa324, 0xa5cfa18f },
1179 { AR5K_PHY_SDELAY, 1069 { 0xa328, 0xb55faf1f },
1180 { 0x000000ff, 0x000000ff, 0x000000ff } }, 1070 { 0xa32c, 0xbddfb99f },
1181 { AR5K_PHY_SPENDING, 1071 { 0xa330, 0xcd7fc73f },
1182 { 0x00000014, 0x00000014, 0x00000014 } }, 1072 { 0xa334, 0xd5ffd1bf },
1183 { 0xa228, 1073 { 0xa338, 0x00000000 },
1184 { 0x000009b5, 0x000009b5, 0x000009b5 } }, 1074 { 0xa33c, 0x00000000 },
1185 { 0xa23c, 1075 { 0xa340, 0x00000000 },
1186 { 0x93c889af, 0x93c889af, 0x93c889af } }, 1076 { 0xa344, 0x00000000 },
1187 { 0xa24c, 1077 { 0xa348, 0x3fffffff },
1188 { 0x00000001, 0x00000001, 0x00000001 } }, 1078 { 0xa34c, 0x3fffffff },
1189 { 0xa250, 1079 { 0xa350, 0x3fffffff },
1190 { 0x0000a000, 0x0000a000, 0x0000a000 } }, 1080 { 0xa354, 0x0003ffff },
1191 { 0xa254, 1081 { 0xa358, 0x79a8aa1f },
1192 { 0x00000000, 0x00000000, 0x00000000 } }, 1082 { 0xa35c, 0x066c420f },
1193 { 0xa258, 1083 { 0xa360, 0x0f282207 },
1194 { 0x0cc75380, 0x0cc75380, 0x0cc75380 } }, 1084 { 0xa364, 0x17601685 },
1195 { 0xa25c, 1085 { 0xa368, 0x1f801104 },
1196 { 0x0f0f0f01, 0x0f0f0f01, 0x0f0f0f01 } }, 1086 { 0xa36c, 0x37a00c03 },
1197 { 0xa260, 1087 { 0xa370, 0x3fc40883 },
1198 { 0x5f690f01, 0x5f690f01, 0x5f690f01 } }, 1088 { 0xa374, 0x57c00803 },
1199 { 0xa264, 1089 { 0xa378, 0x5fd80682 },
1200 { 0x00418a11, 0x00418a11, 0x00418a11 } }, 1090 { 0xa37c, 0x7fe00482 },
1201 { 0xa268, 1091 { 0xa380, 0x7f3c7bba },
1202 { 0x00000000, 0x00000000, 0x00000000 } }, 1092 { 0xa384, 0xf3307ff0 },
1203 { 0xa26c,
1204 { 0x0c30c16a, 0x0c30c16a, 0x0c30c16a } },
1205 { 0xa270,
1206 { 0x00820820, 0x00820820, 0x00820820 } },
1207 { 0xa274,
1208 { 0x001b7caa, 0x001b7caa, 0x001b7caa } },
1209 { 0xa278,
1210 { 0x1ce739ce, 0x1ce739ce, 0x1ce739ce } },
1211 { 0xa27c,
1212 { 0x051701ce, 0x051701ce, 0x051701ce } },
1213 { 0xa300,
1214 { 0x18010000, 0x18010000, 0x18010000 } },
1215 { 0xa304,
1216 { 0x30032602, 0x30032602, 0x30032602 } },
1217 { 0xa308,
1218 { 0x48073e06, 0x48073e06, 0x48073e06 } },
1219 { 0xa30c,
1220 { 0x560b4c0a, 0x560b4c0a, 0x560b4c0a } },
1221 { 0xa310,
1222 { 0x641a600f, 0x641a600f, 0x641a600f } },
1223 { 0xa314,
1224 { 0x784f6e1b, 0x784f6e1b, 0x784f6e1b } },
1225 { 0xa318,
1226 { 0x868f7c5a, 0x868f7c5a, 0x868f7c5a } },
1227 { 0xa31c,
1228 { 0x8ecf865b, 0x8ecf865b, 0x8ecf865b } },
1229 { 0xa320,
1230 { 0x9d4f970f, 0x9d4f970f, 0x9d4f970f } },
1231 { 0xa324,
1232 { 0xa5cfa18f, 0xa5cfa18f, 0xa5cfa18f } },
1233 { 0xa328,
1234 { 0xb55faf1f, 0xb55faf1f, 0xb55faf1f } },
1235 { 0xa32c,
1236 { 0xbddfb99f, 0xbddfb99f, 0xbddfb99f } },
1237 { 0xa330,
1238 { 0xcd7fc73f, 0xcd7fc73f, 0xcd7fc73f } },
1239 { 0xa334,
1240 { 0xd5ffd1bf, 0xd5ffd1bf, 0xd5ffd1bf } },
1241 { 0xa338,
1242 { 0x00000000, 0x00000000, 0x00000000 } },
1243 { 0xa33c,
1244 { 0x00000000, 0x00000000, 0x00000000 } },
1245 { 0xa340,
1246 { 0x00000000, 0x00000000, 0x00000000 } },
1247 { 0xa344,
1248 { 0x00000000, 0x00000000, 0x00000000 } },
1249 { 0xa348,
1250 { 0x3fffffff, 0x3fffffff, 0x3fffffff } },
1251 { 0xa34c,
1252 { 0x3fffffff, 0x3fffffff, 0x3fffffff } },
1253 { 0xa350,
1254 { 0x3fffffff, 0x3fffffff, 0x3fffffff } },
1255 { 0xa354,
1256 { 0x0003ffff, 0x0003ffff, 0x0003ffff } },
1257 { 0xa358,
1258 { 0x79a8aa1f, 0x79a8aa1f, 0x79a8aa1f } },
1259 { 0xa35c,
1260 { 0x066c420f, 0x066c420f, 0x066c420f } },
1261 { 0xa360,
1262 { 0x0f282207, 0x0f282207, 0x0f282207 } },
1263 { 0xa364,
1264 { 0x17601685, 0x17601685, 0x17601685 } },
1265 { 0xa368,
1266 { 0x1f801104, 0x1f801104, 0x1f801104 } },
1267 { 0xa36c,
1268 { 0x37a00c03, 0x37a00c03, 0x37a00c03 } },
1269 { 0xa370,
1270 { 0x3fc40883, 0x3fc40883, 0x3fc40883 } },
1271 { 0xa374,
1272 { 0x57c00803, 0x57c00803, 0x57c00803 } },
1273 { 0xa378,
1274 { 0x5fd80682, 0x5fd80682, 0x5fd80682 } },
1275 { 0xa37c,
1276 { 0x7fe00482, 0x7fe00482, 0x7fe00482 } },
1277 { 0xa380,
1278 { 0x7f3c7bba, 0x7f3c7bba, 0x7f3c7bba } },
1279 { 0xa384,
1280 { 0xf3307ff0, 0xf3307ff0, 0xf3307ff0 } },
1281}; 1093};
1282 1094
1283/* Initial mode-specific settings for RF2425 (Written after ar5212_ini) */ 1095/* Initial mode-specific settings for RF2425 (Written after ar5212_ini) */
1284/* XXX: No dumps for turbog yet, so turbog is the same with g here with some 1096/* XXX: a mode ? */
1285 * minor tweaking based on dumps from other chips */
1286static const struct ath5k_ini_mode rf2425_ini_mode_end[] = { 1097static const struct ath5k_ini_mode rf2425_ini_mode_end[] = {
1287 { AR5K_TXCFG, 1098 { AR5K_TXCFG,
1288 /* g gTurbo */ 1099 /* a/XR aTurbo b g (DYN) gTurbo */
1289 { 0x00000015, 0x00000015 } }, 1100 { 0x00000015, 0x00000015, 0x00000015, 0x00000015, 0x00000015 } },
1290 { AR5K_USEC_5211, 1101 { AR5K_USEC_5211,
1291 { 0x12e013ab, 0x098813cf } }, 1102 { 0x128d93a7, 0x098813cf, 0x04e01395, 0x12e013ab, 0x098813cf } },
1292 { AR5K_PHY_TURBO, 1103 { AR5K_PHY_TURBO,
1293 { 0x00000000, 0x00000003 } }, 1104 { 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000001 } },
1294 { AR5K_PHY(10), 1105 { AR5K_PHY_RF_CTL3,
1295 { 0x0a020001, 0x0a020001 } }, 1106 { 0x0a020001, 0x0a020001, 0x05020100, 0x0a020001, 0x0a020001 } },
1296 { AR5K_PHY(13), 1107 { AR5K_PHY_RF_CTL4,
1297 { 0x00000e0e, 0x00000e0e } }, 1108 { 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e } },
1298 { AR5K_PHY(14), 1109 { AR5K_PHY_PA_CTL,
1299 { 0x0000000b, 0x0000000b } }, 1110 { 0x00000003, 0x00000003, 0x0000000b, 0x0000000b, 0x0000000b } },
1300 { AR5K_PHY(17), 1111 { AR5K_PHY_SETTLING,
1301 { 0x13721422, 0x13721422 } }, 1112 { 0x1372161c, 0x13721c25, 0x13721722, 0x13721422, 0x13721c25 } },
1302 { AR5K_PHY(18), 1113 { AR5K_PHY_GAIN,
1303 { 0x00199a65, 0x00199a65 } }, 1114 { 0x0018fa61, 0x0018fa61, 0x00199a65, 0x00199a65, 0x00199a65 } },
1304 { AR5K_PHY(20), 1115 { AR5K_PHY_DESIRED_SIZE,
1305 { 0x0c98b0da, 0x0c98b0da } }, 1116 { 0x0c98b4e0, 0x0c98b4e0, 0x0c98b0da, 0x0c98b0da, 0x0c98b0da } },
1306 { AR5K_PHY_SIG, 1117 { AR5K_PHY_SIG,
1307 { 0x7ec80d2e, 0x7ec80d2e } }, 1118 { 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e } },
1308 { AR5K_PHY_AGCCOARSE, 1119 { AR5K_PHY_AGCCOARSE,
1309 { 0x3139605e, 0x3139605e } }, 1120 { 0x3139605e, 0x3139605e, 0x3139605e, 0x3139605e, 0x3139605e } },
1310 { AR5K_PHY(27), 1121 { AR5K_PHY_WEAK_OFDM_LOW_THR,
1311 { 0x050cb081, 0x050cb081 } }, 1122 { 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081 } },
1312 { AR5K_PHY_RX_DELAY, 1123 { AR5K_PHY_RX_DELAY,
1313 { 0x00000898, 0x000007d0 } }, 1124 { 0x000007d0, 0x000007d0, 0x0000044c, 0x00000898, 0x000007d0 } },
1314 { AR5K_PHY_FRAME_CTL_5211, 1125 { AR5K_PHY_FRAME_CTL_5211,
1315 { 0xf7b81000, 0xf7b81000 } }, 1126 { 0xf7b81000, 0xf7b81000, 0xf7b80d00, 0xf7b81000, 0xf7b81000 } },
1316 { AR5K_PHY_CCKTXCTL, 1127 { AR5K_PHY_CCKTXCTL,
1317 { 0x00000000, 0x00000000 } }, 1128 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
1318 { AR5K_PHY(642), 1129 { AR5K_PHY_CCK_CROSSCORR,
1319 { 0xd03e6788, 0xd03e6788 } }, 1130 { 0xd6be6788, 0xd6be6788, 0xd03e6788, 0xd03e6788, 0xd03e6788 } },
1320 { AR5K_PHY_GAIN_2GHZ, 1131 { AR5K_PHY_GAIN_2GHZ,
1321 { 0x0052c140, 0x0052c140 } }, 1132 { 0x00000140, 0x00000140, 0x0052c140, 0x0052c140, 0x0052c140 } },
1322 { 0xa21c, 1133 { AR5K_PHY_CCK_RX_CTL_4,
1323 { 0x1883800a, 0x1883800a } }, 1134 { 0x1883800a, 0x1883800a, 0x1863800a, 0x1883800a, 0x1883800a } },
1324 { 0xa324, 1135 { 0xa324,
1325 { 0xa7cfa7cf, 0xa7cfa7cf } }, 1136 { 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf } },
1326 { 0xa328, 1137 { 0xa328,
1327 { 0xa7cfa7cf, 0xa7cfa7cf } }, 1138 { 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf } },
1328 { 0xa32c, 1139 { 0xa32c,
1329 { 0xa7cfa7cf, 0xa7cfa7cf } }, 1140 { 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf } },
1330 { 0xa330, 1141 { 0xa330,
1331 { 0xa7cfa7cf, 0xa7cfa7cf } }, 1142 { 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf } },
1332 { 0xa334, 1143 { 0xa334,
1333 { 0xa7cfa7cf, 0xa7cfa7cf } }, 1144 { 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf } },
1334 { AR5K_DCU_FP, 1145};
1335 { 0x000003e0, 0x000003e0 } }, 1146
1336 { 0x8060, 1147static const struct ath5k_ini rf2425_ini_common_end[] = {
1337 { 0x0000000f, 0x0000000f } }, 1148 { AR5K_DCU_FP, 0x000003e0 },
1338 { 0x809c, 1149 { AR5K_SEQ_MASK, 0x0000000f },
1339 { 0x00000000, 0x00000000 } }, 1150 { 0x809c, 0x00000000 },
1340 { 0x80a0, 1151 { 0x80a0, 0x00000000 },
1341 { 0x00000000, 0x00000000 } }, 1152 { AR5K_MIC_QOS_CTL, 0x00000000 },
1342 { 0x8118, 1153 { AR5K_MIC_QOS_SEL, 0x00000000 },
1343 { 0x00000000, 0x00000000 } }, 1154 { AR5K_MISC_MODE, 0x00000000 },
1344 { 0x811c, 1155 { AR5K_OFDM_FIL_CNT, 0x00000000 },
1345 { 0x00000000, 0x00000000 } }, 1156 { AR5K_CCK_FIL_CNT, 0x00000000 },
1346 { 0x8120, 1157 { AR5K_PHYERR_CNT1, 0x00000000 },
1347 { 0x00000000, 0x00000000 } }, 1158 { AR5K_PHYERR_CNT1_MASK, 0x00000000 },
1348 { 0x8124, 1159 { AR5K_PHYERR_CNT2, 0x00000000 },
1349 { 0x00000000, 0x00000000 } }, 1160 { AR5K_PHYERR_CNT2_MASK, 0x00000000 },
1350 { 0x8128, 1161 { AR5K_TSF_THRES, 0x00000000 },
1351 { 0x00000000, 0x00000000 } }, 1162 { 0x8140, 0x800003f9 },
1352 { 0x812c, 1163 { 0x8144, 0x00000000 },
1353 { 0x00000000, 0x00000000 } }, 1164 { AR5K_PHY_AGC, 0x00000000 },
1354 { 0x8130, 1165 { AR5K_PHY_ADC_CTL, 0x0000a000 },
1355 { 0x00000000, 0x00000000 } }, 1166 { 0x983c, 0x00200400 },
1356 { 0x8134, 1167 { AR5K_PHY_GAIN_OFFSET, 0x1284233c },
1357 { 0x00000000, 0x00000000 } }, 1168 { AR5K_PHY_SCR, 0x0000001f },
1358 { 0x8138, 1169 { AR5K_PHY_SLMT, 0x00000080 },
1359 { 0x00000000, 0x00000000 } }, 1170 { AR5K_PHY_SCAL, 0x0000000e },
1360 { 0x813c, 1171 { 0x9958, 0x00081fff },
1361 { 0x00000000, 0x00000000 } }, 1172 { AR5K_PHY_TIMING_7, 0x00000000 },
1362 { 0x8140, 1173 { AR5K_PHY_TIMING_8, 0x02800000 },
1363 { 0x800003f9, 0x800003f9 } }, 1174 { AR5K_PHY_TIMING_11, 0x00000000 },
1364 { 0x8144, 1175 { 0x99dc, 0xfebadbe8 },
1365 { 0x00000000, 0x00000000 } }, 1176 { AR5K_PHY_HEAVY_CLIP_ENABLE, 0x00000000 },
1366 { AR5K_PHY_AGC, 1177 { 0x99e4, 0xaaaaaaaa },
1367 { 0x00000000, 0x00000000 } }, 1178 { 0x99e8, 0x3c466478 },
1368 { AR5K_PHY(11), 1179 { 0x99ec, 0x000000aa },
1369 { 0x0000a000, 0x0000a000 } }, 1180 { AR5K_PHY_SCLOCK, 0x0000000c },
1370 { AR5K_PHY(15), 1181 { AR5K_PHY_SDELAY, 0x000000ff },
1371 { 0x00200400, 0x00200400 } }, 1182 { AR5K_PHY_SPENDING, 0x00000014 },
1372 { AR5K_PHY(19), 1183 { AR5K_PHY_DAG_CCK_CTL, 0x000009b5 },
1373 { 0x1284233c, 0x1284233c } }, 1184 { AR5K_PHY_TXPOWER_RATE3, 0x20202020 },
1374 { AR5K_PHY_SCR, 1185 { AR5K_PHY_TXPOWER_RATE4, 0x20202020 },
1375 { 0x0000001f, 0x0000001f } }, 1186 { 0xa23c, 0x93c889af },
1376 { AR5K_PHY_SLMT, 1187 { AR5K_PHY_FAST_ADC, 0x00000001 },
1377 { 0x00000080, 0x00000080 } }, 1188 { 0xa250, 0x0000a000 },
1378 { AR5K_PHY_SCAL, 1189 { AR5K_PHY_BLUETOOTH, 0x00000000 },
1379 { 0x0000000e, 0x0000000e } }, 1190 { AR5K_PHY_TPC_RG1, 0x0cc75380 },
1380 { AR5K_PHY(86), 1191 { 0xa25c, 0x0f0f0f01 },
1381 { 0x00081fff, 0x00081fff } }, 1192 { 0xa260, 0x5f690f01 },
1382 { AR5K_PHY(96), 1193 { 0xa264, 0x00418a11 },
1383 { 0x00000000, 0x00000000 } }, 1194 { 0xa268, 0x00000000 },
1384 { AR5K_PHY(97), 1195 { AR5K_PHY_TPC_RG5, 0x0c30c166 },
1385 { 0x02800000, 0x02800000 } }, 1196 { 0xa270, 0x00820820 },
1386 { AR5K_PHY(104), 1197 { 0xa274, 0x081a3caa },
1387 { 0x00000000, 0x00000000 } }, 1198 { 0xa278, 0x1ce739ce },
1388 { AR5K_PHY(119), 1199 { 0xa27c, 0x051701ce },
1389 { 0xfebadbe8, 0xfebadbe8 } }, 1200 { 0xa300, 0x16010000 },
1390 { AR5K_PHY(120), 1201 { 0xa304, 0x2c032402 },
1391 { 0x00000000, 0x00000000 } }, 1202 { 0xa308, 0x48433e42 },
1392 { AR5K_PHY(121), 1203 { 0xa30c, 0x5a0f500b },
1393 { 0xaaaaaaaa, 0xaaaaaaaa } }, 1204 { 0xa310, 0x6c4b624a },
1394 { AR5K_PHY(122), 1205 { 0xa314, 0x7e8b748a },
1395 { 0x3c466478, 0x3c466478 } }, 1206 { 0xa318, 0x96cf8ccb },
1396 { AR5K_PHY(123), 1207 { 0xa31c, 0xa34f9d0f },
1397 { 0x000000aa, 0x000000aa } }, 1208 { 0xa320, 0xa7cfa58f },
1398 { AR5K_PHY_SCLOCK, 1209 { 0xa348, 0x3fffffff },
1399 { 0x0000000c, 0x0000000c } }, 1210 { 0xa34c, 0x3fffffff },
1400 { AR5K_PHY_SDELAY, 1211 { 0xa350, 0x3fffffff },
1401 { 0x000000ff, 0x000000ff } }, 1212 { 0xa354, 0x0003ffff },
1402 { AR5K_PHY_SPENDING, 1213 { 0xa358, 0x79a8aa1f },
1403 { 0x00000014, 0x00000014 } }, 1214 { 0xa35c, 0x066c420f },
1404 { 0xa228, 1215 { 0xa360, 0x0f282207 },
1405 { 0x000009b5, 0x000009b5 } }, 1216 { 0xa364, 0x17601685 },
1406 { AR5K_PHY_TXPOWER_RATE3, 1217 { 0xa368, 0x1f801104 },
1407 { 0x20202020, 0x20202020 } }, 1218 { 0xa36c, 0x37a00c03 },
1408 { AR5K_PHY_TXPOWER_RATE4, 1219 { 0xa370, 0x3fc40883 },
1409 { 0x20202020, 0x20202020 } }, 1220 { 0xa374, 0x57c00803 },
1410 { 0xa23c, 1221 { 0xa378, 0x5fd80682 },
1411 { 0x93c889af, 0x93c889af } }, 1222 { 0xa37c, 0x7fe00482 },
1412 { 0xa24c, 1223 { 0xa380, 0x7f3c7bba },
1413 { 0x00000001, 0x00000001 } }, 1224 { 0xa384, 0xf3307ff0 },
1414 { 0xa250,
1415 { 0x0000a000, 0x0000a000 } },
1416 { 0xa254,
1417 { 0x00000000, 0x00000000 } },
1418 { 0xa258,
1419 { 0x0cc75380, 0x0cc75380 } },
1420 { 0xa25c,
1421 { 0x0f0f0f01, 0x0f0f0f01 } },
1422 { 0xa260,
1423 { 0x5f690f01, 0x5f690f01 } },
1424 { 0xa264,
1425 { 0x00418a11, 0x00418a11 } },
1426 { 0xa268,
1427 { 0x00000000, 0x00000000 } },
1428 { 0xa26c,
1429 { 0x0c30c166, 0x0c30c166 } },
1430 { 0xa270,
1431 { 0x00820820, 0x00820820 } },
1432 { 0xa274,
1433 { 0x081a3caa, 0x081a3caa } },
1434 { 0xa278,
1435 { 0x1ce739ce, 0x1ce739ce } },
1436 { 0xa27c,
1437 { 0x051701ce, 0x051701ce } },
1438 { 0xa300,
1439 { 0x16010000, 0x16010000 } },
1440 { 0xa304,
1441 { 0x2c032402, 0x2c032402 } },
1442 { 0xa308,
1443 { 0x48433e42, 0x48433e42 } },
1444 { 0xa30c,
1445 { 0x5a0f500b, 0x5a0f500b } },
1446 { 0xa310,
1447 { 0x6c4b624a, 0x6c4b624a } },
1448 { 0xa314,
1449 { 0x7e8b748a, 0x7e8b748a } },
1450 { 0xa318,
1451 { 0x96cf8ccb, 0x96cf8ccb } },
1452 { 0xa31c,
1453 { 0xa34f9d0f, 0xa34f9d0f } },
1454 { 0xa320,
1455 { 0xa7cfa58f, 0xa7cfa58f } },
1456 { 0xa348,
1457 { 0x3fffffff, 0x3fffffff } },
1458 { 0xa34c,
1459 { 0x3fffffff, 0x3fffffff } },
1460 { 0xa350,
1461 { 0x3fffffff, 0x3fffffff } },
1462 { 0xa354,
1463 { 0x0003ffff, 0x0003ffff } },
1464 { 0xa358,
1465 { 0x79a8aa1f, 0x79a8aa1f } },
1466 { 0xa35c,
1467 { 0x066c420f, 0x066c420f } },
1468 { 0xa360,
1469 { 0x0f282207, 0x0f282207 } },
1470 { 0xa364,
1471 { 0x17601685, 0x17601685 } },
1472 { 0xa368,
1473 { 0x1f801104, 0x1f801104 } },
1474 { 0xa36c,
1475 { 0x37a00c03, 0x37a00c03 } },
1476 { 0xa370,
1477 { 0x3fc40883, 0x3fc40883 } },
1478 { 0xa374,
1479 { 0x57c00803, 0x57c00803 } },
1480 { 0xa378,
1481 { 0x5fd80682, 0x5fd80682 } },
1482 { 0xa37c,
1483 { 0x7fe00482, 0x7fe00482 } },
1484 { 0xa380,
1485 { 0x7f3c7bba, 0x7f3c7bba } },
1486 { 0xa384,
1487 { 0xf3307ff0, 0xf3307ff0 } },
1488}; 1225};
1489 1226
1490/* 1227/*
@@ -1560,7 +1297,7 @@ static const struct ath5k_ini rf5111_ini_bbgain[] = {
1560 { AR5K_BB_GAIN(63), 0x00000016 }, 1297 { AR5K_BB_GAIN(63), 0x00000016 },
1561}; 1298};
1562 1299
1563/* RF5112 Initial BaseBand Gain settings (Same for RF5413/5414) */ 1300/* RF5112 Initial BaseBand Gain settings (Same for RF5413/5414+) */
1564static const struct ath5k_ini rf5112_ini_bbgain[] = { 1301static const struct ath5k_ini rf5112_ini_bbgain[] = {
1565 { AR5K_BB_GAIN(0), 0x00000000 }, 1302 { AR5K_BB_GAIN(0), 0x00000000 },
1566 { AR5K_BB_GAIN(1), 0x00000001 }, 1303 { AR5K_BB_GAIN(1), 0x00000001 },
@@ -1691,87 +1428,97 @@ int ath5k_hw_write_initvals(struct ath5k_hw *ah, u8 mode, bool change_channel)
1691 /* 1428 /*
1692 * Write initial settings common for all modes 1429 * Write initial settings common for all modes
1693 */ 1430 */
1694 ath5k_hw_ini_registers(ah, ARRAY_SIZE(ar5212_ini), 1431 ath5k_hw_ini_registers(ah, ARRAY_SIZE(ar5212_ini_common_start),
1695 ar5212_ini, change_channel); 1432 ar5212_ini_common_start, change_channel);
1696 1433
1697 /* Second set of mode-specific settings */ 1434 /* Second set of mode-specific settings */
1698 if (ah->ah_radio == AR5K_RF5111) { 1435 switch (ah->ah_radio) {
1436 case AR5K_RF5111:
1699 1437
1700 ath5k_hw_ini_mode_registers(ah, 1438 ath5k_hw_ini_mode_registers(ah,
1701 ARRAY_SIZE(ar5212_rf5111_ini_mode_end), 1439 ARRAY_SIZE(rf5111_ini_mode_end),
1702 ar5212_rf5111_ini_mode_end, mode); 1440 rf5111_ini_mode_end, mode);
1441
1442 ath5k_hw_ini_registers(ah,
1443 ARRAY_SIZE(rf5111_ini_common_end),
1444 rf5111_ini_common_end, change_channel);
1703 1445
1704 /* Baseband gain table */ 1446 /* Baseband gain table */
1705 ath5k_hw_ini_registers(ah, 1447 ath5k_hw_ini_registers(ah,
1706 ARRAY_SIZE(rf5111_ini_bbgain), 1448 ARRAY_SIZE(rf5111_ini_bbgain),
1707 rf5111_ini_bbgain, change_channel); 1449 rf5111_ini_bbgain, change_channel);
1708 1450
1709 } else if (ah->ah_radio == AR5K_RF5112) { 1451 break;
1452 case AR5K_RF5112:
1710 1453
1711 ath5k_hw_ini_mode_registers(ah, 1454 ath5k_hw_ini_mode_registers(ah,
1712 ARRAY_SIZE(ar5212_rf5112_ini_mode_end), 1455 ARRAY_SIZE(rf5112_ini_mode_end),
1713 ar5212_rf5112_ini_mode_end, mode); 1456 rf5112_ini_mode_end, mode);
1457
1458 ath5k_hw_ini_registers(ah,
1459 ARRAY_SIZE(rf5112_ini_common_end),
1460 rf5112_ini_common_end, change_channel);
1714 1461
1715 ath5k_hw_ini_registers(ah, 1462 ath5k_hw_ini_registers(ah,
1716 ARRAY_SIZE(rf5112_ini_bbgain), 1463 ARRAY_SIZE(rf5112_ini_bbgain),
1717 rf5112_ini_bbgain, change_channel); 1464 rf5112_ini_bbgain, change_channel);
1718 1465
1719 } else if (ah->ah_radio == AR5K_RF5413) { 1466 break;
1467 case AR5K_RF5413:
1720 1468
1721 ath5k_hw_ini_mode_registers(ah, 1469 ath5k_hw_ini_mode_registers(ah,
1722 ARRAY_SIZE(rf5413_ini_mode_end), 1470 ARRAY_SIZE(rf5413_ini_mode_end),
1723 rf5413_ini_mode_end, mode); 1471 rf5413_ini_mode_end, mode);
1724 1472
1725 ath5k_hw_ini_registers(ah, 1473 ath5k_hw_ini_registers(ah,
1474 ARRAY_SIZE(rf5413_ini_common_end),
1475 rf5413_ini_common_end, change_channel);
1476
1477 ath5k_hw_ini_registers(ah,
1726 ARRAY_SIZE(rf5112_ini_bbgain), 1478 ARRAY_SIZE(rf5112_ini_bbgain),
1727 rf5112_ini_bbgain, change_channel); 1479 rf5112_ini_bbgain, change_channel);
1728 1480
1729 } else if (ah->ah_radio == AR5K_RF2413) { 1481 break;
1730 1482 case AR5K_RF2316:
1731 if (mode < 2) { 1483 case AR5K_RF2413:
1732 ATH5K_ERR(ah->ah_sc,
1733 "unsupported channel mode: %d\n", mode);
1734 return -EINVAL;
1735 }
1736 mode = mode - 2;
1737
1738 /* Override a setting from ar5212_ini */
1739 ath5k_hw_reg_write(ah, 0x018830c6, AR5K_PHY(648));
1740 1484
1741 ath5k_hw_ini_mode_registers(ah, 1485 ath5k_hw_ini_mode_registers(ah,
1742 ARRAY_SIZE(rf2413_ini_mode_end), 1486 ARRAY_SIZE(rf2413_ini_mode_end),
1743 rf2413_ini_mode_end, mode); 1487 rf2413_ini_mode_end, mode);
1744 1488
1745 /* Baseband gain table */
1746 ath5k_hw_ini_registers(ah, 1489 ath5k_hw_ini_registers(ah,
1747 ARRAY_SIZE(rf5112_ini_bbgain), 1490 ARRAY_SIZE(rf2413_ini_common_end),
1748 rf5112_ini_bbgain, change_channel); 1491 rf2413_ini_common_end, change_channel);
1749
1750 } else if (ah->ah_radio == AR5K_RF2425) {
1751 1492
1752 if (mode < 2) { 1493 /* Override settings from rf2413_ini_common_end */
1753 ATH5K_ERR(ah->ah_sc, 1494 if (ah->ah_radio == AR5K_RF2316) {
1754 "unsupported channel mode: %d\n", mode); 1495 ath5k_hw_reg_write(ah, 0x00004000,
1755 return -EINVAL; 1496 AR5K_PHY_AGC);
1497 ath5k_hw_reg_write(ah, 0x081b7caa,
1498 0xa274);
1756 } 1499 }
1757 1500
1758 /* Map b to g */ 1501 ath5k_hw_ini_registers(ah,
1759 if (mode == 2) 1502 ARRAY_SIZE(rf5112_ini_bbgain),
1760 mode = 0; 1503 rf5112_ini_bbgain, change_channel);
1761 else 1504 break;
1762 mode = mode - 3; 1505 case AR5K_RF2317:
1763 1506 case AR5K_RF2425:
1764 /* Override a setting from ar5212_ini */
1765 ath5k_hw_reg_write(ah, 0x018830c6, AR5K_PHY(648));
1766 1507
1767 ath5k_hw_ini_mode_registers(ah, 1508 ath5k_hw_ini_mode_registers(ah,
1768 ARRAY_SIZE(rf2425_ini_mode_end), 1509 ARRAY_SIZE(rf2425_ini_mode_end),
1769 rf2425_ini_mode_end, mode); 1510 rf2425_ini_mode_end, mode);
1770 1511
1771 /* Baseband gain table */ 1512 ath5k_hw_ini_registers(ah,
1513 ARRAY_SIZE(rf2413_ini_common_end),
1514 rf2413_ini_common_end, change_channel);
1515
1772 ath5k_hw_ini_registers(ah, 1516 ath5k_hw_ini_registers(ah,
1773 ARRAY_SIZE(rf5112_ini_bbgain), 1517 ARRAY_SIZE(rf5112_ini_bbgain),
1774 rf5112_ini_bbgain, change_channel); 1518 rf5112_ini_bbgain, change_channel);
1519 break;
1520 default:
1521 return -EINVAL;
1775 1522
1776 } 1523 }
1777 1524
diff --git a/drivers/net/wireless/ath5k/phy.c b/drivers/net/wireless/ath5k/phy.c
index 7ba18e09463b..81f5bebc48b1 100644
--- a/drivers/net/wireless/ath5k/phy.c
+++ b/drivers/net/wireless/ath5k/phy.c
@@ -2,7 +2,7 @@
2 * PHY functions 2 * PHY functions
3 * 3 *
4 * Copyright (c) 2004-2007 Reyk Floeter <reyk@openbsd.org> 4 * Copyright (c) 2004-2007 Reyk Floeter <reyk@openbsd.org>
5 * Copyright (c) 2006-2007 Nick Kossifidis <mickflemm@gmail.com> 5 * Copyright (c) 2006-2009 Nick Kossifidis <mickflemm@gmail.com>
6 * Copyright (c) 2007-2008 Jiri Slaby <jirislaby@gmail.com> 6 * Copyright (c) 2007-2008 Jiri Slaby <jirislaby@gmail.com>
7 * 7 *
8 * Permission to use, copy, modify, and distribute this software for any 8 * Permission to use, copy, modify, and distribute this software for any
@@ -26,1138 +26,191 @@
26#include "ath5k.h" 26#include "ath5k.h"
27#include "reg.h" 27#include "reg.h"
28#include "base.h" 28#include "base.h"
29 29#include "rfbuffer.h"
30/* Struct to hold initial RF register values (RF Banks) */ 30#include "rfgain.h"
31struct ath5k_ini_rf {
32 u8 rf_bank; /* check out ath5k_reg.h */
33 u16 rf_register; /* register address */
34 u32 rf_value[5]; /* register value for different modes (above) */
35};
36
37/*
38 * Mode-specific RF Gain table (64bytes) for RF5111/5112
39 * (RF5110 only comes with AR5210 and only supports a/turbo a mode so initial
40 * RF Gain values are included in AR5K_AR5210_INI)
41 */
42struct ath5k_ini_rfgain {
43 u16 rfg_register; /* RF Gain register address */
44 u32 rfg_value[2]; /* [freq (see below)] */
45};
46
47struct ath5k_gain_opt {
48 u32 go_default;
49 u32 go_steps_count;
50 const struct ath5k_gain_opt_step go_step[AR5K_GAIN_STEP_COUNT];
51};
52
53/* RF5111 mode-specific init registers */
54static const struct ath5k_ini_rf rfregs_5111[] = {
55 { 0, 0x989c,
56 /* mode a/XR mode aTurbo mode b mode g mode gTurbo */
57 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
58 { 0, 0x989c,
59 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
60 { 0, 0x989c,
61 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
62 { 0, 0x989c,
63 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
64 { 0, 0x989c,
65 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
66 { 0, 0x989c,
67 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
68 { 0, 0x989c,
69 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
70 { 0, 0x989c,
71 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
72 { 0, 0x989c,
73 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
74 { 0, 0x989c,
75 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
76 { 0, 0x989c,
77 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
78 { 0, 0x989c,
79 { 0x00380000, 0x00380000, 0x00380000, 0x00380000, 0x00380000 } },
80 { 0, 0x989c,
81 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
82 { 0, 0x989c,
83 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
84 { 0, 0x989c,
85 { 0x00000000, 0x00000000, 0x000000c0, 0x00000080, 0x00000080 } },
86 { 0, 0x989c,
87 { 0x000400f9, 0x000400f9, 0x000400ff, 0x000400fd, 0x000400fd } },
88 { 0, 0x98d4,
89 { 0x00000000, 0x00000000, 0x00000004, 0x00000004, 0x00000004 } },
90 { 1, 0x98d4,
91 { 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020 } },
92 { 2, 0x98d4,
93 { 0x00000010, 0x00000014, 0x00000010, 0x00000010, 0x00000014 } },
94 { 3, 0x98d8,
95 { 0x00601068, 0x00601068, 0x00601068, 0x00601068, 0x00601068 } },
96 { 6, 0x989c,
97 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
98 { 6, 0x989c,
99 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
100 { 6, 0x989c,
101 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
102 { 6, 0x989c,
103 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
104 { 6, 0x989c,
105 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
106 { 6, 0x989c,
107 { 0x10000000, 0x10000000, 0x10000000, 0x10000000, 0x10000000 } },
108 { 6, 0x989c,
109 { 0x04000000, 0x04000000, 0x04000000, 0x04000000, 0x04000000 } },
110 { 6, 0x989c,
111 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
112 { 6, 0x989c,
113 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
114 { 6, 0x989c,
115 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
116 { 6, 0x989c,
117 { 0x00000000, 0x00000000, 0x0a000000, 0x00000000, 0x00000000 } },
118 { 6, 0x989c,
119 { 0x003800c0, 0x00380080, 0x023800c0, 0x003800c0, 0x003800c0 } },
120 { 6, 0x989c,
121 { 0x00020006, 0x00020006, 0x00000006, 0x00020006, 0x00020006 } },
122 { 6, 0x989c,
123 { 0x00000089, 0x00000089, 0x00000089, 0x00000089, 0x00000089 } },
124 { 6, 0x989c,
125 { 0x000000a0, 0x000000a0, 0x000000a0, 0x000000a0, 0x000000a0 } },
126 { 6, 0x989c,
127 { 0x00040007, 0x00040007, 0x00040007, 0x00040007, 0x00040007 } },
128 { 6, 0x98d4,
129 { 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a } },
130 { 7, 0x989c,
131 { 0x00000040, 0x00000048, 0x00000040, 0x00000040, 0x00000040 } },
132 { 7, 0x989c,
133 { 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010 } },
134 { 7, 0x989c,
135 { 0x00000008, 0x00000008, 0x00000008, 0x00000008, 0x00000008 } },
136 { 7, 0x989c,
137 { 0x0000004f, 0x0000004f, 0x0000004f, 0x0000004f, 0x0000004f } },
138 { 7, 0x989c,
139 { 0x000000f1, 0x000000f1, 0x00000061, 0x000000f1, 0x000000f1 } },
140 { 7, 0x989c,
141 { 0x0000904f, 0x0000904f, 0x0000904c, 0x0000904f, 0x0000904f } },
142 { 7, 0x989c,
143 { 0x0000125a, 0x0000125a, 0x0000129a, 0x0000125a, 0x0000125a } },
144 { 7, 0x98cc,
145 { 0x0000000e, 0x0000000e, 0x0000000f, 0x0000000e, 0x0000000e } },
146};
147
148/* Initial RF Gain settings for RF5111 */
149static const struct ath5k_ini_rfgain rfgain_5111[] = {
150 /* 5Ghz 2Ghz */
151 { AR5K_RF_GAIN(0), { 0x000001a9, 0x00000000 } },
152 { AR5K_RF_GAIN(1), { 0x000001e9, 0x00000040 } },
153 { AR5K_RF_GAIN(2), { 0x00000029, 0x00000080 } },
154 { AR5K_RF_GAIN(3), { 0x00000069, 0x00000150 } },
155 { AR5K_RF_GAIN(4), { 0x00000199, 0x00000190 } },
156 { AR5K_RF_GAIN(5), { 0x000001d9, 0x000001d0 } },
157 { AR5K_RF_GAIN(6), { 0x00000019, 0x00000010 } },
158 { AR5K_RF_GAIN(7), { 0x00000059, 0x00000044 } },
159 { AR5K_RF_GAIN(8), { 0x00000099, 0x00000084 } },
160 { AR5K_RF_GAIN(9), { 0x000001a5, 0x00000148 } },
161 { AR5K_RF_GAIN(10), { 0x000001e5, 0x00000188 } },
162 { AR5K_RF_GAIN(11), { 0x00000025, 0x000001c8 } },
163 { AR5K_RF_GAIN(12), { 0x000001c8, 0x00000014 } },
164 { AR5K_RF_GAIN(13), { 0x00000008, 0x00000042 } },
165 { AR5K_RF_GAIN(14), { 0x00000048, 0x00000082 } },
166 { AR5K_RF_GAIN(15), { 0x00000088, 0x00000178 } },
167 { AR5K_RF_GAIN(16), { 0x00000198, 0x000001b8 } },
168 { AR5K_RF_GAIN(17), { 0x000001d8, 0x000001f8 } },
169 { AR5K_RF_GAIN(18), { 0x00000018, 0x00000012 } },
170 { AR5K_RF_GAIN(19), { 0x00000058, 0x00000052 } },
171 { AR5K_RF_GAIN(20), { 0x00000098, 0x00000092 } },
172 { AR5K_RF_GAIN(21), { 0x000001a4, 0x0000017c } },
173 { AR5K_RF_GAIN(22), { 0x000001e4, 0x000001bc } },
174 { AR5K_RF_GAIN(23), { 0x00000024, 0x000001fc } },
175 { AR5K_RF_GAIN(24), { 0x00000064, 0x0000000a } },
176 { AR5K_RF_GAIN(25), { 0x000000a4, 0x0000004a } },
177 { AR5K_RF_GAIN(26), { 0x000000e4, 0x0000008a } },
178 { AR5K_RF_GAIN(27), { 0x0000010a, 0x0000015a } },
179 { AR5K_RF_GAIN(28), { 0x0000014a, 0x0000019a } },
180 { AR5K_RF_GAIN(29), { 0x0000018a, 0x000001da } },
181 { AR5K_RF_GAIN(30), { 0x000001ca, 0x0000000e } },
182 { AR5K_RF_GAIN(31), { 0x0000000a, 0x0000004e } },
183 { AR5K_RF_GAIN(32), { 0x0000004a, 0x0000008e } },
184 { AR5K_RF_GAIN(33), { 0x0000008a, 0x0000015e } },
185 { AR5K_RF_GAIN(34), { 0x000001ba, 0x0000019e } },
186 { AR5K_RF_GAIN(35), { 0x000001fa, 0x000001de } },
187 { AR5K_RF_GAIN(36), { 0x0000003a, 0x00000009 } },
188 { AR5K_RF_GAIN(37), { 0x0000007a, 0x00000049 } },
189 { AR5K_RF_GAIN(38), { 0x00000186, 0x00000089 } },
190 { AR5K_RF_GAIN(39), { 0x000001c6, 0x00000179 } },
191 { AR5K_RF_GAIN(40), { 0x00000006, 0x000001b9 } },
192 { AR5K_RF_GAIN(41), { 0x00000046, 0x000001f9 } },
193 { AR5K_RF_GAIN(42), { 0x00000086, 0x00000039 } },
194 { AR5K_RF_GAIN(43), { 0x000000c6, 0x00000079 } },
195 { AR5K_RF_GAIN(44), { 0x000000c6, 0x000000b9 } },
196 { AR5K_RF_GAIN(45), { 0x000000c6, 0x000001bd } },
197 { AR5K_RF_GAIN(46), { 0x000000c6, 0x000001fd } },
198 { AR5K_RF_GAIN(47), { 0x000000c6, 0x0000003d } },
199 { AR5K_RF_GAIN(48), { 0x000000c6, 0x0000007d } },
200 { AR5K_RF_GAIN(49), { 0x000000c6, 0x000000bd } },
201 { AR5K_RF_GAIN(50), { 0x000000c6, 0x000000fd } },
202 { AR5K_RF_GAIN(51), { 0x000000c6, 0x000000fd } },
203 { AR5K_RF_GAIN(52), { 0x000000c6, 0x000000fd } },
204 { AR5K_RF_GAIN(53), { 0x000000c6, 0x000000fd } },
205 { AR5K_RF_GAIN(54), { 0x000000c6, 0x000000fd } },
206 { AR5K_RF_GAIN(55), { 0x000000c6, 0x000000fd } },
207 { AR5K_RF_GAIN(56), { 0x000000c6, 0x000000fd } },
208 { AR5K_RF_GAIN(57), { 0x000000c6, 0x000000fd } },
209 { AR5K_RF_GAIN(58), { 0x000000c6, 0x000000fd } },
210 { AR5K_RF_GAIN(59), { 0x000000c6, 0x000000fd } },
211 { AR5K_RF_GAIN(60), { 0x000000c6, 0x000000fd } },
212 { AR5K_RF_GAIN(61), { 0x000000c6, 0x000000fd } },
213 { AR5K_RF_GAIN(62), { 0x000000c6, 0x000000fd } },
214 { AR5K_RF_GAIN(63), { 0x000000c6, 0x000000fd } },
215};
216
217static const struct ath5k_gain_opt rfgain_opt_5111 = {
218 4,
219 9,
220 {
221 { { 4, 1, 1, 1 }, 6 },
222 { { 4, 0, 1, 1 }, 4 },
223 { { 3, 1, 1, 1 }, 3 },
224 { { 4, 0, 0, 1 }, 1 },
225 { { 4, 1, 1, 0 }, 0 },
226 { { 4, 0, 1, 0 }, -2 },
227 { { 3, 1, 1, 0 }, -3 },
228 { { 4, 0, 0, 0 }, -4 },
229 { { 2, 1, 1, 0 }, -6 }
230 }
231};
232
233/* RF5112 mode-specific init registers */
234static const struct ath5k_ini_rf rfregs_5112[] = {
235 { 1, 0x98d4,
236 /* mode a/XR mode aTurbo mode b mode g mode gTurbo */
237 { 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020 } },
238 { 2, 0x98d0,
239 { 0x03060408, 0x03070408, 0x03060408, 0x03060408, 0x03070408 } },
240 { 3, 0x98dc,
241 { 0x00a0c0c0, 0x00a0c0c0, 0x00e0c0c0, 0x00e0c0c0, 0x00e0c0c0 } },
242 { 6, 0x989c,
243 { 0x00a00000, 0x00a00000, 0x00a00000, 0x00a00000, 0x00a00000 } },
244 { 6, 0x989c,
245 { 0x000a0000, 0x000a0000, 0x000a0000, 0x000a0000, 0x000a0000 } },
246 { 6, 0x989c,
247 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
248 { 6, 0x989c,
249 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
250 { 6, 0x989c,
251 { 0x00660000, 0x00660000, 0x00660000, 0x00660000, 0x00660000 } },
252 { 6, 0x989c,
253 { 0x00db0000, 0x00db0000, 0x00db0000, 0x00db0000, 0x00db0000 } },
254 { 6, 0x989c,
255 { 0x00f10000, 0x00f10000, 0x00f10000, 0x00f10000, 0x00f10000 } },
256 { 6, 0x989c,
257 { 0x00120000, 0x00120000, 0x00120000, 0x00120000, 0x00120000 } },
258 { 6, 0x989c,
259 { 0x00120000, 0x00120000, 0x00120000, 0x00120000, 0x00120000 } },
260 { 6, 0x989c,
261 { 0x00730000, 0x00730000, 0x00730000, 0x00730000, 0x00730000 } },
262 { 6, 0x989c,
263 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
264 { 6, 0x989c,
265 { 0x000c0000, 0x000c0000, 0x000c0000, 0x000c0000, 0x000c0000 } },
266 { 6, 0x989c,
267 { 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000 } },
268 { 6, 0x989c,
269 { 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000 } },
270 { 6, 0x989c,
271 { 0x008b0000, 0x008b0000, 0x008b0000, 0x008b0000, 0x008b0000 } },
272 { 6, 0x989c,
273 { 0x00600000, 0x00600000, 0x00600000, 0x00600000, 0x00600000 } },
274 { 6, 0x989c,
275 { 0x000c0000, 0x000c0000, 0x000c0000, 0x000c0000, 0x000c0000 } },
276 { 6, 0x989c,
277 { 0x00840000, 0x00840000, 0x00840000, 0x00840000, 0x00840000 } },
278 { 6, 0x989c,
279 { 0x00640000, 0x00640000, 0x00640000, 0x00640000, 0x00640000 } },
280 { 6, 0x989c,
281 { 0x00200000, 0x00200000, 0x00200000, 0x00200000, 0x00200000 } },
282 { 6, 0x989c,
283 { 0x00240000, 0x00240000, 0x00240000, 0x00240000, 0x00240000 } },
284 { 6, 0x989c,
285 { 0x00250000, 0x00250000, 0x00250000, 0x00250000, 0x00250000 } },
286 { 6, 0x989c,
287 { 0x00110000, 0x00110000, 0x00110000, 0x00110000, 0x00110000 } },
288 { 6, 0x989c,
289 { 0x00110000, 0x00110000, 0x00110000, 0x00110000, 0x00110000 } },
290 { 6, 0x989c,
291 { 0x00510000, 0x00510000, 0x00510000, 0x00510000, 0x00510000 } },
292 { 6, 0x989c,
293 { 0x1c040000, 0x1c040000, 0x1c040000, 0x1c040000, 0x1c040000 } },
294 { 6, 0x989c,
295 { 0x000a0000, 0x000a0000, 0x000a0000, 0x000a0000, 0x000a0000 } },
296 { 6, 0x989c,
297 { 0x00a10000, 0x00a10000, 0x00a10000, 0x00a10000, 0x00a10000 } },
298 { 6, 0x989c,
299 { 0x00400000, 0x00400000, 0x00400000, 0x00400000, 0x00400000 } },
300 { 6, 0x989c,
301 { 0x03090000, 0x03090000, 0x03090000, 0x03090000, 0x03090000 } },
302 { 6, 0x989c,
303 { 0x06000000, 0x06000000, 0x06000000, 0x06000000, 0x06000000 } },
304 { 6, 0x989c,
305 { 0x000000b0, 0x000000b0, 0x000000a8, 0x000000a8, 0x000000a8 } },
306 { 6, 0x989c,
307 { 0x0000002e, 0x0000002e, 0x0000002e, 0x0000002e, 0x0000002e } },
308 { 6, 0x989c,
309 { 0x006c4a41, 0x006c4a41, 0x006c4af1, 0x006c4a61, 0x006c4a61 } },
310 { 6, 0x989c,
311 { 0x0050892a, 0x0050892a, 0x0050892b, 0x0050892b, 0x0050892b } },
312 { 6, 0x989c,
313 { 0x00842400, 0x00842400, 0x00842400, 0x00842400, 0x00842400 } },
314 { 6, 0x989c,
315 { 0x00c69200, 0x00c69200, 0x00c69200, 0x00c69200, 0x00c69200 } },
316 { 6, 0x98d0,
317 { 0x0002000c, 0x0002000c, 0x0002000c, 0x0002000c, 0x0002000c } },
318 { 7, 0x989c,
319 { 0x00000094, 0x00000094, 0x00000094, 0x00000094, 0x00000094 } },
320 { 7, 0x989c,
321 { 0x00000091, 0x00000091, 0x00000091, 0x00000091, 0x00000091 } },
322 { 7, 0x989c,
323 { 0x0000000a, 0x0000000a, 0x00000012, 0x00000012, 0x00000012 } },
324 { 7, 0x989c,
325 { 0x00000080, 0x00000080, 0x00000080, 0x00000080, 0x00000080 } },
326 { 7, 0x989c,
327 { 0x000000c1, 0x000000c1, 0x000000c1, 0x000000c1, 0x000000c1 } },
328 { 7, 0x989c,
329 { 0x00000060, 0x00000060, 0x00000060, 0x00000060, 0x00000060 } },
330 { 7, 0x989c,
331 { 0x000000f0, 0x000000f0, 0x000000f0, 0x000000f0, 0x000000f0 } },
332 { 7, 0x989c,
333 { 0x00000022, 0x00000022, 0x00000022, 0x00000022, 0x00000022 } },
334 { 7, 0x989c,
335 { 0x00000092, 0x00000092, 0x00000092, 0x00000092, 0x00000092 } },
336 { 7, 0x989c,
337 { 0x000000d4, 0x000000d4, 0x000000d4, 0x000000d4, 0x000000d4 } },
338 { 7, 0x989c,
339 { 0x000014cc, 0x000014cc, 0x000014cc, 0x000014cc, 0x000014cc } },
340 { 7, 0x989c,
341 { 0x0000048c, 0x0000048c, 0x0000048c, 0x0000048c, 0x0000048c } },
342 { 7, 0x98c4,
343 { 0x00000003, 0x00000003, 0x00000003, 0x00000003, 0x00000003 } },
344};
345
346/* RF5112A mode-specific init registers */
347static const struct ath5k_ini_rf rfregs_5112a[] = {
348 { 1, 0x98d4,
349 /* mode a/XR mode aTurbo mode b mode g mode gTurbo */
350 { 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020 } },
351 { 2, 0x98d0,
352 { 0x03060408, 0x03070408, 0x03060408, 0x03060408, 0x03070408 } },
353 { 3, 0x98dc,
354 { 0x00a0c0c0, 0x00a0c0c0, 0x00e0c0c0, 0x00e0c0c0, 0x00e0c0c0 } },
355 { 6, 0x989c,
356 { 0x0f000000, 0x0f000000, 0x0f000000, 0x0f000000, 0x0f000000 } },
357 { 6, 0x989c,
358 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
359 { 6, 0x989c,
360 { 0x00800000, 0x00800000, 0x00800000, 0x00800000, 0x00800000 } },
361 { 6, 0x989c,
362 { 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000 } },
363 { 6, 0x989c,
364 { 0x00010000, 0x00010000, 0x00010000, 0x00010000, 0x00010000 } },
365 { 6, 0x989c,
366 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
367 { 6, 0x989c,
368 { 0x00180000, 0x00180000, 0x00180000, 0x00180000, 0x00180000 } },
369 { 6, 0x989c,
370 { 0x00600000, 0x00600000, 0x006e0000, 0x006e0000, 0x006e0000 } },
371 { 6, 0x989c,
372 { 0x00c70000, 0x00c70000, 0x00c70000, 0x00c70000, 0x00c70000 } },
373 { 6, 0x989c,
374 { 0x004b0000, 0x004b0000, 0x004b0000, 0x004b0000, 0x004b0000 } },
375 { 6, 0x989c,
376 { 0x04480000, 0x04480000, 0x04480000, 0x04480000, 0x04480000 } },
377 { 6, 0x989c,
378 { 0x00220000, 0x00220000, 0x00220000, 0x00220000, 0x00220000 } },
379 { 6, 0x989c,
380 { 0x00e40000, 0x00e40000, 0x00e40000, 0x00e40000, 0x00e40000 } },
381 { 6, 0x989c,
382 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
383 { 6, 0x989c,
384 { 0x00fc0000, 0x00fc0000, 0x00fc0000, 0x00fc0000, 0x00fc0000 } },
385 { 6, 0x989c,
386 { 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000 } },
387 { 6, 0x989c,
388 { 0x043f0000, 0x043f0000, 0x043f0000, 0x043f0000, 0x043f0000 } },
389 { 6, 0x989c,
390 { 0x000c0000, 0x000c0000, 0x000c0000, 0x000c0000, 0x000c0000 } },
391 { 6, 0x989c,
392 { 0x00190000, 0x00190000, 0x00190000, 0x00190000, 0x00190000 } },
393 { 6, 0x989c,
394 { 0x00240000, 0x00240000, 0x00240000, 0x00240000, 0x00240000 } },
395 { 6, 0x989c,
396 { 0x00b40000, 0x00b40000, 0x00b40000, 0x00b40000, 0x00b40000 } },
397 { 6, 0x989c,
398 { 0x00990000, 0x00990000, 0x00990000, 0x00990000, 0x00990000 } },
399 { 6, 0x989c,
400 { 0x00500000, 0x00500000, 0x00500000, 0x00500000, 0x00500000 } },
401 { 6, 0x989c,
402 { 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000 } },
403 { 6, 0x989c,
404 { 0x00120000, 0x00120000, 0x00120000, 0x00120000, 0x00120000 } },
405 { 6, 0x989c,
406 { 0xc0320000, 0xc0320000, 0xc0320000, 0xc0320000, 0xc0320000 } },
407 { 6, 0x989c,
408 { 0x01740000, 0x01740000, 0x01740000, 0x01740000, 0x01740000 } },
409 { 6, 0x989c,
410 { 0x00110000, 0x00110000, 0x00110000, 0x00110000, 0x00110000 } },
411 { 6, 0x989c,
412 { 0x86280000, 0x86280000, 0x86280000, 0x86280000, 0x86280000 } },
413 { 6, 0x989c,
414 { 0x31840000, 0x31840000, 0x31840000, 0x31840000, 0x31840000 } },
415 { 6, 0x989c,
416 { 0x00020080, 0x00020080, 0x00020080, 0x00020080, 0x00020080 } },
417 { 6, 0x989c,
418 { 0x00080009, 0x00080009, 0x00080009, 0x00080009, 0x00080009 } },
419 { 6, 0x989c,
420 { 0x00000003, 0x00000003, 0x00000003, 0x00000003, 0x00000003 } },
421 { 6, 0x989c,
422 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
423 { 6, 0x989c,
424 { 0x000000b2, 0x000000b2, 0x000000b2, 0x000000b2, 0x000000b2 } },
425 { 6, 0x989c,
426 { 0x00b02084, 0x00b02084, 0x00b02084, 0x00b02084, 0x00b02084 } },
427 { 6, 0x989c,
428 { 0x004125a4, 0x004125a4, 0x004125a4, 0x004125a4, 0x004125a4 } },
429 { 6, 0x989c,
430 { 0x00119220, 0x00119220, 0x00119220, 0x00119220, 0x00119220 } },
431 { 6, 0x989c,
432 { 0x001a4800, 0x001a4800, 0x001a4800, 0x001a4800, 0x001a4800 } },
433 { 6, 0x98d8,
434 { 0x000b0230, 0x000b0230, 0x000b0230, 0x000b0230, 0x000b0230 } },
435 { 7, 0x989c,
436 { 0x00000094, 0x00000094, 0x00000094, 0x00000094, 0x00000094 } },
437 { 7, 0x989c,
438 { 0x00000091, 0x00000091, 0x00000091, 0x00000091, 0x00000091 } },
439 { 7, 0x989c,
440 { 0x00000012, 0x00000012, 0x00000012, 0x00000012, 0x00000012 } },
441 { 7, 0x989c,
442 { 0x00000080, 0x00000080, 0x00000080, 0x00000080, 0x00000080 } },
443 { 7, 0x989c,
444 { 0x000000d9, 0x000000d9, 0x000000d9, 0x000000d9, 0x000000d9 } },
445 { 7, 0x989c,
446 { 0x00000060, 0x00000060, 0x00000060, 0x00000060, 0x00000060 } },
447 { 7, 0x989c,
448 { 0x000000f0, 0x000000f0, 0x000000f0, 0x000000f0, 0x000000f0 } },
449 { 7, 0x989c,
450 { 0x000000a2, 0x000000a2, 0x000000a2, 0x000000a2, 0x000000a2 } },
451 { 7, 0x989c,
452 { 0x00000052, 0x00000052, 0x00000052, 0x00000052, 0x00000052 } },
453 { 7, 0x989c,
454 { 0x000000d4, 0x000000d4, 0x000000d4, 0x000000d4, 0x000000d4 } },
455 { 7, 0x989c,
456 { 0x000014cc, 0x000014cc, 0x000014cc, 0x000014cc, 0x000014cc } },
457 { 7, 0x989c,
458 { 0x0000048c, 0x0000048c, 0x0000048c, 0x0000048c, 0x0000048c } },
459 { 7, 0x98c4,
460 { 0x00000003, 0x00000003, 0x00000003, 0x00000003, 0x00000003 } },
461};
462
463
464static const struct ath5k_ini_rf rfregs_2112a[] = {
465 { 1, AR5K_RF_BUFFER_CONTROL_4,
466 /* mode b mode g mode gTurbo */
467 { 0x00000020, 0x00000020, 0x00000020 } },
468 { 2, AR5K_RF_BUFFER_CONTROL_3,
469 { 0x03060408, 0x03060408, 0x03070408 } },
470 { 3, AR5K_RF_BUFFER_CONTROL_6,
471 { 0x00e020c0, 0x00e020c0, 0x00e020c0 } },
472 { 6, AR5K_RF_BUFFER,
473 { 0x0a000000, 0x0a000000, 0x0a000000 } },
474 { 6, AR5K_RF_BUFFER,
475 { 0x00000000, 0x00000000, 0x00000000 } },
476 { 6, AR5K_RF_BUFFER,
477 { 0x00800000, 0x00800000, 0x00800000 } },
478 { 6, AR5K_RF_BUFFER,
479 { 0x002a0000, 0x002a0000, 0x002a0000 } },
480 { 6, AR5K_RF_BUFFER,
481 { 0x00010000, 0x00010000, 0x00010000 } },
482 { 6, AR5K_RF_BUFFER,
483 { 0x00000000, 0x00000000, 0x00000000 } },
484 { 6, AR5K_RF_BUFFER,
485 { 0x00180000, 0x00180000, 0x00180000 } },
486 { 6, AR5K_RF_BUFFER,
487 { 0x006e0000, 0x006e0000, 0x006e0000 } },
488 { 6, AR5K_RF_BUFFER,
489 { 0x00c70000, 0x00c70000, 0x00c70000 } },
490 { 6, AR5K_RF_BUFFER,
491 { 0x004b0000, 0x004b0000, 0x004b0000 } },
492 { 6, AR5K_RF_BUFFER,
493 { 0x04480000, 0x04480000, 0x04480000 } },
494 { 6, AR5K_RF_BUFFER,
495 { 0x002a0000, 0x002a0000, 0x002a0000 } },
496 { 6, AR5K_RF_BUFFER,
497 { 0x00e40000, 0x00e40000, 0x00e40000 } },
498 { 6, AR5K_RF_BUFFER,
499 { 0x00000000, 0x00000000, 0x00000000 } },
500 { 6, AR5K_RF_BUFFER,
501 { 0x00fc0000, 0x00fc0000, 0x00fc0000 } },
502 { 6, AR5K_RF_BUFFER,
503 { 0x00ff0000, 0x00ff0000, 0x00ff0000 } },
504 { 6, AR5K_RF_BUFFER,
505 { 0x043f0000, 0x043f0000, 0x043f0000 } },
506 { 6, AR5K_RF_BUFFER,
507 { 0x0c0c0000, 0x0c0c0000, 0x0c0c0000 } },
508 { 6, AR5K_RF_BUFFER,
509 { 0x02190000, 0x02190000, 0x02190000 } },
510 { 6, AR5K_RF_BUFFER,
511 { 0x00240000, 0x00240000, 0x00240000 } },
512 { 6, AR5K_RF_BUFFER,
513 { 0x00b40000, 0x00b40000, 0x00b40000 } },
514 { 6, AR5K_RF_BUFFER,
515 { 0x00990000, 0x00990000, 0x00990000 } },
516 { 6, AR5K_RF_BUFFER,
517 { 0x00500000, 0x00500000, 0x00500000 } },
518 { 6, AR5K_RF_BUFFER,
519 { 0x002a0000, 0x002a0000, 0x002a0000 } },
520 { 6, AR5K_RF_BUFFER,
521 { 0x00120000, 0x00120000, 0x00120000 } },
522 { 6, AR5K_RF_BUFFER,
523 { 0xc0320000, 0xc0320000, 0xc0320000 } },
524 { 6, AR5K_RF_BUFFER,
525 { 0x01740000, 0x01740000, 0x01740000 } },
526 { 6, AR5K_RF_BUFFER,
527 { 0x00110000, 0x00110000, 0x00110000 } },
528 { 6, AR5K_RF_BUFFER,
529 { 0x86280000, 0x86280000, 0x86280000 } },
530 { 6, AR5K_RF_BUFFER,
531 { 0x31840000, 0x31840000, 0x31840000 } },
532 { 6, AR5K_RF_BUFFER,
533 { 0x00f20080, 0x00f20080, 0x00f20080 } },
534 { 6, AR5K_RF_BUFFER,
535 { 0x00070019, 0x00070019, 0x00070019 } },
536 { 6, AR5K_RF_BUFFER,
537 { 0x00000000, 0x00000000, 0x00000000 } },
538 { 6, AR5K_RF_BUFFER,
539 { 0x00000000, 0x00000000, 0x00000000 } },
540 { 6, AR5K_RF_BUFFER,
541 { 0x000000b2, 0x000000b2, 0x000000b2 } },
542 { 6, AR5K_RF_BUFFER,
543 { 0x00b02184, 0x00b02184, 0x00b02184 } },
544 { 6, AR5K_RF_BUFFER,
545 { 0x004125a4, 0x004125a4, 0x004125a4 } },
546 { 6, AR5K_RF_BUFFER,
547 { 0x00119220, 0x00119220, 0x00119220 } },
548 { 6, AR5K_RF_BUFFER,
549 { 0x001a4800, 0x001a4800, 0x001a4800 } },
550 { 6, AR5K_RF_BUFFER_CONTROL_5,
551 { 0x000b0230, 0x000b0230, 0x000b0230 } },
552 { 7, AR5K_RF_BUFFER,
553 { 0x00000094, 0x00000094, 0x00000094 } },
554 { 7, AR5K_RF_BUFFER,
555 { 0x00000091, 0x00000091, 0x00000091 } },
556 { 7, AR5K_RF_BUFFER,
557 { 0x00000012, 0x00000012, 0x00000012 } },
558 { 7, AR5K_RF_BUFFER,
559 { 0x00000080, 0x00000080, 0x00000080 } },
560 { 7, AR5K_RF_BUFFER,
561 { 0x000000d9, 0x000000d9, 0x000000d9 } },
562 { 7, AR5K_RF_BUFFER,
563 { 0x00000060, 0x00000060, 0x00000060 } },
564 { 7, AR5K_RF_BUFFER,
565 { 0x000000f0, 0x000000f0, 0x000000f0 } },
566 { 7, AR5K_RF_BUFFER,
567 { 0x000000a2, 0x000000a2, 0x000000a2 } },
568 { 7, AR5K_RF_BUFFER,
569 { 0x00000052, 0x00000052, 0x00000052 } },
570 { 7, AR5K_RF_BUFFER,
571 { 0x000000d4, 0x000000d4, 0x000000d4 } },
572 { 7, AR5K_RF_BUFFER,
573 { 0x000014cc, 0x000014cc, 0x000014cc } },
574 { 7, AR5K_RF_BUFFER,
575 { 0x0000048c, 0x0000048c, 0x0000048c } },
576 { 7, AR5K_RF_BUFFER_CONTROL_1,
577 { 0x00000003, 0x00000003, 0x00000003 } },
578};
579
580/* RF5413/5414 mode-specific init registers */
581static const struct ath5k_ini_rf rfregs_5413[] = {
582 { 1, 0x98d4,
583 /* mode a/XR mode aTurbo mode b mode g mode gTurbo */
584 { 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020 } },
585 { 2, 0x98d0,
586 { 0x00000008, 0x00000008, 0x00000008, 0x00000008, 0x00000008 } },
587 { 3, 0x98dc,
588 { 0x00a000c0, 0x00a000c0, 0x00e000c0, 0x00e000c0, 0x00e000c0 } },
589 { 6, 0x989c,
590 { 0x33000000, 0x33000000, 0x33000000, 0x33000000, 0x33000000 } },
591 { 6, 0x989c,
592 { 0x01000000, 0x01000000, 0x01000000, 0x01000000, 0x01000000 } },
593 { 6, 0x989c,
594 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
595 { 6, 0x989c,
596 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
597 { 6, 0x989c,
598 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
599 { 6, 0x989c,
600 { 0x1f000000, 0x1f000000, 0x1f000000, 0x1f000000, 0x1f000000 } },
601 { 6, 0x989c,
602 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
603 { 6, 0x989c,
604 { 0x00b80000, 0x00b80000, 0x00b80000, 0x00b80000, 0x00b80000 } },
605 { 6, 0x989c,
606 { 0x00b70000, 0x00b70000, 0x00b70000, 0x00b70000, 0x00b70000 } },
607 { 6, 0x989c,
608 { 0x00840000, 0x00840000, 0x00840000, 0x00840000, 0x00840000 } },
609 { 6, 0x989c,
610 { 0x00980000, 0x00980000, 0x00980000, 0x00980000, 0x00980000 } },
611 { 6, 0x989c,
612 { 0x00c00000, 0x00c00000, 0x00c00000, 0x00c00000, 0x00c00000 } },
613 { 6, 0x989c,
614 { 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000 } },
615 { 6, 0x989c,
616 { 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000 } },
617 { 6, 0x989c,
618 { 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000 } },
619 { 6, 0x989c,
620 { 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000 } },
621 { 6, 0x989c,
622 { 0x00d70000, 0x00d70000, 0x00d70000, 0x00d70000, 0x00d70000 } },
623 { 6, 0x989c,
624 { 0x00610000, 0x00610000, 0x00610000, 0x00610000, 0x00610000 } },
625 { 6, 0x989c,
626 { 0x00fe0000, 0x00fe0000, 0x00fe0000, 0x00fe0000, 0x00fe0000 } },
627 { 6, 0x989c,
628 { 0x00de0000, 0x00de0000, 0x00de0000, 0x00de0000, 0x00de0000 } },
629 { 6, 0x989c,
630 { 0x007f0000, 0x007f0000, 0x007f0000, 0x007f0000, 0x007f0000 } },
631 { 6, 0x989c,
632 { 0x043d0000, 0x043d0000, 0x043d0000, 0x043d0000, 0x043d0000 } },
633 { 6, 0x989c,
634 { 0x00770000, 0x00770000, 0x00770000, 0x00770000, 0x00770000 } },
635 { 6, 0x989c,
636 { 0x00440000, 0x00440000, 0x00440000, 0x00440000, 0x00440000 } },
637 { 6, 0x989c,
638 { 0x00980000, 0x00980000, 0x00980000, 0x00980000, 0x00980000 } },
639 { 6, 0x989c,
640 { 0x00100080, 0x00100080, 0x00100080, 0x00100080, 0x00100080 } },
641 { 6, 0x989c,
642 { 0x0005c034, 0x0005c034, 0x0005c034, 0x0005c034, 0x0005c034 } },
643 { 6, 0x989c,
644 { 0x003100f0, 0x003100f0, 0x003100f0, 0x003100f0, 0x003100f0 } },
645 { 6, 0x989c,
646 { 0x000c011f, 0x000c011f, 0x000c011f, 0x000c011f, 0x000c011f } },
647 { 6, 0x989c,
648 { 0x00510040, 0x00510040, 0x005100a0, 0x005100a0, 0x005100a0 } },
649 { 6, 0x989c,
650 { 0x0050006a, 0x0050006a, 0x005000dd, 0x005000dd, 0x005000dd } },
651 { 6, 0x989c,
652 { 0x00000001, 0x00000001, 0x00000000, 0x00000000, 0x00000000 } },
653 { 6, 0x989c,
654 { 0x00004044, 0x00004044, 0x00004044, 0x00004044, 0x00004044 } },
655 { 6, 0x989c,
656 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
657 { 6, 0x989c,
658 { 0x000060c0, 0x000060c0, 0x000060c0, 0x000060c0, 0x000060c0 } },
659 { 6, 0x989c,
660 { 0x00002c00, 0x00002c00, 0x00003600, 0x00003600, 0x00003600 } },
661 { 6, 0x98c8,
662 { 0x00000403, 0x00000403, 0x00040403, 0x00040403, 0x00040403 } },
663 { 7, 0x989c,
664 { 0x00006400, 0x00006400, 0x00006400, 0x00006400, 0x00006400 } },
665 { 7, 0x989c,
666 { 0x00000800, 0x00000800, 0x00000800, 0x00000800, 0x00000800 } },
667 { 7, 0x98cc,
668 { 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e } },
669};
670
671/* RF2413/2414 mode-specific init registers */
672static const struct ath5k_ini_rf rfregs_2413[] = {
673 { 1, AR5K_RF_BUFFER_CONTROL_4,
674 /* mode b mode g mode gTurbo */
675 { 0x00000020, 0x00000020, 0x00000020 } },
676 { 2, AR5K_RF_BUFFER_CONTROL_3,
677 { 0x02001408, 0x02001408, 0x02001408 } },
678 { 3, AR5K_RF_BUFFER_CONTROL_6,
679 { 0x00e020c0, 0x00e020c0, 0x00e020c0 } },
680 { 6, AR5K_RF_BUFFER,
681 { 0xf0000000, 0xf0000000, 0xf0000000 } },
682 { 6, AR5K_RF_BUFFER,
683 { 0x00000000, 0x00000000, 0x00000000 } },
684 { 6, AR5K_RF_BUFFER,
685 { 0x03000000, 0x03000000, 0x03000000 } },
686 { 6, AR5K_RF_BUFFER,
687 { 0x00000000, 0x00000000, 0x00000000 } },
688 { 6, AR5K_RF_BUFFER,
689 { 0x00000000, 0x00000000, 0x00000000 } },
690 { 6, AR5K_RF_BUFFER,
691 { 0x00000000, 0x00000000, 0x00000000 } },
692 { 6, AR5K_RF_BUFFER,
693 { 0x00000000, 0x00000000, 0x00000000 } },
694 { 6, AR5K_RF_BUFFER,
695 { 0x00000000, 0x00000000, 0x00000000 } },
696 { 6, AR5K_RF_BUFFER,
697 { 0x40400000, 0x40400000, 0x40400000 } },
698 { 6, AR5K_RF_BUFFER,
699 { 0x65050000, 0x65050000, 0x65050000 } },
700 { 6, AR5K_RF_BUFFER,
701 { 0x00000000, 0x00000000, 0x00000000 } },
702 { 6, AR5K_RF_BUFFER,
703 { 0x00000000, 0x00000000, 0x00000000 } },
704 { 6, AR5K_RF_BUFFER,
705 { 0x00420000, 0x00420000, 0x00420000 } },
706 { 6, AR5K_RF_BUFFER,
707 { 0x00b50000, 0x00b50000, 0x00b50000 } },
708 { 6, AR5K_RF_BUFFER,
709 { 0x00030000, 0x00030000, 0x00030000 } },
710 { 6, AR5K_RF_BUFFER,
711 { 0x00f70000, 0x00f70000, 0x00f70000 } },
712 { 6, AR5K_RF_BUFFER,
713 { 0x009d0000, 0x009d0000, 0x009d0000 } },
714 { 6, AR5K_RF_BUFFER,
715 { 0x00220000, 0x00220000, 0x00220000 } },
716 { 6, AR5K_RF_BUFFER,
717 { 0x04220000, 0x04220000, 0x04220000 } },
718 { 6, AR5K_RF_BUFFER,
719 { 0x00230018, 0x00230018, 0x00230018 } },
720 { 6, AR5K_RF_BUFFER,
721 { 0x00280050, 0x00280050, 0x00280050 } },
722 { 6, AR5K_RF_BUFFER,
723 { 0x005000c3, 0x005000c3, 0x005000c3 } },
724 { 6, AR5K_RF_BUFFER,
725 { 0x0004007f, 0x0004007f, 0x0004007f } },
726 { 6, AR5K_RF_BUFFER,
727 { 0x00000458, 0x00000458, 0x00000458 } },
728 { 6, AR5K_RF_BUFFER,
729 { 0x00000000, 0x00000000, 0x00000000 } },
730 { 6, AR5K_RF_BUFFER,
731 { 0x0000c000, 0x0000c000, 0x0000c000 } },
732 { 6, AR5K_RF_BUFFER_CONTROL_5,
733 { 0x00400230, 0x00400230, 0x00400230 } },
734 { 7, AR5K_RF_BUFFER,
735 { 0x00006400, 0x00006400, 0x00006400 } },
736 { 7, AR5K_RF_BUFFER,
737 { 0x00000800, 0x00000800, 0x00000800 } },
738 { 7, AR5K_RF_BUFFER_CONTROL_2,
739 { 0x0000000e, 0x0000000e, 0x0000000e } },
740};
741
742/* RF2425 mode-specific init registers */
743static const struct ath5k_ini_rf rfregs_2425[] = {
744 { 1, AR5K_RF_BUFFER_CONTROL_4,
745 /* mode g mode gTurbo */
746 { 0x00000020, 0x00000020 } },
747 { 2, AR5K_RF_BUFFER_CONTROL_3,
748 { 0x02001408, 0x02001408 } },
749 { 3, AR5K_RF_BUFFER_CONTROL_6,
750 { 0x00e020c0, 0x00e020c0 } },
751 { 6, AR5K_RF_BUFFER,
752 { 0x10000000, 0x10000000 } },
753 { 6, AR5K_RF_BUFFER,
754 { 0x00000000, 0x00000000 } },
755 { 6, AR5K_RF_BUFFER,
756 { 0x00000000, 0x00000000 } },
757 { 6, AR5K_RF_BUFFER,
758 { 0x00000000, 0x00000000 } },
759 { 6, AR5K_RF_BUFFER,
760 { 0x00000000, 0x00000000 } },
761 { 6, AR5K_RF_BUFFER,
762 { 0x00000000, 0x00000000 } },
763 { 6, AR5K_RF_BUFFER,
764 { 0x00000000, 0x00000000 } },
765 { 6, AR5K_RF_BUFFER,
766 { 0x00000000, 0x00000000 } },
767 { 6, AR5K_RF_BUFFER,
768 { 0x00000000, 0x00000000 } },
769 { 6, AR5K_RF_BUFFER,
770 { 0x00000000, 0x00000000 } },
771 { 6, AR5K_RF_BUFFER,
772 { 0x00000000, 0x00000000 } },
773 { 6, AR5K_RF_BUFFER,
774 { 0x002a0000, 0x002a0000 } },
775 { 6, AR5K_RF_BUFFER,
776 { 0x00000000, 0x00000000 } },
777 { 6, AR5K_RF_BUFFER,
778 { 0x00000000, 0x00000000 } },
779 { 6, AR5K_RF_BUFFER,
780 { 0x00100000, 0x00100000 } },
781 { 6, AR5K_RF_BUFFER,
782 { 0x00020000, 0x00020000 } },
783 { 6, AR5K_RF_BUFFER,
784 { 0x00730000, 0x00730000 } },
785 { 6, AR5K_RF_BUFFER,
786 { 0x00f80000, 0x00f80000 } },
787 { 6, AR5K_RF_BUFFER,
788 { 0x00e70000, 0x00e70000 } },
789 { 6, AR5K_RF_BUFFER,
790 { 0x00140000, 0x00140000 } },
791 { 6, AR5K_RF_BUFFER,
792 { 0x00910040, 0x00910040 } },
793 { 6, AR5K_RF_BUFFER,
794 { 0x0007001a, 0x0007001a } },
795 { 6, AR5K_RF_BUFFER,
796 { 0x00410000, 0x00410000 } },
797 { 6, AR5K_RF_BUFFER,
798 { 0x00810060, 0x00810060 } },
799 { 6, AR5K_RF_BUFFER,
800 { 0x00020803, 0x00020803 } },
801 { 6, AR5K_RF_BUFFER,
802 { 0x00000000, 0x00000000 } },
803 { 6, AR5K_RF_BUFFER,
804 { 0x00000000, 0x00000000 } },
805 { 6, AR5K_RF_BUFFER,
806 { 0x00001660, 0x00001660 } },
807 { 6, AR5K_RF_BUFFER,
808 { 0x00001688, 0x00001688 } },
809 { 6, AR5K_RF_BUFFER_CONTROL_1,
810 { 0x00000001, 0x00000001 } },
811 { 7, AR5K_RF_BUFFER,
812 { 0x00006400, 0x00006400 } },
813 { 7, AR5K_RF_BUFFER,
814 { 0x00000800, 0x00000800 } },
815 { 7, AR5K_RF_BUFFER_CONTROL_2,
816 { 0x0000000e, 0x0000000e } },
817};
818
819/* Initial RF Gain settings for RF5112 */
820static const struct ath5k_ini_rfgain rfgain_5112[] = {
821 /* 5Ghz 2Ghz */
822 { AR5K_RF_GAIN(0), { 0x00000007, 0x00000007 } },
823 { AR5K_RF_GAIN(1), { 0x00000047, 0x00000047 } },
824 { AR5K_RF_GAIN(2), { 0x00000087, 0x00000087 } },
825 { AR5K_RF_GAIN(3), { 0x000001a0, 0x000001a0 } },
826 { AR5K_RF_GAIN(4), { 0x000001e0, 0x000001e0 } },
827 { AR5K_RF_GAIN(5), { 0x00000020, 0x00000020 } },
828 { AR5K_RF_GAIN(6), { 0x00000060, 0x00000060 } },
829 { AR5K_RF_GAIN(7), { 0x000001a1, 0x000001a1 } },
830 { AR5K_RF_GAIN(8), { 0x000001e1, 0x000001e1 } },
831 { AR5K_RF_GAIN(9), { 0x00000021, 0x00000021 } },
832 { AR5K_RF_GAIN(10), { 0x00000061, 0x00000061 } },
833 { AR5K_RF_GAIN(11), { 0x00000162, 0x00000162 } },
834 { AR5K_RF_GAIN(12), { 0x000001a2, 0x000001a2 } },
835 { AR5K_RF_GAIN(13), { 0x000001e2, 0x000001e2 } },
836 { AR5K_RF_GAIN(14), { 0x00000022, 0x00000022 } },
837 { AR5K_RF_GAIN(15), { 0x00000062, 0x00000062 } },
838 { AR5K_RF_GAIN(16), { 0x00000163, 0x00000163 } },
839 { AR5K_RF_GAIN(17), { 0x000001a3, 0x000001a3 } },
840 { AR5K_RF_GAIN(18), { 0x000001e3, 0x000001e3 } },
841 { AR5K_RF_GAIN(19), { 0x00000023, 0x00000023 } },
842 { AR5K_RF_GAIN(20), { 0x00000063, 0x00000063 } },
843 { AR5K_RF_GAIN(21), { 0x00000184, 0x00000184 } },
844 { AR5K_RF_GAIN(22), { 0x000001c4, 0x000001c4 } },
845 { AR5K_RF_GAIN(23), { 0x00000004, 0x00000004 } },
846 { AR5K_RF_GAIN(24), { 0x000001ea, 0x0000000b } },
847 { AR5K_RF_GAIN(25), { 0x0000002a, 0x0000004b } },
848 { AR5K_RF_GAIN(26), { 0x0000006a, 0x0000008b } },
849 { AR5K_RF_GAIN(27), { 0x000000aa, 0x000001ac } },
850 { AR5K_RF_GAIN(28), { 0x000001ab, 0x000001ec } },
851 { AR5K_RF_GAIN(29), { 0x000001eb, 0x0000002c } },
852 { AR5K_RF_GAIN(30), { 0x0000002b, 0x00000012 } },
853 { AR5K_RF_GAIN(31), { 0x0000006b, 0x00000052 } },
854 { AR5K_RF_GAIN(32), { 0x000000ab, 0x00000092 } },
855 { AR5K_RF_GAIN(33), { 0x000001ac, 0x00000193 } },
856 { AR5K_RF_GAIN(34), { 0x000001ec, 0x000001d3 } },
857 { AR5K_RF_GAIN(35), { 0x0000002c, 0x00000013 } },
858 { AR5K_RF_GAIN(36), { 0x0000003a, 0x00000053 } },
859 { AR5K_RF_GAIN(37), { 0x0000007a, 0x00000093 } },
860 { AR5K_RF_GAIN(38), { 0x000000ba, 0x00000194 } },
861 { AR5K_RF_GAIN(39), { 0x000001bb, 0x000001d4 } },
862 { AR5K_RF_GAIN(40), { 0x000001fb, 0x00000014 } },
863 { AR5K_RF_GAIN(41), { 0x0000003b, 0x0000003a } },
864 { AR5K_RF_GAIN(42), { 0x0000007b, 0x0000007a } },
865 { AR5K_RF_GAIN(43), { 0x000000bb, 0x000000ba } },
866 { AR5K_RF_GAIN(44), { 0x000001bc, 0x000001bb } },
867 { AR5K_RF_GAIN(45), { 0x000001fc, 0x000001fb } },
868 { AR5K_RF_GAIN(46), { 0x0000003c, 0x0000003b } },
869 { AR5K_RF_GAIN(47), { 0x0000007c, 0x0000007b } },
870 { AR5K_RF_GAIN(48), { 0x000000bc, 0x000000bb } },
871 { AR5K_RF_GAIN(49), { 0x000000fc, 0x000001bc } },
872 { AR5K_RF_GAIN(50), { 0x000000fc, 0x000001fc } },
873 { AR5K_RF_GAIN(51), { 0x000000fc, 0x0000003c } },
874 { AR5K_RF_GAIN(52), { 0x000000fc, 0x0000007c } },
875 { AR5K_RF_GAIN(53), { 0x000000fc, 0x000000bc } },
876 { AR5K_RF_GAIN(54), { 0x000000fc, 0x000000fc } },
877 { AR5K_RF_GAIN(55), { 0x000000fc, 0x000000fc } },
878 { AR5K_RF_GAIN(56), { 0x000000fc, 0x000000fc } },
879 { AR5K_RF_GAIN(57), { 0x000000fc, 0x000000fc } },
880 { AR5K_RF_GAIN(58), { 0x000000fc, 0x000000fc } },
881 { AR5K_RF_GAIN(59), { 0x000000fc, 0x000000fc } },
882 { AR5K_RF_GAIN(60), { 0x000000fc, 0x000000fc } },
883 { AR5K_RF_GAIN(61), { 0x000000fc, 0x000000fc } },
884 { AR5K_RF_GAIN(62), { 0x000000fc, 0x000000fc } },
885 { AR5K_RF_GAIN(63), { 0x000000fc, 0x000000fc } },
886};
887
888/* Initial RF Gain settings for RF5413 */
889static const struct ath5k_ini_rfgain rfgain_5413[] = {
890 /* 5Ghz 2Ghz */
891 { AR5K_RF_GAIN(0), { 0x00000000, 0x00000000 } },
892 { AR5K_RF_GAIN(1), { 0x00000040, 0x00000040 } },
893 { AR5K_RF_GAIN(2), { 0x00000080, 0x00000080 } },
894 { AR5K_RF_GAIN(3), { 0x000001a1, 0x00000161 } },
895 { AR5K_RF_GAIN(4), { 0x000001e1, 0x000001a1 } },
896 { AR5K_RF_GAIN(5), { 0x00000021, 0x000001e1 } },
897 { AR5K_RF_GAIN(6), { 0x00000061, 0x00000021 } },
898 { AR5K_RF_GAIN(7), { 0x00000188, 0x00000061 } },
899 { AR5K_RF_GAIN(8), { 0x000001c8, 0x00000188 } },
900 { AR5K_RF_GAIN(9), { 0x00000008, 0x000001c8 } },
901 { AR5K_RF_GAIN(10), { 0x00000048, 0x00000008 } },
902 { AR5K_RF_GAIN(11), { 0x00000088, 0x00000048 } },
903 { AR5K_RF_GAIN(12), { 0x000001a9, 0x00000088 } },
904 { AR5K_RF_GAIN(13), { 0x000001e9, 0x00000169 } },
905 { AR5K_RF_GAIN(14), { 0x00000029, 0x000001a9 } },
906 { AR5K_RF_GAIN(15), { 0x00000069, 0x000001e9 } },
907 { AR5K_RF_GAIN(16), { 0x000001d0, 0x00000029 } },
908 { AR5K_RF_GAIN(17), { 0x00000010, 0x00000069 } },
909 { AR5K_RF_GAIN(18), { 0x00000050, 0x00000190 } },
910 { AR5K_RF_GAIN(19), { 0x00000090, 0x000001d0 } },
911 { AR5K_RF_GAIN(20), { 0x000001b1, 0x00000010 } },
912 { AR5K_RF_GAIN(21), { 0x000001f1, 0x00000050 } },
913 { AR5K_RF_GAIN(22), { 0x00000031, 0x00000090 } },
914 { AR5K_RF_GAIN(23), { 0x00000071, 0x00000171 } },
915 { AR5K_RF_GAIN(24), { 0x000001b8, 0x000001b1 } },
916 { AR5K_RF_GAIN(25), { 0x000001f8, 0x000001f1 } },
917 { AR5K_RF_GAIN(26), { 0x00000038, 0x00000031 } },
918 { AR5K_RF_GAIN(27), { 0x00000078, 0x00000071 } },
919 { AR5K_RF_GAIN(28), { 0x00000199, 0x00000198 } },
920 { AR5K_RF_GAIN(29), { 0x000001d9, 0x000001d8 } },
921 { AR5K_RF_GAIN(30), { 0x00000019, 0x00000018 } },
922 { AR5K_RF_GAIN(31), { 0x00000059, 0x00000058 } },
923 { AR5K_RF_GAIN(32), { 0x00000099, 0x00000098 } },
924 { AR5K_RF_GAIN(33), { 0x000000d9, 0x00000179 } },
925 { AR5K_RF_GAIN(34), { 0x000000f9, 0x000001b9 } },
926 { AR5K_RF_GAIN(35), { 0x000000f9, 0x000001f9 } },
927 { AR5K_RF_GAIN(36), { 0x000000f9, 0x00000039 } },
928 { AR5K_RF_GAIN(37), { 0x000000f9, 0x00000079 } },
929 { AR5K_RF_GAIN(38), { 0x000000f9, 0x000000b9 } },
930 { AR5K_RF_GAIN(39), { 0x000000f9, 0x000000f9 } },
931 { AR5K_RF_GAIN(40), { 0x000000f9, 0x000000f9 } },
932 { AR5K_RF_GAIN(41), { 0x000000f9, 0x000000f9 } },
933 { AR5K_RF_GAIN(42), { 0x000000f9, 0x000000f9 } },
934 { AR5K_RF_GAIN(43), { 0x000000f9, 0x000000f9 } },
935 { AR5K_RF_GAIN(44), { 0x000000f9, 0x000000f9 } },
936 { AR5K_RF_GAIN(45), { 0x000000f9, 0x000000f9 } },
937 { AR5K_RF_GAIN(46), { 0x000000f9, 0x000000f9 } },
938 { AR5K_RF_GAIN(47), { 0x000000f9, 0x000000f9 } },
939 { AR5K_RF_GAIN(48), { 0x000000f9, 0x000000f9 } },
940 { AR5K_RF_GAIN(49), { 0x000000f9, 0x000000f9 } },
941 { AR5K_RF_GAIN(50), { 0x000000f9, 0x000000f9 } },
942 { AR5K_RF_GAIN(51), { 0x000000f9, 0x000000f9 } },
943 { AR5K_RF_GAIN(52), { 0x000000f9, 0x000000f9 } },
944 { AR5K_RF_GAIN(53), { 0x000000f9, 0x000000f9 } },
945 { AR5K_RF_GAIN(54), { 0x000000f9, 0x000000f9 } },
946 { AR5K_RF_GAIN(55), { 0x000000f9, 0x000000f9 } },
947 { AR5K_RF_GAIN(56), { 0x000000f9, 0x000000f9 } },
948 { AR5K_RF_GAIN(57), { 0x000000f9, 0x000000f9 } },
949 { AR5K_RF_GAIN(58), { 0x000000f9, 0x000000f9 } },
950 { AR5K_RF_GAIN(59), { 0x000000f9, 0x000000f9 } },
951 { AR5K_RF_GAIN(60), { 0x000000f9, 0x000000f9 } },
952 { AR5K_RF_GAIN(61), { 0x000000f9, 0x000000f9 } },
953 { AR5K_RF_GAIN(62), { 0x000000f9, 0x000000f9 } },
954 { AR5K_RF_GAIN(63), { 0x000000f9, 0x000000f9 } },
955};
956
957/* Initial RF Gain settings for RF2413 */
958static const struct ath5k_ini_rfgain rfgain_2413[] = {
959 { AR5K_RF_GAIN(0), { 0x00000000 } },
960 { AR5K_RF_GAIN(1), { 0x00000040 } },
961 { AR5K_RF_GAIN(2), { 0x00000080 } },
962 { AR5K_RF_GAIN(3), { 0x00000181 } },
963 { AR5K_RF_GAIN(4), { 0x000001c1 } },
964 { AR5K_RF_GAIN(5), { 0x00000001 } },
965 { AR5K_RF_GAIN(6), { 0x00000041 } },
966 { AR5K_RF_GAIN(7), { 0x00000081 } },
967 { AR5K_RF_GAIN(8), { 0x00000168 } },
968 { AR5K_RF_GAIN(9), { 0x000001a8 } },
969 { AR5K_RF_GAIN(10), { 0x000001e8 } },
970 { AR5K_RF_GAIN(11), { 0x00000028 } },
971 { AR5K_RF_GAIN(12), { 0x00000068 } },
972 { AR5K_RF_GAIN(13), { 0x00000189 } },
973 { AR5K_RF_GAIN(14), { 0x000001c9 } },
974 { AR5K_RF_GAIN(15), { 0x00000009 } },
975 { AR5K_RF_GAIN(16), { 0x00000049 } },
976 { AR5K_RF_GAIN(17), { 0x00000089 } },
977 { AR5K_RF_GAIN(18), { 0x00000190 } },
978 { AR5K_RF_GAIN(19), { 0x000001d0 } },
979 { AR5K_RF_GAIN(20), { 0x00000010 } },
980 { AR5K_RF_GAIN(21), { 0x00000050 } },
981 { AR5K_RF_GAIN(22), { 0x00000090 } },
982 { AR5K_RF_GAIN(23), { 0x00000191 } },
983 { AR5K_RF_GAIN(24), { 0x000001d1 } },
984 { AR5K_RF_GAIN(25), { 0x00000011 } },
985 { AR5K_RF_GAIN(26), { 0x00000051 } },
986 { AR5K_RF_GAIN(27), { 0x00000091 } },
987 { AR5K_RF_GAIN(28), { 0x00000178 } },
988 { AR5K_RF_GAIN(29), { 0x000001b8 } },
989 { AR5K_RF_GAIN(30), { 0x000001f8 } },
990 { AR5K_RF_GAIN(31), { 0x00000038 } },
991 { AR5K_RF_GAIN(32), { 0x00000078 } },
992 { AR5K_RF_GAIN(33), { 0x00000199 } },
993 { AR5K_RF_GAIN(34), { 0x000001d9 } },
994 { AR5K_RF_GAIN(35), { 0x00000019 } },
995 { AR5K_RF_GAIN(36), { 0x00000059 } },
996 { AR5K_RF_GAIN(37), { 0x00000099 } },
997 { AR5K_RF_GAIN(38), { 0x000000d9 } },
998 { AR5K_RF_GAIN(39), { 0x000000f9 } },
999 { AR5K_RF_GAIN(40), { 0x000000f9 } },
1000 { AR5K_RF_GAIN(41), { 0x000000f9 } },
1001 { AR5K_RF_GAIN(42), { 0x000000f9 } },
1002 { AR5K_RF_GAIN(43), { 0x000000f9 } },
1003 { AR5K_RF_GAIN(44), { 0x000000f9 } },
1004 { AR5K_RF_GAIN(45), { 0x000000f9 } },
1005 { AR5K_RF_GAIN(46), { 0x000000f9 } },
1006 { AR5K_RF_GAIN(47), { 0x000000f9 } },
1007 { AR5K_RF_GAIN(48), { 0x000000f9 } },
1008 { AR5K_RF_GAIN(49), { 0x000000f9 } },
1009 { AR5K_RF_GAIN(50), { 0x000000f9 } },
1010 { AR5K_RF_GAIN(51), { 0x000000f9 } },
1011 { AR5K_RF_GAIN(52), { 0x000000f9 } },
1012 { AR5K_RF_GAIN(53), { 0x000000f9 } },
1013 { AR5K_RF_GAIN(54), { 0x000000f9 } },
1014 { AR5K_RF_GAIN(55), { 0x000000f9 } },
1015 { AR5K_RF_GAIN(56), { 0x000000f9 } },
1016 { AR5K_RF_GAIN(57), { 0x000000f9 } },
1017 { AR5K_RF_GAIN(58), { 0x000000f9 } },
1018 { AR5K_RF_GAIN(59), { 0x000000f9 } },
1019 { AR5K_RF_GAIN(60), { 0x000000f9 } },
1020 { AR5K_RF_GAIN(61), { 0x000000f9 } },
1021 { AR5K_RF_GAIN(62), { 0x000000f9 } },
1022 { AR5K_RF_GAIN(63), { 0x000000f9 } },
1023};
1024
1025/* Initial RF Gain settings for RF2425 */
1026static const struct ath5k_ini_rfgain rfgain_2425[] = {
1027 { AR5K_RF_GAIN(0), { 0x00000000 } },
1028 { AR5K_RF_GAIN(1), { 0x00000040 } },
1029 { AR5K_RF_GAIN(2), { 0x00000080 } },
1030 { AR5K_RF_GAIN(3), { 0x00000181 } },
1031 { AR5K_RF_GAIN(4), { 0x000001c1 } },
1032 { AR5K_RF_GAIN(5), { 0x00000001 } },
1033 { AR5K_RF_GAIN(6), { 0x00000041 } },
1034 { AR5K_RF_GAIN(7), { 0x00000081 } },
1035 { AR5K_RF_GAIN(8), { 0x00000188 } },
1036 { AR5K_RF_GAIN(9), { 0x000001c8 } },
1037 { AR5K_RF_GAIN(10), { 0x00000008 } },
1038 { AR5K_RF_GAIN(11), { 0x00000048 } },
1039 { AR5K_RF_GAIN(12), { 0x00000088 } },
1040 { AR5K_RF_GAIN(13), { 0x00000189 } },
1041 { AR5K_RF_GAIN(14), { 0x000001c9 } },
1042 { AR5K_RF_GAIN(15), { 0x00000009 } },
1043 { AR5K_RF_GAIN(16), { 0x00000049 } },
1044 { AR5K_RF_GAIN(17), { 0x00000089 } },
1045 { AR5K_RF_GAIN(18), { 0x000001b0 } },
1046 { AR5K_RF_GAIN(19), { 0x000001f0 } },
1047 { AR5K_RF_GAIN(20), { 0x00000030 } },
1048 { AR5K_RF_GAIN(21), { 0x00000070 } },
1049 { AR5K_RF_GAIN(22), { 0x00000171 } },
1050 { AR5K_RF_GAIN(23), { 0x000001b1 } },
1051 { AR5K_RF_GAIN(24), { 0x000001f1 } },
1052 { AR5K_RF_GAIN(25), { 0x00000031 } },
1053 { AR5K_RF_GAIN(26), { 0x00000071 } },
1054 { AR5K_RF_GAIN(27), { 0x000001b8 } },
1055 { AR5K_RF_GAIN(28), { 0x000001f8 } },
1056 { AR5K_RF_GAIN(29), { 0x00000038 } },
1057 { AR5K_RF_GAIN(30), { 0x00000078 } },
1058 { AR5K_RF_GAIN(31), { 0x000000b8 } },
1059 { AR5K_RF_GAIN(32), { 0x000001b9 } },
1060 { AR5K_RF_GAIN(33), { 0x000001f9 } },
1061 { AR5K_RF_GAIN(34), { 0x00000039 } },
1062 { AR5K_RF_GAIN(35), { 0x00000079 } },
1063 { AR5K_RF_GAIN(36), { 0x000000b9 } },
1064 { AR5K_RF_GAIN(37), { 0x000000f9 } },
1065 { AR5K_RF_GAIN(38), { 0x000000f9 } },
1066 { AR5K_RF_GAIN(39), { 0x000000f9 } },
1067 { AR5K_RF_GAIN(40), { 0x000000f9 } },
1068 { AR5K_RF_GAIN(41), { 0x000000f9 } },
1069 { AR5K_RF_GAIN(42), { 0x000000f9 } },
1070 { AR5K_RF_GAIN(43), { 0x000000f9 } },
1071 { AR5K_RF_GAIN(44), { 0x000000f9 } },
1072 { AR5K_RF_GAIN(45), { 0x000000f9 } },
1073 { AR5K_RF_GAIN(46), { 0x000000f9 } },
1074 { AR5K_RF_GAIN(47), { 0x000000f9 } },
1075 { AR5K_RF_GAIN(48), { 0x000000f9 } },
1076 { AR5K_RF_GAIN(49), { 0x000000f9 } },
1077 { AR5K_RF_GAIN(50), { 0x000000f9 } },
1078 { AR5K_RF_GAIN(51), { 0x000000f9 } },
1079 { AR5K_RF_GAIN(52), { 0x000000f9 } },
1080 { AR5K_RF_GAIN(53), { 0x000000f9 } },
1081 { AR5K_RF_GAIN(54), { 0x000000f9 } },
1082 { AR5K_RF_GAIN(55), { 0x000000f9 } },
1083 { AR5K_RF_GAIN(56), { 0x000000f9 } },
1084 { AR5K_RF_GAIN(57), { 0x000000f9 } },
1085 { AR5K_RF_GAIN(58), { 0x000000f9 } },
1086 { AR5K_RF_GAIN(59), { 0x000000f9 } },
1087 { AR5K_RF_GAIN(60), { 0x000000f9 } },
1088 { AR5K_RF_GAIN(61), { 0x000000f9 } },
1089 { AR5K_RF_GAIN(62), { 0x000000f9 } },
1090 { AR5K_RF_GAIN(63), { 0x000000f9 } },
1091};
1092
1093static const struct ath5k_gain_opt rfgain_opt_5112 = {
1094 1,
1095 8,
1096 {
1097 { { 3, 0, 0, 0, 0, 0, 0 }, 6 },
1098 { { 2, 0, 0, 0, 0, 0, 0 }, 0 },
1099 { { 1, 0, 0, 0, 0, 0, 0 }, -3 },
1100 { { 0, 0, 0, 0, 0, 0, 0 }, -6 },
1101 { { 0, 1, 1, 0, 0, 0, 0 }, -8 },
1102 { { 0, 1, 1, 0, 1, 1, 0 }, -10 },
1103 { { 0, 1, 0, 1, 1, 1, 0 }, -13 },
1104 { { 0, 1, 0, 1, 1, 0, 1 }, -16 },
1105 }
1106};
1107 31
1108/* 32/*
1109 * Used to modify RF Banks before writing them to AR5K_RF_BUFFER 33 * Used to modify RF Banks before writing them to AR5K_RF_BUFFER
1110 */ 34 */
1111static unsigned int ath5k_hw_rfregs_op(u32 *rf, u32 offset, u32 reg, u32 bits, 35static unsigned int ath5k_hw_rfb_op(struct ath5k_hw *ah,
1112 u32 first, u32 col, bool set) 36 const struct ath5k_rf_reg *rf_regs,
37 u32 val, u8 reg_id, bool set)
1113{ 38{
1114 u32 mask, entry, last, data, shift, position; 39 const struct ath5k_rf_reg *rfreg = NULL;
1115 s32 left; 40 u8 offset, bank, num_bits, col, position;
41 u16 entry;
42 u32 mask, data, last_bit, bits_shifted, first_bit;
43 u32 *rfb;
44 s32 bits_left;
1116 int i; 45 int i;
1117 46
1118 data = 0; 47 data = 0;
48 rfb = ah->ah_rf_banks;
1119 49
1120 if (rf == NULL) 50 for (i = 0; i < ah->ah_rf_regs_count; i++) {
51 if (rf_regs[i].index == reg_id) {
52 rfreg = &rf_regs[i];
53 break;
54 }
55 }
56
57 if (rfb == NULL || rfreg == NULL) {
58 ATH5K_PRINTF("Rf register not found!\n");
1121 /* should not happen */ 59 /* should not happen */
1122 return 0; 60 return 0;
61 }
62
63 bank = rfreg->bank;
64 num_bits = rfreg->field.len;
65 first_bit = rfreg->field.pos;
66 col = rfreg->field.col;
67
68 /* first_bit is an offset from bank's
69 * start. Since we have all banks on
70 * the same array, we use this offset
71 * to mark each bank's start */
72 offset = ah->ah_offset[bank];
1123 73
1124 if (!(col <= 3 && bits <= 32 && first + bits <= 319)) { 74 /* Boundary check */
75 if (!(col <= 3 && num_bits <= 32 && first_bit + num_bits <= 319)) {
1125 ATH5K_PRINTF("invalid values at offset %u\n", offset); 76 ATH5K_PRINTF("invalid values at offset %u\n", offset);
1126 return 0; 77 return 0;
1127 } 78 }
1128 79
1129 entry = ((first - 1) / 8) + offset; 80 entry = ((first_bit - 1) / 8) + offset;
1130 position = (first - 1) % 8; 81 position = (first_bit - 1) % 8;
1131 82
1132 if (set) 83 if (set)
1133 data = ath5k_hw_bitswap(reg, bits); 84 data = ath5k_hw_bitswap(val, num_bits);
85
86 for (bits_shifted = 0, bits_left = num_bits; bits_left > 0;
87 position = 0, entry++) {
88
89 last_bit = (position + bits_left > 8) ? 8 :
90 position + bits_left;
1134 91
1135 for (i = shift = 0, left = bits; left > 0; position = 0, entry++, i++) { 92 mask = (((1 << last_bit) - 1) ^ ((1 << position) - 1)) <<
1136 last = (position + left > 8) ? 8 : position + left; 93 (col * 8);
1137 mask = (((1 << last) - 1) ^ ((1 << position) - 1)) << (col * 8);
1138 94
1139 if (set) { 95 if (set) {
1140 rf[entry] &= ~mask; 96 rfb[entry] &= ~mask;
1141 rf[entry] |= ((data << position) << (col * 8)) & mask; 97 rfb[entry] |= ((data << position) << (col * 8)) & mask;
1142 data >>= (8 - position); 98 data >>= (8 - position);
1143 } else { 99 } else {
1144 data = (((rf[entry] & mask) >> (col * 8)) >> position) 100 data |= (((rfb[entry] & mask) >> (col * 8)) >> position)
1145 << shift; 101 << bits_shifted;
1146 shift += last - position; 102 bits_shifted += last_bit - position;
1147 } 103 }
1148 104
1149 left -= 8 - position; 105 bits_left -= 8 - position;
1150 } 106 }
1151 107
1152 data = set ? 1 : ath5k_hw_bitswap(data, bits); 108 data = set ? 1 : ath5k_hw_bitswap(data, num_bits);
1153 109
1154 return data; 110 return data;
1155} 111}
1156 112
1157static u32 ath5k_hw_rfregs_gainf_corr(struct ath5k_hw *ah) 113/**********************\
114* RF Gain optimization *
115\**********************/
116
117/*
118 * This code is used to optimize rf gain on different environments
119 * (temprature mostly) based on feedback from a power detector.
120 *
121 * It's only used on RF5111 and RF5112, later RF chips seem to have
122 * auto adjustment on hw -notice they have a much smaller BANK 7 and
123 * no gain optimization ladder-.
124 *
125 * For more infos check out this patent doc
126 * http://www.freepatentsonline.com/7400691.html
127 *
128 * This paper describes power drops as seen on the receiver due to
129 * probe packets
130 * http://www.cnri.dit.ie/publications/ICT08%20-%20Practical%20Issues
131 * %20of%20Power%20Control.pdf
132 *
133 * And this is the MadWiFi bug entry related to the above
134 * http://madwifi-project.org/ticket/1659
135 * with various measurements and diagrams
136 *
137 * TODO: Deal with power drops due to probes by setting an apropriate
138 * tx power on the probe packets ! Make this part of the calibration process.
139 */
140
141/* Initialize ah_gain durring attach */
142int ath5k_hw_rfgain_opt_init(struct ath5k_hw *ah)
143{
144 /* Initialize the gain optimization values */
145 switch (ah->ah_radio) {
146 case AR5K_RF5111:
147 ah->ah_gain.g_step_idx = rfgain_opt_5111.go_default;
148 ah->ah_gain.g_low = 20;
149 ah->ah_gain.g_high = 35;
150 ah->ah_gain.g_state = AR5K_RFGAIN_ACTIVE;
151 break;
152 case AR5K_RF5112:
153 ah->ah_gain.g_step_idx = rfgain_opt_5112.go_default;
154 ah->ah_gain.g_low = 20;
155 ah->ah_gain.g_high = 85;
156 ah->ah_gain.g_state = AR5K_RFGAIN_ACTIVE;
157 break;
158 default:
159 return -EINVAL;
160 }
161
162 return 0;
163}
164
165/* Schedule a gain probe check on the next transmited packet.
166 * That means our next packet is going to be sent with lower
167 * tx power and a Peak to Average Power Detector (PAPD) will try
168 * to measure the gain.
169 *
170 * TODO: Use propper tx power setting for the probe packet so
171 * that we don't observe a serious power drop on the receiver
172 *
173 * XXX: How about forcing a tx packet (bypassing PCU arbitrator etc)
174 * just after we enable the probe so that we don't mess with
175 * standard traffic ? Maybe it's time to use sw interrupts and
176 * a probe tasklet !!!
177 */
178static void ath5k_hw_request_rfgain_probe(struct ath5k_hw *ah)
179{
180
181 /* Skip if gain calibration is inactive or
182 * we already handle a probe request */
183 if (ah->ah_gain.g_state != AR5K_RFGAIN_ACTIVE)
184 return;
185
186 ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txpower.txp_max,
187 AR5K_PHY_PAPD_PROBE_TXPOWER) |
188 AR5K_PHY_PAPD_PROBE_TX_NEXT, AR5K_PHY_PAPD_PROBE);
189
190 ah->ah_gain.g_state = AR5K_RFGAIN_READ_REQUESTED;
191
192}
193
194/* Calculate gain_F measurement correction
195 * based on the current step for RF5112 rev. 2 */
196static u32 ath5k_hw_rf_gainf_corr(struct ath5k_hw *ah)
1158{ 197{
1159 u32 mix, step; 198 u32 mix, step;
1160 u32 *rf; 199 u32 *rf;
200 const struct ath5k_gain_opt *go;
201 const struct ath5k_gain_opt_step *g_step;
202 const struct ath5k_rf_reg *rf_regs;
203
204 /* Only RF5112 Rev. 2 supports it */
205 if ((ah->ah_radio != AR5K_RF5112) ||
206 (ah->ah_radio_5ghz_revision <= AR5K_SREV_RAD_5112A))
207 return 0;
208
209 go = &rfgain_opt_5112;
210 rf_regs = rf_regs_5112a;
211 ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_5112a);
212
213 g_step = &go->go_step[ah->ah_gain.g_step_idx];
1161 214
1162 if (ah->ah_rf_banks == NULL) 215 if (ah->ah_rf_banks == NULL)
1163 return 0; 216 return 0;
@@ -1165,11 +218,15 @@ static u32 ath5k_hw_rfregs_gainf_corr(struct ath5k_hw *ah)
1165 rf = ah->ah_rf_banks; 218 rf = ah->ah_rf_banks;
1166 ah->ah_gain.g_f_corr = 0; 219 ah->ah_gain.g_f_corr = 0;
1167 220
1168 if (ath5k_hw_rfregs_op(rf, ah->ah_offset[7], 0, 1, 36, 0, false) != 1) 221 /* No VGA (Variable Gain Amplifier) override, skip */
222 if (ath5k_hw_rfb_op(ah, rf_regs, 0, AR5K_RF_MIXVGA_OVR, false) != 1)
1169 return 0; 223 return 0;
1170 224
1171 step = ath5k_hw_rfregs_op(rf, ah->ah_offset[7], 0, 4, 32, 0, false); 225 /* Mix gain stepping */
1172 mix = ah->ah_gain.g_step->gos_param[0]; 226 step = ath5k_hw_rfb_op(ah, rf_regs, 0, AR5K_RF_MIXGAIN_STEP, false);
227
228 /* Mix gain override */
229 mix = g_step->gos_param[0];
1173 230
1174 switch (mix) { 231 switch (mix) {
1175 case 3: 232 case 3:
@@ -1189,9 +246,14 @@ static u32 ath5k_hw_rfregs_gainf_corr(struct ath5k_hw *ah)
1189 return ah->ah_gain.g_f_corr; 246 return ah->ah_gain.g_f_corr;
1190} 247}
1191 248
1192static bool ath5k_hw_rfregs_gain_readback(struct ath5k_hw *ah) 249/* Check if current gain_F measurement is in the range of our
250 * power detector windows. If we get a measurement outside range
251 * we know it's not accurate (detectors can't measure anything outside
252 * their detection window) so we must ignore it */
253static bool ath5k_hw_rf_check_gainf_readback(struct ath5k_hw *ah)
1193{ 254{
1194 u32 step, mix, level[4]; 255 const struct ath5k_rf_reg *rf_regs;
256 u32 step, mix_ovr, level[4];
1195 u32 *rf; 257 u32 *rf;
1196 258
1197 if (ah->ah_rf_banks == NULL) 259 if (ah->ah_rf_banks == NULL)
@@ -1200,23 +262,33 @@ static bool ath5k_hw_rfregs_gain_readback(struct ath5k_hw *ah)
1200 rf = ah->ah_rf_banks; 262 rf = ah->ah_rf_banks;
1201 263
1202 if (ah->ah_radio == AR5K_RF5111) { 264 if (ah->ah_radio == AR5K_RF5111) {
1203 step = ath5k_hw_rfregs_op(rf, ah->ah_offset[7], 0, 6, 37, 0, 265
1204 false); 266 rf_regs = rf_regs_5111;
267 ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_5111);
268
269 step = ath5k_hw_rfb_op(ah, rf_regs, 0, AR5K_RF_RFGAIN_STEP,
270 false);
271
1205 level[0] = 0; 272 level[0] = 0;
1206 level[1] = (step == 0x3f) ? 0x32 : step + 4; 273 level[1] = (step == 63) ? 50 : step + 4;
1207 level[2] = (step != 0x3f) ? 0x40 : level[0]; 274 level[2] = (step != 63) ? 64 : level[0];
1208 level[3] = level[2] + 0x32; 275 level[3] = level[2] + 50 ;
1209 276
1210 ah->ah_gain.g_high = level[3] - 277 ah->ah_gain.g_high = level[3] -
1211 (step == 0x3f ? AR5K_GAIN_DYN_ADJUST_HI_MARGIN : -5); 278 (step == 63 ? AR5K_GAIN_DYN_ADJUST_HI_MARGIN : -5);
1212 ah->ah_gain.g_low = level[0] + 279 ah->ah_gain.g_low = level[0] +
1213 (step == 0x3f ? AR5K_GAIN_DYN_ADJUST_LO_MARGIN : 0); 280 (step == 63 ? AR5K_GAIN_DYN_ADJUST_LO_MARGIN : 0);
1214 } else { 281 } else {
1215 mix = ath5k_hw_rfregs_op(rf, ah->ah_offset[7], 0, 1, 36, 0, 282
1216 false); 283 rf_regs = rf_regs_5112;
284 ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_5112);
285
286 mix_ovr = ath5k_hw_rfb_op(ah, rf_regs, 0, AR5K_RF_MIXVGA_OVR,
287 false);
288
1217 level[0] = level[2] = 0; 289 level[0] = level[2] = 0;
1218 290
1219 if (mix == 1) { 291 if (mix_ovr == 1) {
1220 level[1] = level[3] = 83; 292 level[1] = level[3] = 83;
1221 } else { 293 } else {
1222 level[1] = level[3] = 107; 294 level[1] = level[3] = 107;
@@ -1230,9 +302,12 @@ static bool ath5k_hw_rfregs_gain_readback(struct ath5k_hw *ah)
1230 ah->ah_gain.g_current <= level[3]); 302 ah->ah_gain.g_current <= level[3]);
1231} 303}
1232 304
1233static s32 ath5k_hw_rfregs_gain_adjust(struct ath5k_hw *ah) 305/* Perform gain_F adjustment by choosing the right set
306 * of parameters from rf gain optimization ladder */
307static s8 ath5k_hw_rf_gainf_adjust(struct ath5k_hw *ah)
1234{ 308{
1235 const struct ath5k_gain_opt *go; 309 const struct ath5k_gain_opt *go;
310 const struct ath5k_gain_opt_step *g_step;
1236 int ret = 0; 311 int ret = 0;
1237 312
1238 switch (ah->ah_radio) { 313 switch (ah->ah_radio) {
@@ -1246,35 +321,39 @@ static s32 ath5k_hw_rfregs_gain_adjust(struct ath5k_hw *ah)
1246 return 0; 321 return 0;
1247 } 322 }
1248 323
1249 ah->ah_gain.g_step = &go->go_step[ah->ah_gain.g_step_idx]; 324 g_step = &go->go_step[ah->ah_gain.g_step_idx];
1250 325
1251 if (ah->ah_gain.g_current >= ah->ah_gain.g_high) { 326 if (ah->ah_gain.g_current >= ah->ah_gain.g_high) {
327
328 /* Reached maximum */
1252 if (ah->ah_gain.g_step_idx == 0) 329 if (ah->ah_gain.g_step_idx == 0)
1253 return -1; 330 return -1;
331
1254 for (ah->ah_gain.g_target = ah->ah_gain.g_current; 332 for (ah->ah_gain.g_target = ah->ah_gain.g_current;
1255 ah->ah_gain.g_target >= ah->ah_gain.g_high && 333 ah->ah_gain.g_target >= ah->ah_gain.g_high &&
1256 ah->ah_gain.g_step_idx > 0; 334 ah->ah_gain.g_step_idx > 0;
1257 ah->ah_gain.g_step = 335 g_step = &go->go_step[ah->ah_gain.g_step_idx])
1258 &go->go_step[ah->ah_gain.g_step_idx])
1259 ah->ah_gain.g_target -= 2 * 336 ah->ah_gain.g_target -= 2 *
1260 (go->go_step[--(ah->ah_gain.g_step_idx)].gos_gain - 337 (go->go_step[--(ah->ah_gain.g_step_idx)].gos_gain -
1261 ah->ah_gain.g_step->gos_gain); 338 g_step->gos_gain);
1262 339
1263 ret = 1; 340 ret = 1;
1264 goto done; 341 goto done;
1265 } 342 }
1266 343
1267 if (ah->ah_gain.g_current <= ah->ah_gain.g_low) { 344 if (ah->ah_gain.g_current <= ah->ah_gain.g_low) {
345
346 /* Reached minimum */
1268 if (ah->ah_gain.g_step_idx == (go->go_steps_count - 1)) 347 if (ah->ah_gain.g_step_idx == (go->go_steps_count - 1))
1269 return -2; 348 return -2;
349
1270 for (ah->ah_gain.g_target = ah->ah_gain.g_current; 350 for (ah->ah_gain.g_target = ah->ah_gain.g_current;
1271 ah->ah_gain.g_target <= ah->ah_gain.g_low && 351 ah->ah_gain.g_target <= ah->ah_gain.g_low &&
1272 ah->ah_gain.g_step_idx < go->go_steps_count-1; 352 ah->ah_gain.g_step_idx < go->go_steps_count-1;
1273 ah->ah_gain.g_step = 353 g_step = &go->go_step[ah->ah_gain.g_step_idx])
1274 &go->go_step[ah->ah_gain.g_step_idx])
1275 ah->ah_gain.g_target -= 2 * 354 ah->ah_gain.g_target -= 2 *
1276 (go->go_step[++ah->ah_gain.g_step_idx].gos_gain - 355 (go->go_step[++ah->ah_gain.g_step_idx].gos_gain -
1277 ah->ah_gain.g_step->gos_gain); 356 g_step->gos_gain);
1278 357
1279 ret = 2; 358 ret = 2;
1280 goto done; 359 goto done;
@@ -1289,468 +368,449 @@ done:
1289 return ret; 368 return ret;
1290} 369}
1291 370
1292/* 371/* Main callback for thermal rf gain calibration engine
1293 * Read EEPROM Calibration data, modify RF Banks and Initialize RF5111 372 * Check for a new gain reading and schedule an adjustment
1294 */ 373 * if needed.
1295static int ath5k_hw_rf5111_rfregs(struct ath5k_hw *ah, 374 *
1296 struct ieee80211_channel *channel, unsigned int mode) 375 * TODO: Use sw interrupt to schedule reset if gain_F needs
376 * adjustment */
377enum ath5k_rfgain ath5k_hw_gainf_calibrate(struct ath5k_hw *ah)
1297{ 378{
379 u32 data, type;
1298 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; 380 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
1299 u32 *rf;
1300 const unsigned int rf_size = ARRAY_SIZE(rfregs_5111);
1301 unsigned int i;
1302 int obdb = -1, bank = -1;
1303 u32 ee_mode;
1304
1305 AR5K_ASSERT_ENTRY(mode, AR5K_MODE_MAX);
1306
1307 rf = ah->ah_rf_banks;
1308 381
1309 /* Copy values to modify them */ 382 ATH5K_TRACE(ah->ah_sc);
1310 for (i = 0; i < rf_size; i++) {
1311 if (rfregs_5111[i].rf_bank >= AR5K_RF5111_INI_RF_MAX_BANKS) {
1312 ATH5K_ERR(ah->ah_sc, "invalid bank\n");
1313 return -EINVAL;
1314 }
1315
1316 if (bank != rfregs_5111[i].rf_bank) {
1317 bank = rfregs_5111[i].rf_bank;
1318 ah->ah_offset[bank] = i;
1319 }
1320 383
1321 rf[i] = rfregs_5111[i].rf_value[mode]; 384 if (ah->ah_rf_banks == NULL ||
1322 } 385 ah->ah_gain.g_state == AR5K_RFGAIN_INACTIVE)
386 return AR5K_RFGAIN_INACTIVE;
1323 387
1324 /* Modify bank 0 */ 388 /* No check requested, either engine is inactive
1325 if (channel->hw_value & CHANNEL_2GHZ) { 389 * or an adjustment is already requested */
1326 if (channel->hw_value & CHANNEL_CCK) 390 if (ah->ah_gain.g_state != AR5K_RFGAIN_READ_REQUESTED)
1327 ee_mode = AR5K_EEPROM_MODE_11B; 391 goto done;
1328 else
1329 ee_mode = AR5K_EEPROM_MODE_11G;
1330 obdb = 0;
1331 392
1332 if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[0], 393 /* Read the PAPD (Peak to Average Power Detector)
1333 ee->ee_ob[ee_mode][obdb], 3, 119, 0, true)) 394 * register */
1334 return -EINVAL; 395 data = ath5k_hw_reg_read(ah, AR5K_PHY_PAPD_PROBE);
1335 396
1336 if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[0], 397 /* No probe is scheduled, read gain_F measurement */
1337 ee->ee_ob[ee_mode][obdb], 3, 122, 0, true)) 398 if (!(data & AR5K_PHY_PAPD_PROBE_TX_NEXT)) {
1338 return -EINVAL; 399 ah->ah_gain.g_current = data >> AR5K_PHY_PAPD_PROBE_GAINF_S;
400 type = AR5K_REG_MS(data, AR5K_PHY_PAPD_PROBE_TYPE);
1339 401
1340 obdb = 1; 402 /* If tx packet is CCK correct the gain_F measurement
1341 /* Modify bank 6 */ 403 * by cck ofdm gain delta */
1342 } else { 404 if (type == AR5K_PHY_PAPD_PROBE_TYPE_CCK) {
1343 /* For 11a, Turbo and XR */ 405 if (ah->ah_radio_5ghz_revision >= AR5K_SREV_RAD_5112A)
1344 ee_mode = AR5K_EEPROM_MODE_11A; 406 ah->ah_gain.g_current +=
1345 obdb = channel->center_freq >= 5725 ? 3 : 407 ee->ee_cck_ofdm_gain_delta;
1346 (channel->center_freq >= 5500 ? 2 : 408 else
1347 (channel->center_freq >= 5260 ? 1 : 409 ah->ah_gain.g_current +=
1348 (channel->center_freq > 4000 ? 0 : -1))); 410 AR5K_GAIN_CCK_PROBE_CORR;
411 }
1349 412
1350 if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[6], 413 /* Further correct gain_F measurement for
1351 ee->ee_pwd_84, 1, 51, 3, true)) 414 * RF5112A radios */
1352 return -EINVAL; 415 if (ah->ah_radio_5ghz_revision >= AR5K_SREV_RAD_5112A) {
416 ath5k_hw_rf_gainf_corr(ah);
417 ah->ah_gain.g_current =
418 ah->ah_gain.g_current >= ah->ah_gain.g_f_corr ?
419 (ah->ah_gain.g_current-ah->ah_gain.g_f_corr) :
420 0;
421 }
1353 422
1354 if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[6], 423 /* Check if measurement is ok and if we need
1355 ee->ee_pwd_90, 1, 45, 3, true)) 424 * to adjust gain, schedule a gain adjustment,
1356 return -EINVAL; 425 * else switch back to the acive state */
426 if (ath5k_hw_rf_check_gainf_readback(ah) &&
427 AR5K_GAIN_CHECK_ADJUST(&ah->ah_gain) &&
428 ath5k_hw_rf_gainf_adjust(ah)) {
429 ah->ah_gain.g_state = AR5K_RFGAIN_NEED_CHANGE;
430 } else {
431 ah->ah_gain.g_state = AR5K_RFGAIN_ACTIVE;
432 }
1357 } 433 }
1358 434
1359 if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[6], 435done:
1360 !ee->ee_xpd[ee_mode], 1, 95, 0, true)) 436 return ah->ah_gain.g_state;
1361 return -EINVAL; 437}
1362
1363 if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[6],
1364 ee->ee_x_gain[ee_mode], 4, 96, 0, true))
1365 return -EINVAL;
1366
1367 if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[6], obdb >= 0 ?
1368 ee->ee_ob[ee_mode][obdb] : 0, 3, 104, 0, true))
1369 return -EINVAL;
1370 438
1371 if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[6], obdb >= 0 ? 439/* Write initial rf gain table to set the RF sensitivity
1372 ee->ee_db[ee_mode][obdb] : 0, 3, 107, 0, true)) 440 * this one works on all RF chips and has nothing to do
1373 return -EINVAL; 441 * with gain_F calibration */
442int ath5k_hw_rfgain_init(struct ath5k_hw *ah, unsigned int freq)
443{
444 const struct ath5k_ini_rfgain *ath5k_rfg;
445 unsigned int i, size;
1374 446
1375 /* Modify bank 7 */ 447 switch (ah->ah_radio) {
1376 if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[7], 448 case AR5K_RF5111:
1377 ee->ee_i_gain[ee_mode], 6, 29, 0, true)) 449 ath5k_rfg = rfgain_5111;
450 size = ARRAY_SIZE(rfgain_5111);
451 break;
452 case AR5K_RF5112:
453 ath5k_rfg = rfgain_5112;
454 size = ARRAY_SIZE(rfgain_5112);
455 break;
456 case AR5K_RF2413:
457 ath5k_rfg = rfgain_2413;
458 size = ARRAY_SIZE(rfgain_2413);
459 break;
460 case AR5K_RF2316:
461 ath5k_rfg = rfgain_2316;
462 size = ARRAY_SIZE(rfgain_2316);
463 break;
464 case AR5K_RF5413:
465 ath5k_rfg = rfgain_5413;
466 size = ARRAY_SIZE(rfgain_5413);
467 break;
468 case AR5K_RF2317:
469 case AR5K_RF2425:
470 ath5k_rfg = rfgain_2425;
471 size = ARRAY_SIZE(rfgain_2425);
472 break;
473 default:
1378 return -EINVAL; 474 return -EINVAL;
475 }
1379 476
1380 if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[7], 477 switch (freq) {
1381 ee->ee_xpd[ee_mode], 1, 4, 0, true)) 478 case AR5K_INI_RFGAIN_2GHZ:
479 case AR5K_INI_RFGAIN_5GHZ:
480 break;
481 default:
1382 return -EINVAL; 482 return -EINVAL;
483 }
1383 484
1384 /* Write RF values */ 485 for (i = 0; i < size; i++) {
1385 for (i = 0; i < rf_size; i++) {
1386 AR5K_REG_WAIT(i); 486 AR5K_REG_WAIT(i);
1387 ath5k_hw_reg_write(ah, rf[i], rfregs_5111[i].rf_register); 487 ath5k_hw_reg_write(ah, ath5k_rfg[i].rfg_value[freq],
488 (u32)ath5k_rfg[i].rfg_register);
1388 } 489 }
1389 490
1390 return 0; 491 return 0;
1391} 492}
1392 493
494
495
496/********************\
497* RF Registers setup *
498\********************/
499
500
1393/* 501/*
1394 * Read EEPROM Calibration data, modify RF Banks and Initialize RF5112 502 * Setup RF registers by writing rf buffer on hw
1395 */ 503 */
1396static int ath5k_hw_rf5112_rfregs(struct ath5k_hw *ah, 504int ath5k_hw_rfregs_init(struct ath5k_hw *ah, struct ieee80211_channel *channel,
1397 struct ieee80211_channel *channel, unsigned int mode) 505 unsigned int mode)
1398{ 506{
1399 const struct ath5k_ini_rf *rf_ini; 507 const struct ath5k_rf_reg *rf_regs;
508 const struct ath5k_ini_rfbuffer *ini_rfb;
509 const struct ath5k_gain_opt *go = NULL;
510 const struct ath5k_gain_opt_step *g_step;
1400 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; 511 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
1401 u32 *rf; 512 u8 ee_mode = 0;
1402 unsigned int rf_size, i; 513 u32 *rfb;
1403 int obdb = -1, bank = -1; 514 int i, obdb = -1, bank = -1;
1404 u32 ee_mode;
1405
1406 AR5K_ASSERT_ENTRY(mode, AR5K_MODE_MAX);
1407 515
1408 rf = ah->ah_rf_banks; 516 switch (ah->ah_radio) {
517 case AR5K_RF5111:
518 rf_regs = rf_regs_5111;
519 ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_5111);
520 ini_rfb = rfb_5111;
521 ah->ah_rf_banks_size = ARRAY_SIZE(rfb_5111);
522 go = &rfgain_opt_5111;
523 break;
524 case AR5K_RF5112:
525 if (ah->ah_radio_5ghz_revision >= AR5K_SREV_RAD_5112A) {
526 rf_regs = rf_regs_5112a;
527 ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_5112a);
528 ini_rfb = rfb_5112a;
529 ah->ah_rf_banks_size = ARRAY_SIZE(rfb_5112a);
530 } else {
531 rf_regs = rf_regs_5112;
532 ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_5112);
533 ini_rfb = rfb_5112;
534 ah->ah_rf_banks_size = ARRAY_SIZE(rfb_5112);
535 }
536 go = &rfgain_opt_5112;
537 break;
538 case AR5K_RF2413:
539 rf_regs = rf_regs_2413;
540 ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_2413);
541 ini_rfb = rfb_2413;
542 ah->ah_rf_banks_size = ARRAY_SIZE(rfb_2413);
543 break;
544 case AR5K_RF2316:
545 rf_regs = rf_regs_2316;
546 ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_2316);
547 ini_rfb = rfb_2316;
548 ah->ah_rf_banks_size = ARRAY_SIZE(rfb_2316);
549 break;
550 case AR5K_RF5413:
551 rf_regs = rf_regs_5413;
552 ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_5413);
553 ini_rfb = rfb_5413;
554 ah->ah_rf_banks_size = ARRAY_SIZE(rfb_5413);
555 break;
556 case AR5K_RF2317:
557 rf_regs = rf_regs_2425;
558 ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_2425);
559 ini_rfb = rfb_2317;
560 ah->ah_rf_banks_size = ARRAY_SIZE(rfb_2317);
561 break;
562 case AR5K_RF2425:
563 rf_regs = rf_regs_2425;
564 ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_2425);
565 if (ah->ah_mac_srev < AR5K_SREV_AR2417) {
566 ini_rfb = rfb_2425;
567 ah->ah_rf_banks_size = ARRAY_SIZE(rfb_2425);
568 } else {
569 ini_rfb = rfb_2417;
570 ah->ah_rf_banks_size = ARRAY_SIZE(rfb_2417);
571 }
572 break;
573 default:
574 return -EINVAL;
575 }
1409 576
1410 if (ah->ah_radio_5ghz_revision >= AR5K_SREV_RAD_2112A 577 /* If it's the first time we set rf buffer, allocate
1411 && !test_bit(AR5K_MODE_11A, ah->ah_capabilities.cap_mode)) { 578 * ah->ah_rf_banks based on ah->ah_rf_banks_size
1412 rf_ini = rfregs_2112a; 579 * we set above */
1413 rf_size = ARRAY_SIZE(rfregs_5112a); 580 if (ah->ah_rf_banks == NULL) {
1414 if (mode < 2) { 581 ah->ah_rf_banks = kmalloc(sizeof(u32) * ah->ah_rf_banks_size,
1415 ATH5K_ERR(ah->ah_sc, "invalid channel mode: %i\n", 582 GFP_KERNEL);
1416 mode); 583 if (ah->ah_rf_banks == NULL) {
1417 return -EINVAL; 584 ATH5K_ERR(ah->ah_sc, "out of memory\n");
585 return -ENOMEM;
1418 } 586 }
1419 mode = mode - 2; /*no a/turboa modes for 2112*/
1420 } else if (ah->ah_radio_5ghz_revision >= AR5K_SREV_RAD_5112A) {
1421 rf_ini = rfregs_5112a;
1422 rf_size = ARRAY_SIZE(rfregs_5112a);
1423 } else {
1424 rf_ini = rfregs_5112;
1425 rf_size = ARRAY_SIZE(rfregs_5112);
1426 } 587 }
1427 588
1428 /* Copy values to modify them */ 589 /* Copy values to modify them */
1429 for (i = 0; i < rf_size; i++) { 590 rfb = ah->ah_rf_banks;
1430 if (rf_ini[i].rf_bank >= AR5K_RF5112_INI_RF_MAX_BANKS) { 591
592 for (i = 0; i < ah->ah_rf_banks_size; i++) {
593 if (ini_rfb[i].rfb_bank >= AR5K_MAX_RF_BANKS) {
1431 ATH5K_ERR(ah->ah_sc, "invalid bank\n"); 594 ATH5K_ERR(ah->ah_sc, "invalid bank\n");
1432 return -EINVAL; 595 return -EINVAL;
1433 } 596 }
1434 597
1435 if (bank != rf_ini[i].rf_bank) { 598 /* Bank changed, write down the offset */
1436 bank = rf_ini[i].rf_bank; 599 if (bank != ini_rfb[i].rfb_bank) {
600 bank = ini_rfb[i].rfb_bank;
1437 ah->ah_offset[bank] = i; 601 ah->ah_offset[bank] = i;
1438 } 602 }
1439 603
1440 rf[i] = rf_ini[i].rf_value[mode]; 604 rfb[i] = ini_rfb[i].rfb_mode_data[mode];
1441 } 605 }
1442 606
1443 /* Modify bank 6 */ 607 /* Set Output and Driver bias current (OB/DB) */
1444 if (channel->hw_value & CHANNEL_2GHZ) { 608 if (channel->hw_value & CHANNEL_2GHZ) {
1445 if (channel->hw_value & CHANNEL_OFDM) 609
610 if (channel->hw_value & CHANNEL_CCK)
611 ee_mode = AR5K_EEPROM_MODE_11B;
612 else
1446 ee_mode = AR5K_EEPROM_MODE_11G; 613 ee_mode = AR5K_EEPROM_MODE_11G;
614
615 /* For RF511X/RF211X combination we
616 * use b_OB and b_DB parameters stored
617 * in eeprom on ee->ee_ob[ee_mode][0]
618 *
619 * For all other chips we use OB/DB for 2Ghz
620 * stored in the b/g modal section just like
621 * 802.11a on ee->ee_ob[ee_mode][1] */
622 if ((ah->ah_radio == AR5K_RF5111) ||
623 (ah->ah_radio == AR5K_RF5112))
624 obdb = 0;
1447 else 625 else
1448 ee_mode = AR5K_EEPROM_MODE_11B; 626 obdb = 1;
1449 obdb = 0;
1450 627
1451 if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[6], 628 ath5k_hw_rfb_op(ah, rf_regs, ee->ee_ob[ee_mode][obdb],
1452 ee->ee_ob[ee_mode][obdb], 3, 287, 0, true)) 629 AR5K_RF_OB_2GHZ, true);
1453 return -EINVAL;
1454 630
1455 if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[6], 631 ath5k_hw_rfb_op(ah, rf_regs, ee->ee_db[ee_mode][obdb],
1456 ee->ee_ob[ee_mode][obdb], 3, 290, 0, true)) 632 AR5K_RF_DB_2GHZ, true);
1457 return -EINVAL; 633
1458 } else { 634 /* RF5111 always needs OB/DB for 5GHz, even if we use 2GHz */
1459 /* For 11a, Turbo and XR */ 635 } else if ((channel->hw_value & CHANNEL_5GHZ) ||
636 (ah->ah_radio == AR5K_RF5111)) {
637
638 /* For 11a, Turbo and XR we need to choose
639 * OB/DB based on frequency range */
1460 ee_mode = AR5K_EEPROM_MODE_11A; 640 ee_mode = AR5K_EEPROM_MODE_11A;
1461 obdb = channel->center_freq >= 5725 ? 3 : 641 obdb = channel->center_freq >= 5725 ? 3 :
1462 (channel->center_freq >= 5500 ? 2 : 642 (channel->center_freq >= 5500 ? 2 :
1463 (channel->center_freq >= 5260 ? 1 : 643 (channel->center_freq >= 5260 ? 1 :
1464 (channel->center_freq > 4000 ? 0 : -1))); 644 (channel->center_freq > 4000 ? 0 : -1)));
1465 645
1466 if (obdb == -1) 646 if (obdb < 0)
1467 return -EINVAL; 647 return -EINVAL;
1468 648
1469 if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[6], 649 ath5k_hw_rfb_op(ah, rf_regs, ee->ee_ob[ee_mode][obdb],
1470 ee->ee_ob[ee_mode][obdb], 3, 279, 0, true)) 650 AR5K_RF_OB_5GHZ, true);
1471 return -EINVAL;
1472 651
1473 if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[6], 652 ath5k_hw_rfb_op(ah, rf_regs, ee->ee_db[ee_mode][obdb],
1474 ee->ee_ob[ee_mode][obdb], 3, 282, 0, true)) 653 AR5K_RF_DB_5GHZ, true);
1475 return -EINVAL;
1476 } 654 }
1477 655
1478 ath5k_hw_rfregs_op(rf, ah->ah_offset[6], 656 g_step = &go->go_step[ah->ah_gain.g_step_idx];
1479 ee->ee_x_gain[ee_mode], 2, 270, 0, true);
1480 ath5k_hw_rfregs_op(rf, ah->ah_offset[6],
1481 ee->ee_x_gain[ee_mode], 2, 257, 0, true);
1482 657
1483 if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[6], 658 /* Bank Modifications (chip-specific) */
1484 ee->ee_xpd[ee_mode], 1, 302, 0, true)) 659 if (ah->ah_radio == AR5K_RF5111) {
1485 return -EINVAL;
1486 660
1487 /* Modify bank 7 */ 661 /* Set gain_F settings according to current step */
1488 if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[7], 662 if (channel->hw_value & CHANNEL_OFDM) {
1489 ee->ee_i_gain[ee_mode], 6, 14, 0, true))
1490 return -EINVAL;
1491 663
1492 /* Write RF values */ 664 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_FRAME_CTL,
1493 for (i = 0; i < rf_size; i++) 665 AR5K_PHY_FRAME_CTL_TX_CLIP,
1494 ath5k_hw_reg_write(ah, rf[i], rf_ini[i].rf_register); 666 g_step->gos_param[0]);
1495 667
1496 return 0; 668 ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[1],
1497} 669 AR5K_RF_PWD_90, true);
1498 670
1499/* 671 ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[2],
1500 * Initialize RF5413/5414 and future chips 672 AR5K_RF_PWD_84, true);
1501 * (until we come up with a better solution)
1502 */
1503static int ath5k_hw_rf5413_rfregs(struct ath5k_hw *ah,
1504 struct ieee80211_channel *channel, unsigned int mode)
1505{
1506 const struct ath5k_ini_rf *rf_ini;
1507 u32 *rf;
1508 unsigned int rf_size, i;
1509 int bank = -1;
1510 673
1511 AR5K_ASSERT_ENTRY(mode, AR5K_MODE_MAX); 674 ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[3],
1512 675 AR5K_RF_RFGAIN_SEL, true);
1513 rf = ah->ah_rf_banks;
1514 676
1515 switch (ah->ah_radio) { 677 /* We programmed gain_F parameters, switch back
1516 case AR5K_RF5413: 678 * to active state */
1517 rf_ini = rfregs_5413; 679 ah->ah_gain.g_state = AR5K_RFGAIN_ACTIVE;
1518 rf_size = ARRAY_SIZE(rfregs_5413);
1519 break;
1520 case AR5K_RF2413:
1521 rf_ini = rfregs_2413;
1522 rf_size = ARRAY_SIZE(rfregs_2413);
1523 680
1524 if (mode < 2) {
1525 ATH5K_ERR(ah->ah_sc,
1526 "invalid channel mode: %i\n", mode);
1527 return -EINVAL;
1528 } 681 }
1529 682
1530 mode = mode - 2; 683 /* Bank 6/7 setup */
1531 break;
1532 case AR5K_RF2425:
1533 rf_ini = rfregs_2425;
1534 rf_size = ARRAY_SIZE(rfregs_2425);
1535 684
1536 if (mode < 2) { 685 ath5k_hw_rfb_op(ah, rf_regs, !ee->ee_xpd[ee_mode],
1537 ATH5K_ERR(ah->ah_sc, 686 AR5K_RF_PWD_XPD, true);
1538 "invalid channel mode: %i\n", mode);
1539 return -EINVAL;
1540 }
1541 687
1542 /* Map b to g */ 688 ath5k_hw_rfb_op(ah, rf_regs, ee->ee_x_gain[ee_mode],
1543 if (mode == 2) 689 AR5K_RF_XPD_GAIN, true);
1544 mode = 0;
1545 else
1546 mode = mode - 3;
1547 690
1548 break; 691 ath5k_hw_rfb_op(ah, rf_regs, ee->ee_i_gain[ee_mode],
1549 default: 692 AR5K_RF_GAIN_I, true);
1550 return -EINVAL; 693
694 ath5k_hw_rfb_op(ah, rf_regs, ee->ee_xpd[ee_mode],
695 AR5K_RF_PLO_SEL, true);
696
697 /* TODO: Half/quarter channel support */
1551 } 698 }
1552 699
1553 /* Copy values to modify them */ 700 if (ah->ah_radio == AR5K_RF5112) {
1554 for (i = 0; i < rf_size; i++) {
1555 if (rf_ini[i].rf_bank >= AR5K_RF5112_INI_RF_MAX_BANKS) {
1556 ATH5K_ERR(ah->ah_sc, "invalid bank\n");
1557 return -EINVAL;
1558 }
1559 701
1560 if (bank != rf_ini[i].rf_bank) { 702 /* Set gain_F settings according to current step */
1561 bank = rf_ini[i].rf_bank; 703 if (channel->hw_value & CHANNEL_OFDM) {
1562 ah->ah_offset[bank] = i;
1563 }
1564 704
1565 rf[i] = rf_ini[i].rf_value[mode]; 705 ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[0],
1566 } 706 AR5K_RF_MIXGAIN_OVR, true);
1567 707
1568 /* 708 ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[1],
1569 * After compairing dumps from different cards 709 AR5K_RF_PWD_138, true);
1570 * we get the same RF_BUFFER settings (diff returns
1571 * 0 lines). It seems that RF_BUFFER settings are static
1572 * and are written unmodified (no EEPROM stuff
1573 * is used because calibration data would be
1574 * different between different cards and would result
1575 * different RF_BUFFER settings)
1576 */
1577 710
1578 /* Write RF values */ 711 ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[2],
1579 for (i = 0; i < rf_size; i++) 712 AR5K_RF_PWD_137, true);
1580 ath5k_hw_reg_write(ah, rf[i], rf_ini[i].rf_register);
1581 713
1582 return 0; 714 ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[3],
1583} 715 AR5K_RF_PWD_136, true);
1584 716
1585/* 717 ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[4],
1586 * Initialize RF 718 AR5K_RF_PWD_132, true);
1587 */
1588int ath5k_hw_rfregs(struct ath5k_hw *ah, struct ieee80211_channel *channel,
1589 unsigned int mode)
1590{
1591 int (*func)(struct ath5k_hw *, struct ieee80211_channel *, unsigned int);
1592 int ret;
1593 719
1594 switch (ah->ah_radio) { 720 ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[5],
1595 case AR5K_RF5111: 721 AR5K_RF_PWD_131, true);
1596 ah->ah_rf_banks_size = sizeof(rfregs_5111);
1597 func = ath5k_hw_rf5111_rfregs;
1598 break;
1599 case AR5K_RF5112:
1600 if (ah->ah_radio_5ghz_revision >= AR5K_SREV_RAD_5112A)
1601 ah->ah_rf_banks_size = sizeof(rfregs_5112a);
1602 else
1603 ah->ah_rf_banks_size = sizeof(rfregs_5112);
1604 func = ath5k_hw_rf5112_rfregs;
1605 break;
1606 case AR5K_RF5413:
1607 ah->ah_rf_banks_size = sizeof(rfregs_5413);
1608 func = ath5k_hw_rf5413_rfregs;
1609 break;
1610 case AR5K_RF2413:
1611 ah->ah_rf_banks_size = sizeof(rfregs_2413);
1612 func = ath5k_hw_rf5413_rfregs;
1613 break;
1614 case AR5K_RF2425:
1615 ah->ah_rf_banks_size = sizeof(rfregs_2425);
1616 func = ath5k_hw_rf5413_rfregs;
1617 break;
1618 default:
1619 return -EINVAL;
1620 }
1621 722
1622 if (ah->ah_rf_banks == NULL) { 723 ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[6],
1623 /* XXX do extra checks? */ 724 AR5K_RF_PWD_130, true);
1624 ah->ah_rf_banks = kmalloc(ah->ah_rf_banks_size, GFP_KERNEL); 725
1625 if (ah->ah_rf_banks == NULL) { 726 /* We programmed gain_F parameters, switch back
1626 ATH5K_ERR(ah->ah_sc, "out of memory\n"); 727 * to active state */
1627 return -ENOMEM; 728 ah->ah_gain.g_state = AR5K_RFGAIN_ACTIVE;
1628 } 729 }
1629 }
1630 730
1631 ret = func(ah, channel, mode); 731 /* Bank 6/7 setup */
1632 if (!ret)
1633 ah->ah_rf_gain = AR5K_RFGAIN_INACTIVE;
1634 732
1635 return ret; 733 ath5k_hw_rfb_op(ah, rf_regs, ee->ee_xpd[ee_mode],
1636} 734 AR5K_RF_XPD_SEL, true);
1637 735
1638int ath5k_hw_rfgain(struct ath5k_hw *ah, unsigned int freq) 736 if (ah->ah_radio_5ghz_revision < AR5K_SREV_RAD_5112A) {
1639{ 737 /* Rev. 1 supports only one xpd */
1640 const struct ath5k_ini_rfgain *ath5k_rfg; 738 ath5k_hw_rfb_op(ah, rf_regs,
1641 unsigned int i, size; 739 ee->ee_x_gain[ee_mode],
740 AR5K_RF_XPD_GAIN, true);
1642 741
1643 switch (ah->ah_radio) { 742 } else {
1644 case AR5K_RF5111: 743 /* TODO: Set high and low gain bits */
1645 ath5k_rfg = rfgain_5111; 744 ath5k_hw_rfb_op(ah, rf_regs,
1646 size = ARRAY_SIZE(rfgain_5111); 745 ee->ee_x_gain[ee_mode],
1647 break; 746 AR5K_RF_PD_GAIN_LO, true);
1648 case AR5K_RF5112: 747 ath5k_hw_rfb_op(ah, rf_regs,
1649 ath5k_rfg = rfgain_5112; 748 ee->ee_x_gain[ee_mode],
1650 size = ARRAY_SIZE(rfgain_5112); 749 AR5K_RF_PD_GAIN_HI, true);
1651 break;
1652 case AR5K_RF5413:
1653 ath5k_rfg = rfgain_5413;
1654 size = ARRAY_SIZE(rfgain_5413);
1655 break;
1656 case AR5K_RF2413:
1657 ath5k_rfg = rfgain_2413;
1658 size = ARRAY_SIZE(rfgain_2413);
1659 freq = 0; /* only 2Ghz */
1660 break;
1661 case AR5K_RF2425:
1662 ath5k_rfg = rfgain_2425;
1663 size = ARRAY_SIZE(rfgain_2425);
1664 freq = 0; /* only 2Ghz */
1665 break;
1666 default:
1667 return -EINVAL;
1668 }
1669 750
1670 switch (freq) { 751 /* Lower synth voltage on Rev 2 */
1671 case AR5K_INI_RFGAIN_2GHZ: 752 ath5k_hw_rfb_op(ah, rf_regs, 2,
1672 case AR5K_INI_RFGAIN_5GHZ: 753 AR5K_RF_HIGH_VC_CP, true);
1673 break;
1674 default:
1675 return -EINVAL;
1676 }
1677 754
1678 for (i = 0; i < size; i++) { 755 ath5k_hw_rfb_op(ah, rf_regs, 2,
1679 AR5K_REG_WAIT(i); 756 AR5K_RF_MID_VC_CP, true);
1680 ath5k_hw_reg_write(ah, ath5k_rfg[i].rfg_value[freq],
1681 (u32)ath5k_rfg[i].rfg_register);
1682 }
1683 757
1684 return 0; 758 ath5k_hw_rfb_op(ah, rf_regs, 2,
1685} 759 AR5K_RF_LOW_VC_CP, true);
1686 760
1687enum ath5k_rfgain ath5k_hw_get_rf_gain(struct ath5k_hw *ah) 761 ath5k_hw_rfb_op(ah, rf_regs, 2,
1688{ 762 AR5K_RF_PUSH_UP, true);
1689 u32 data, type;
1690 763
1691 ATH5K_TRACE(ah->ah_sc); 764 /* Decrease power consumption on 5213+ BaseBand */
765 if (ah->ah_phy_revision >= AR5K_SREV_PHY_5212A) {
766 ath5k_hw_rfb_op(ah, rf_regs, 1,
767 AR5K_RF_PAD2GND, true);
1692 768
1693 if (ah->ah_rf_banks == NULL || !ah->ah_gain.g_active || 769 ath5k_hw_rfb_op(ah, rf_regs, 1,
1694 ah->ah_version <= AR5K_AR5211) 770 AR5K_RF_XB2_LVL, true);
1695 return AR5K_RFGAIN_INACTIVE;
1696 771
1697 if (ah->ah_rf_gain != AR5K_RFGAIN_READ_REQUESTED) 772 ath5k_hw_rfb_op(ah, rf_regs, 1,
1698 goto done; 773 AR5K_RF_XB5_LVL, true);
1699 774
1700 data = ath5k_hw_reg_read(ah, AR5K_PHY_PAPD_PROBE); 775 ath5k_hw_rfb_op(ah, rf_regs, 1,
776 AR5K_RF_PWD_167, true);
1701 777
1702 if (!(data & AR5K_PHY_PAPD_PROBE_TX_NEXT)) { 778 ath5k_hw_rfb_op(ah, rf_regs, 1,
1703 ah->ah_gain.g_current = data >> AR5K_PHY_PAPD_PROBE_GAINF_S; 779 AR5K_RF_PWD_166, true);
1704 type = AR5K_REG_MS(data, AR5K_PHY_PAPD_PROBE_TYPE); 780 }
781 }
1705 782
1706 if (type == AR5K_PHY_PAPD_PROBE_TYPE_CCK) 783 ath5k_hw_rfb_op(ah, rf_regs, ee->ee_i_gain[ee_mode],
1707 ah->ah_gain.g_current += AR5K_GAIN_CCK_PROBE_CORR; 784 AR5K_RF_GAIN_I, true);
1708 785
1709 if (ah->ah_radio >= AR5K_RF5112) { 786 /* TODO: Half/quarter channel support */
1710 ath5k_hw_rfregs_gainf_corr(ah);
1711 ah->ah_gain.g_current =
1712 ah->ah_gain.g_current >= ah->ah_gain.g_f_corr ?
1713 (ah->ah_gain.g_current-ah->ah_gain.g_f_corr) :
1714 0;
1715 }
1716 787
1717 if (ath5k_hw_rfregs_gain_readback(ah) &&
1718 AR5K_GAIN_CHECK_ADJUST(&ah->ah_gain) &&
1719 ath5k_hw_rfregs_gain_adjust(ah))
1720 ah->ah_rf_gain = AR5K_RFGAIN_NEED_CHANGE;
1721 } 788 }
1722 789
1723done: 790 if (ah->ah_radio == AR5K_RF5413 &&
1724 return ah->ah_rf_gain; 791 channel->hw_value & CHANNEL_2GHZ) {
1725} 792
793 ath5k_hw_rfb_op(ah, rf_regs, 1, AR5K_RF_DERBY_CHAN_SEL_MODE,
794 true);
795
796 /* Set optimum value for early revisions (on pci-e chips) */
797 if (ah->ah_mac_srev >= AR5K_SREV_AR5424 &&
798 ah->ah_mac_srev < AR5K_SREV_AR5413)
799 ath5k_hw_rfb_op(ah, rf_regs, ath5k_hw_bitswap(6, 3),
800 AR5K_RF_PWD_ICLOBUF_2G, true);
1726 801
1727int ath5k_hw_set_rfgain_opt(struct ath5k_hw *ah) 802 }
1728{ 803
1729 /* Initialize the gain optimization values */ 804 /* Write RF banks on hw */
1730 switch (ah->ah_radio) { 805 for (i = 0; i < ah->ah_rf_banks_size; i++) {
1731 case AR5K_RF5111: 806 AR5K_REG_WAIT(i);
1732 ah->ah_gain.g_step_idx = rfgain_opt_5111.go_default; 807 ath5k_hw_reg_write(ah, rfb[i], ini_rfb[i].rfb_ctrl_register);
1733 ah->ah_gain.g_step =
1734 &rfgain_opt_5111.go_step[ah->ah_gain.g_step_idx];
1735 ah->ah_gain.g_low = 20;
1736 ah->ah_gain.g_high = 35;
1737 ah->ah_gain.g_active = 1;
1738 break;
1739 case AR5K_RF5112:
1740 ah->ah_gain.g_step_idx = rfgain_opt_5112.go_default;
1741 ah->ah_gain.g_step =
1742 &rfgain_opt_5112.go_step[ah->ah_gain.g_step_idx];
1743 ah->ah_gain.g_low = 20;
1744 ah->ah_gain.g_high = 85;
1745 ah->ah_gain.g_active = 1;
1746 break;
1747 default:
1748 return -EINVAL;
1749 } 808 }
1750 809
1751 return 0; 810 return 0;
1752} 811}
1753 812
813
1754/**************************\ 814/**************************\
1755 PHY/RF channel functions 815 PHY/RF channel functions
1756\**************************/ 816\**************************/
@@ -2271,13 +1331,8 @@ done:
2271 * as often as I/Q calibration.*/ 1331 * as often as I/Q calibration.*/
2272 ath5k_hw_noise_floor_calibration(ah, channel->center_freq); 1332 ath5k_hw_noise_floor_calibration(ah, channel->center_freq);
2273 1333
2274 /* Request RF gain */ 1334 /* Initiate a gain_F calibration */
2275 if (channel->hw_value & CHANNEL_5GHZ) { 1335 ath5k_hw_request_rfgain_probe(ah);
2276 ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txpower.txp_max,
2277 AR5K_PHY_PAPD_PROBE_TXPOWER) |
2278 AR5K_PHY_PAPD_PROBE_TX_NEXT, AR5K_PHY_PAPD_PROBE);
2279 ah->ah_rf_gain = AR5K_RFGAIN_READ_REQUESTED;
2280 }
2281 1336
2282 return 0; 1337 return 0;
2283} 1338}
diff --git a/drivers/net/wireless/ath5k/reg.h b/drivers/net/wireless/ath5k/reg.h
index 9189ab13286c..2dc008e10226 100644
--- a/drivers/net/wireless/ath5k/reg.h
+++ b/drivers/net/wireless/ath5k/reg.h
@@ -187,6 +187,7 @@
187#define AR5K_TXCFG_FRMPAD_DIS 0x00002000 /* [5211+] */ 187#define AR5K_TXCFG_FRMPAD_DIS 0x00002000 /* [5211+] */
188#define AR5K_TXCFG_RDY_CBR_DIS 0x00004000 /* Ready time CBR disable [5211+] */ 188#define AR5K_TXCFG_RDY_CBR_DIS 0x00004000 /* Ready time CBR disable [5211+] */
189#define AR5K_TXCFG_JUMBO_FRM_MODE 0x00008000 /* Jumbo frame mode [5211+] */ 189#define AR5K_TXCFG_JUMBO_FRM_MODE 0x00008000 /* Jumbo frame mode [5211+] */
190#define AR5K_TXCFG_DCU_DBL_BUF_DIS 0x00008000 /* Disable double buffering on DCU */
190#define AR5K_TXCFG_DCU_CACHING_DIS 0x00010000 /* Disable DCU caching */ 191#define AR5K_TXCFG_DCU_CACHING_DIS 0x00010000 /* Disable DCU caching */
191 192
192/* 193/*
@@ -753,7 +754,7 @@
753 */ 754 */
754#define AR5K_DCU_SEQNUM_BASE 0x1140 755#define AR5K_DCU_SEQNUM_BASE 0x1140
755#define AR5K_DCU_SEQNUM_M 0x00000fff 756#define AR5K_DCU_SEQNUM_M 0x00000fff
756#define AR5K_QUEUE_DFS_SEQNUM(_q) AR5K_QUEUE_REG(AR5K_DCU_SEQNUM_BASE, _q) 757#define AR5K_QUEUE_DCU_SEQNUM(_q) AR5K_QUEUE_REG(AR5K_DCU_SEQNUM_BASE, _q)
757 758
758/* 759/*
759 * DCU global IFS SIFS register 760 * DCU global IFS SIFS register
@@ -811,6 +812,8 @@
811 812
812/* 813/*
813 * DCU transmit filter table 0 (32 entries) 814 * DCU transmit filter table 0 (32 entries)
815 * each entry contains a 32bit slice of the
816 * 128bit tx filter for each DCU (4 slices per DCU)
814 */ 817 */
815#define AR5K_DCU_TX_FILTER_0_BASE 0x1038 818#define AR5K_DCU_TX_FILTER_0_BASE 0x1038
816#define AR5K_DCU_TX_FILTER_0(_n) (AR5K_DCU_TX_FILTER_0_BASE + (_n * 64)) 819#define AR5K_DCU_TX_FILTER_0(_n) (AR5K_DCU_TX_FILTER_0_BASE + (_n * 64))
@@ -819,7 +822,7 @@
819 * DCU transmit filter table 1 (16 entries) 822 * DCU transmit filter table 1 (16 entries)
820 */ 823 */
821#define AR5K_DCU_TX_FILTER_1_BASE 0x103c 824#define AR5K_DCU_TX_FILTER_1_BASE 0x103c
822#define AR5K_DCU_TX_FILTER_1(_n) (AR5K_DCU_TX_FILTER_1_BASE + ((_n - 32) * 64)) 825#define AR5K_DCU_TX_FILTER_1(_n) (AR5K_DCU_TX_FILTER_1_BASE + (_n * 64))
823 826
824/* 827/*
825 * DCU clear transmit filter register 828 * DCU clear transmit filter register
@@ -1447,7 +1450,7 @@
1447 AR5K_TSF_U32_5210 : AR5K_TSF_U32_5211) 1450 AR5K_TSF_U32_5210 : AR5K_TSF_U32_5211)
1448 1451
1449/* 1452/*
1450 * Last beacon timestamp register 1453 * Last beacon timestamp register (Read Only)
1451 */ 1454 */
1452#define AR5K_LAST_TSTP 0x8080 1455#define AR5K_LAST_TSTP 0x8080
1453 1456
@@ -1465,7 +1468,7 @@
1465#define AR5K_ADDAC_TEST_TRIG_PTY 0x00020000 /* Trigger polarity */ 1468#define AR5K_ADDAC_TEST_TRIG_PTY 0x00020000 /* Trigger polarity */
1466#define AR5K_ADDAC_TEST_RXCONT 0x00040000 /* Continuous capture */ 1469#define AR5K_ADDAC_TEST_RXCONT 0x00040000 /* Continuous capture */
1467#define AR5K_ADDAC_TEST_CAPTURE 0x00080000 /* Begin capture */ 1470#define AR5K_ADDAC_TEST_CAPTURE 0x00080000 /* Begin capture */
1468#define AR5K_ADDAC_TEST_TST_ARM 0x00100000 /* Test ARM (Adaptive Radio Mode ?) */ 1471#define AR5K_ADDAC_TEST_TST_ARM 0x00100000 /* ARM rx buffer for capture */
1469 1472
1470/* 1473/*
1471 * Default antenna register [5211+] 1474 * Default antenna register [5211+]
@@ -1677,7 +1680,7 @@
1677 * TSF parameter register 1680 * TSF parameter register
1678 */ 1681 */
1679#define AR5K_TSF_PARM 0x8104 /* Register Address */ 1682#define AR5K_TSF_PARM 0x8104 /* Register Address */
1680#define AR5K_TSF_PARM_INC_M 0x000000ff /* Mask for TSF increment */ 1683#define AR5K_TSF_PARM_INC 0x000000ff /* Mask for TSF increment */
1681#define AR5K_TSF_PARM_INC_S 0 1684#define AR5K_TSF_PARM_INC_S 0
1682 1685
1683/* 1686/*
@@ -1689,7 +1692,7 @@
1689#define AR5K_QOS_NOACK_BIT_OFFSET 0x00000070 /* ??? */ 1692#define AR5K_QOS_NOACK_BIT_OFFSET 0x00000070 /* ??? */
1690#define AR5K_QOS_NOACK_BIT_OFFSET_S 4 1693#define AR5K_QOS_NOACK_BIT_OFFSET_S 4
1691#define AR5K_QOS_NOACK_BYTE_OFFSET 0x00000180 /* ??? */ 1694#define AR5K_QOS_NOACK_BYTE_OFFSET 0x00000180 /* ??? */
1692#define AR5K_QOS_NOACK_BYTE_OFFSET_S 8 1695#define AR5K_QOS_NOACK_BYTE_OFFSET_S 7
1693 1696
1694/* 1697/*
1695 * PHY error filter register 1698 * PHY error filter register
@@ -1848,15 +1851,14 @@
1848 * TST_2 (Misc config parameters) 1851 * TST_2 (Misc config parameters)
1849 */ 1852 */
1850#define AR5K_PHY_TST2 0x9800 /* Register Address */ 1853#define AR5K_PHY_TST2 0x9800 /* Register Address */
1851#define AR5K_PHY_TST2_TRIG_SEL 0x00000001 /* Trigger select (?) (field ?) */ 1854#define AR5K_PHY_TST2_TRIG_SEL 0x00000007 /* Trigger select (?)*/
1852#define AR5K_PHY_TST2_TRIG 0x00000010 /* Trigger (?) (field ?) */ 1855#define AR5K_PHY_TST2_TRIG 0x00000010 /* Trigger (?) */
1853#define AR5K_PHY_TST2_CBUS_MODE 0x00000100 /* Cardbus mode (?) */ 1856#define AR5K_PHY_TST2_CBUS_MODE 0x00000060 /* Cardbus mode (?) */
1854/* bit reserved */
1855#define AR5K_PHY_TST2_CLK32 0x00000400 /* CLK_OUT is CLK32 (32Khz external) */ 1857#define AR5K_PHY_TST2_CLK32 0x00000400 /* CLK_OUT is CLK32 (32Khz external) */
1856#define AR5K_PHY_TST2_CHANCOR_DUMP_EN 0x00000800 /* Enable Chancor dump (?) */ 1858#define AR5K_PHY_TST2_CHANCOR_DUMP_EN 0x00000800 /* Enable Chancor dump (?) */
1857#define AR5K_PHY_TST2_EVEN_CHANCOR_DUMP 0x00001000 /* Even Chancor dump (?) */ 1859#define AR5K_PHY_TST2_EVEN_CHANCOR_DUMP 0x00001000 /* Even Chancor dump (?) */
1858#define AR5K_PHY_TST2_RFSILENT_EN 0x00002000 /* Enable RFSILENT */ 1860#define AR5K_PHY_TST2_RFSILENT_EN 0x00002000 /* Enable RFSILENT */
1859#define AR5K_PHY_TST2_ALT_RFDATA 0x00004000 /* Alternate RFDATA (5-2GHz switch) */ 1861#define AR5K_PHY_TST2_ALT_RFDATA 0x00004000 /* Alternate RFDATA (5-2GHz switch ?) */
1860#define AR5K_PHY_TST2_MINI_OBS_EN 0x00008000 /* Enable mini OBS (?) */ 1862#define AR5K_PHY_TST2_MINI_OBS_EN 0x00008000 /* Enable mini OBS (?) */
1861#define AR5K_PHY_TST2_RX2_IS_RX5_INV 0x00010000 /* 2GHz rx path is the 5GHz path inverted (?) */ 1863#define AR5K_PHY_TST2_RX2_IS_RX5_INV 0x00010000 /* 2GHz rx path is the 5GHz path inverted (?) */
1862#define AR5K_PHY_TST2_SLOW_CLK160 0x00020000 /* Slow CLK160 (?) */ 1864#define AR5K_PHY_TST2_SLOW_CLK160 0x00020000 /* Slow CLK160 (?) */
@@ -1926,8 +1928,8 @@
1926#define AR5K_PHY_RF_CTL2_TXF2TXD_START_S 0 1928#define AR5K_PHY_RF_CTL2_TXF2TXD_START_S 0
1927 1929
1928#define AR5K_PHY_RF_CTL3 0x9828 /* Register Address */ 1930#define AR5K_PHY_RF_CTL3 0x9828 /* Register Address */
1929#define AR5K_PHY_RF_CTL3_TXE2XLNA_ON 0x0000000f /* TX end to XLNA on */ 1931#define AR5K_PHY_RF_CTL3_TXE2XLNA_ON 0x0000ff00 /* TX end to XLNA on */
1930#define AR5K_PHY_RF_CTL3_TXE2XLNA_ON_S 0 1932#define AR5K_PHY_RF_CTL3_TXE2XLNA_ON_S 8
1931 1933
1932#define AR5K_PHY_ADC_CTL 0x982c 1934#define AR5K_PHY_ADC_CTL 0x982c
1933#define AR5K_PHY_ADC_CTL_INBUFGAIN_OFF 0x00000003 1935#define AR5K_PHY_ADC_CTL_INBUFGAIN_OFF 0x00000003
@@ -1961,7 +1963,7 @@
1961#define AR5K_PHY_SETTLING_AGC 0x0000007f /* AGC settling time */ 1963#define AR5K_PHY_SETTLING_AGC 0x0000007f /* AGC settling time */
1962#define AR5K_PHY_SETTLING_AGC_S 0 1964#define AR5K_PHY_SETTLING_AGC_S 0
1963#define AR5K_PHY_SETTLING_SWITCH 0x00003f80 /* Switch settlig time */ 1965#define AR5K_PHY_SETTLING_SWITCH 0x00003f80 /* Switch settlig time */
1964#define AR5K_PHY_SETTLINK_SWITCH_S 7 1966#define AR5K_PHY_SETTLING_SWITCH_S 7
1965 1967
1966/* 1968/*
1967 * PHY Gain registers 1969 * PHY Gain registers
@@ -2067,14 +2069,14 @@
2067 * PHY sleep registers [5112+] 2069 * PHY sleep registers [5112+]
2068 */ 2070 */
2069#define AR5K_PHY_SCR 0x9870 2071#define AR5K_PHY_SCR 0x9870
2070#define AR5K_PHY_SCR_32MHZ 0x0000001f
2071 2072
2072#define AR5K_PHY_SLMT 0x9874 2073#define AR5K_PHY_SLMT 0x9874
2073#define AR5K_PHY_SLMT_32MHZ 0x0000007f 2074#define AR5K_PHY_SLMT_32MHZ 0x0000007f
2074 2075
2075#define AR5K_PHY_SCAL 0x9878 2076#define AR5K_PHY_SCAL 0x9878
2076#define AR5K_PHY_SCAL_32MHZ 0x0000000e 2077#define AR5K_PHY_SCAL_32MHZ 0x0000000e
2077 2078#define AR5K_PHY_SCAL_32MHZ_2417 0x0000000a
2079#define AR5K_PHY_SCAL_32MHZ_HB63 0x00000032
2078 2080
2079/* 2081/*
2080 * PHY PLL (Phase Locked Loop) control register 2082 * PHY PLL (Phase Locked Loop) control register
@@ -2101,34 +2103,10 @@
2101/* 2103/*
2102 * RF Buffer register 2104 * RF Buffer register
2103 * 2105 *
2104 * There are some special control registers on the RF chip
2105 * that hold various operation settings related mostly to
2106 * the analog parts (channel, gain adjustment etc).
2107 *
2108 * We don't write on those registers directly but
2109 * we send a data packet on the buffer register and
2110 * then write on another special register to notify hw
2111 * to apply the settings. This is done so that control registers
2112 * can be dynamicaly programmed during operation and the settings
2113 * are applied faster on the hw.
2114 *
2115 * We sent such data packets during rf initialization and channel change
2116 * through ath5k_hw_rf*_rfregs and ath5k_hw_rf*_channel functions.
2117 *
2118 * The data packets we send during initializadion are inside ath5k_ini_rf
2119 * struct (see ath5k_hw.h) and each one is related to an "rf register bank".
2120 * We use *rfregs functions to modify them acording to current operation
2121 * mode and eeprom values and pass them all together to the chip.
2122 *
2123 * It's obvious from the code that 0x989c is the buffer register but 2106 * It's obvious from the code that 0x989c is the buffer register but
2124 * for the other special registers that we write to after sending each 2107 * for the other special registers that we write to after sending each
2125 * packet, i have no idea. So i'll name them BUFFER_CONTROL_X registers 2108 * packet, i have no idea. So i'll name them BUFFER_CONTROL_X registers
2126 * for now. It's interesting that they are also used for some other operations. 2109 * for now. It's interesting that they are also used for some other operations.
2127 *
2128 * Also check out hw.h and U.S. Patent 6677779 B1 (about buffer
2129 * registers and control registers):
2130 *
2131 * http://www.google.com/patents?id=qNURAAAAEBAJ
2132 */ 2110 */
2133 2111
2134#define AR5K_RF_BUFFER 0x989c 2112#define AR5K_RF_BUFFER 0x989c
@@ -2178,7 +2156,8 @@
2178#define AR5K_PHY_ANT_CTL_TXRX_EN 0x00000001 /* Enable TX/RX (?) */ 2156#define AR5K_PHY_ANT_CTL_TXRX_EN 0x00000001 /* Enable TX/RX (?) */
2179#define AR5K_PHY_ANT_CTL_SECTORED_ANT 0x00000004 /* Sectored Antenna */ 2157#define AR5K_PHY_ANT_CTL_SECTORED_ANT 0x00000004 /* Sectored Antenna */
2180#define AR5K_PHY_ANT_CTL_HITUNE5 0x00000008 /* Hitune5 (?) */ 2158#define AR5K_PHY_ANT_CTL_HITUNE5 0x00000008 /* Hitune5 (?) */
2181#define AR5K_PHY_ANT_CTL_SWTABLE_IDLE 0x00000010 /* Switch table idle (?) */ 2159#define AR5K_PHY_ANT_CTL_SWTABLE_IDLE 0x000003f0 /* Switch table idle (?) */
2160#define AR5K_PHY_ANT_CTL_SWTABLE_IDLE_S 4
2182 2161
2183/* 2162/*
2184 * PHY receiver delay register [5111+] 2163 * PHY receiver delay register [5111+]
@@ -2218,7 +2197,7 @@
2218#define AR5K_PHY_OFDM_SELFCORR 0x9924 /* Register Address */ 2197#define AR5K_PHY_OFDM_SELFCORR 0x9924 /* Register Address */
2219#define AR5K_PHY_OFDM_SELFCORR_CYPWR_THR1_EN 0x00000001 /* Enable cyclic RSSI thr 1 */ 2198#define AR5K_PHY_OFDM_SELFCORR_CYPWR_THR1_EN 0x00000001 /* Enable cyclic RSSI thr 1 */
2220#define AR5K_PHY_OFDM_SELFCORR_CYPWR_THR1 0x000000fe /* Mask for Cyclic RSSI threshold 1 */ 2199#define AR5K_PHY_OFDM_SELFCORR_CYPWR_THR1 0x000000fe /* Mask for Cyclic RSSI threshold 1 */
2221#define AR5K_PHY_OFDM_SELFCORR_CYPWR_THR1_S 0 2200#define AR5K_PHY_OFDM_SELFCORR_CYPWR_THR1_S 1
2222#define AR5K_PHY_OFDM_SELFCORR_CYPWR_THR3 0x00000100 /* Cyclic RSSI threshold 3 (field) (?) */ 2201#define AR5K_PHY_OFDM_SELFCORR_CYPWR_THR3 0x00000100 /* Cyclic RSSI threshold 3 (field) (?) */
2223#define AR5K_PHY_OFDM_SELFCORR_RSSI_1ATHR_EN 0x00008000 /* Enable 1A RSSI threshold (?) */ 2202#define AR5K_PHY_OFDM_SELFCORR_RSSI_1ATHR_EN 0x00008000 /* Enable 1A RSSI threshold (?) */
2224#define AR5K_PHY_OFDM_SELFCORR_RSSI_1ATHR 0x00010000 /* 1A RSSI threshold (field) (?) */ 2203#define AR5K_PHY_OFDM_SELFCORR_RSSI_1ATHR 0x00010000 /* 1A RSSI threshold (field) (?) */
@@ -2243,9 +2222,7 @@
2243#define AR5K_PHY_CTL_LOW_FREQ_SLE_EN 0x00000080 /* Enable low freq sleep */ 2222#define AR5K_PHY_CTL_LOW_FREQ_SLE_EN 0x00000080 /* Enable low freq sleep */
2244 2223
2245/* 2224/*
2246 * PHY PAPD probe register [5111+ (?)] 2225 * PHY PAPD probe register [5111+]
2247 * Is this only present in 5212 ?
2248 * Because it's always 0 in 5211 initialization code
2249 */ 2226 */
2250#define AR5K_PHY_PAPD_PROBE 0x9930 2227#define AR5K_PHY_PAPD_PROBE 0x9930
2251#define AR5K_PHY_PAPD_PROBE_SH_HI_PAR 0x00000001 2228#define AR5K_PHY_PAPD_PROBE_SH_HI_PAR 0x00000001
@@ -2303,6 +2280,15 @@
2303 AR5K_PHY_FRAME_CTL_TIMING_ERR 2280 AR5K_PHY_FRAME_CTL_TIMING_ERR
2304 2281
2305/* 2282/*
2283 * PHY Tx Power adjustment register [5212A+]
2284 */
2285#define AR5K_PHY_TX_PWR_ADJ 0x994c
2286#define AR5K_PHY_TX_PWR_ADJ_CCK_GAIN_DELTA 0x00000fc0
2287#define AR5K_PHY_TX_PWR_ADJ_CCK_GAIN_DELTA_S 6
2288#define AR5K_PHY_TX_PWR_ADJ_CCK_PCDAC_INDEX 0x00fc0000
2289#define AR5K_PHY_TX_PWR_ADJ_CCK_PCDAC_INDEX_S 18
2290
2291/*
2306 * PHY radar detection register [5111+] 2292 * PHY radar detection register [5111+]
2307 */ 2293 */
2308#define AR5K_PHY_RADAR 0x9954 2294#define AR5K_PHY_RADAR 0x9954
@@ -2355,7 +2341,7 @@
2355#define AR5K_PHY_SIGMA_DELTA_FILT2_S 3 2341#define AR5K_PHY_SIGMA_DELTA_FILT2_S 3
2356#define AR5K_PHY_SIGMA_DELTA_FILT1 0x00001f00 2342#define AR5K_PHY_SIGMA_DELTA_FILT1 0x00001f00
2357#define AR5K_PHY_SIGMA_DELTA_FILT1_S 8 2343#define AR5K_PHY_SIGMA_DELTA_FILT1_S 8
2358#define AR5K_PHY_SIGMA_DELTA_ADC_CLIP 0x01ff3000 2344#define AR5K_PHY_SIGMA_DELTA_ADC_CLIP 0x01ffe000
2359#define AR5K_PHY_SIGMA_DELTA_ADC_CLIP_S 13 2345#define AR5K_PHY_SIGMA_DELTA_ADC_CLIP_S 13
2360 2346
2361/* 2347/*
@@ -2387,21 +2373,21 @@
2387#define AR5K_PHY_BIN_MASK2_4_MASK_4 0x00003fff 2373#define AR5K_PHY_BIN_MASK2_4_MASK_4 0x00003fff
2388#define AR5K_PHY_BIN_MASK2_4_MASK_4_S 0 2374#define AR5K_PHY_BIN_MASK2_4_MASK_4_S 0
2389 2375
2390#define AR_PHY_TIMING_9 0x9998 2376#define AR5K_PHY_TIMING_9 0x9998
2391#define AR_PHY_TIMING_10 0x999c 2377#define AR5K_PHY_TIMING_10 0x999c
2392#define AR_PHY_TIMING_10_PILOT_MASK_2 0x000fffff 2378#define AR5K_PHY_TIMING_10_PILOT_MASK_2 0x000fffff
2393#define AR_PHY_TIMING_10_PILOT_MASK_2_S 0 2379#define AR5K_PHY_TIMING_10_PILOT_MASK_2_S 0
2394 2380
2395/* 2381/*
2396 * Spur mitigation control 2382 * Spur mitigation control
2397 */ 2383 */
2398#define AR_PHY_TIMING_11 0x99a0 /* Register address */ 2384#define AR5K_PHY_TIMING_11 0x99a0 /* Register address */
2399#define AR_PHY_TIMING_11_SPUR_DELTA_PHASE 0x000fffff /* Spur delta phase */ 2385#define AR5K_PHY_TIMING_11_SPUR_DELTA_PHASE 0x000fffff /* Spur delta phase */
2400#define AR_PHY_TIMING_11_SPUR_DELTA_PHASE_S 0 2386#define AR5K_PHY_TIMING_11_SPUR_DELTA_PHASE_S 0
2401#define AR_PHY_TIMING_11_SPUR_FREQ_SD 0x3ff00000 /* Freq sigma delta */ 2387#define AR5K_PHY_TIMING_11_SPUR_FREQ_SD 0x3ff00000 /* Freq sigma delta */
2402#define AR_PHY_TIMING_11_SPUR_FREQ_SD_S 20 2388#define AR5K_PHY_TIMING_11_SPUR_FREQ_SD_S 20
2403#define AR_PHY_TIMING_11_USE_SPUR_IN_AGC 0x40000000 /* Spur filter in AGC detector */ 2389#define AR5K_PHY_TIMING_11_USE_SPUR_IN_AGC 0x40000000 /* Spur filter in AGC detector */
2404#define AR_PHY_TIMING_11_USE_SPUR_IN_SELFCOR 0x80000000 /* Spur filter in OFDM self correlator */ 2390#define AR5K_PHY_TIMING_11_USE_SPUR_IN_SELFCOR 0x80000000 /* Spur filter in OFDM self correlator */
2405 2391
2406/* 2392/*
2407 * Gain tables 2393 * Gain tables
@@ -2483,17 +2469,7 @@
2483#define AR5K_PHY_SDELAY 0x99f4 2469#define AR5K_PHY_SDELAY 0x99f4
2484#define AR5K_PHY_SDELAY_32MHZ 0x000000ff 2470#define AR5K_PHY_SDELAY_32MHZ 0x000000ff
2485#define AR5K_PHY_SPENDING 0x99f8 2471#define AR5K_PHY_SPENDING 0x99f8
2486#define AR5K_PHY_SPENDING_14 0x00000014 2472
2487#define AR5K_PHY_SPENDING_18 0x00000018
2488#define AR5K_PHY_SPENDING_RF5111 0x00000018
2489#define AR5K_PHY_SPENDING_RF5112 0x00000014
2490/* #define AR5K_PHY_SPENDING_RF5112A 0x0000000e */
2491/* #define AR5K_PHY_SPENDING_RF5424 0x00000012 */
2492#define AR5K_PHY_SPENDING_RF5413 0x00000018
2493#define AR5K_PHY_SPENDING_RF2413 0x00000018
2494#define AR5K_PHY_SPENDING_RF2316 0x00000018
2495#define AR5K_PHY_SPENDING_RF2317 0x00000018
2496#define AR5K_PHY_SPENDING_RF2425 0x00000014
2497 2473
2498/* 2474/*
2499 * PHY PAPD I (power?) table (?) 2475 * PHY PAPD I (power?) table (?)
@@ -2505,11 +2481,7 @@
2505/* 2481/*
2506 * PHY PCDAC TX power table 2482 * PHY PCDAC TX power table
2507 */ 2483 */
2508#define AR5K_PHY_PCDAC_TXPOWER_BASE_5211 0xa180 2484#define AR5K_PHY_PCDAC_TXPOWER_BASE 0xa180
2509#define AR5K_PHY_PCDAC_TXPOWER_BASE_2413 0xa280
2510#define AR5K_PHY_PCDAC_TXPOWER_BASE (ah->ah_radio >= AR5K_RF2413 ? \
2511 AR5K_PHY_PCDAC_TXPOWER_BASE_2413 :\
2512 AR5K_PHY_PCDAC_TXPOWER_BASE_5211)
2513#define AR5K_PHY_PCDAC_TXPOWER(_n) (AR5K_PHY_PCDAC_TXPOWER_BASE + ((_n) << 2)) 2485#define AR5K_PHY_PCDAC_TXPOWER(_n) (AR5K_PHY_PCDAC_TXPOWER_BASE + ((_n) << 2))
2514 2486
2515/* 2487/*
@@ -2590,3 +2562,9 @@
2590#define AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_3_S 16 2562#define AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_3_S 16
2591#define AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_4 0x0FC00000 2563#define AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_4 0x0FC00000
2592#define AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_4_S 22 2564#define AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_4_S 22
2565
2566/*
2567 * PHY PDADC Tx power table
2568 */
2569#define AR5K_PHY_PDADC_TXPOWER_BASE 0xa280
2570#define AR5K_PHY_PDADC_TXPOWER(_n) (AR5K_PHY_PDADC_TXPOWER_BASE + ((_n) << 2))
diff --git a/drivers/net/wireless/ath5k/reset.c b/drivers/net/wireless/ath5k/reset.c
index dc2d7d8bdb7a..1531ccd35066 100644
--- a/drivers/net/wireless/ath5k/reset.c
+++ b/drivers/net/wireless/ath5k/reset.c
@@ -25,7 +25,8 @@
25 Reset functions and helpers 25 Reset functions and helpers
26\*****************************/ 26\*****************************/
27 27
28#include <linux/pci.h> 28#include <linux/pci.h> /* To determine if a card is pci-e */
29#include <linux/bitops.h> /* For get_bitmask_order */
29#include "ath5k.h" 30#include "ath5k.h"
30#include "reg.h" 31#include "reg.h"
31#include "base.h" 32#include "base.h"
@@ -37,10 +38,14 @@
37 * @ah: the &struct ath5k_hw 38 * @ah: the &struct ath5k_hw
38 * @channel: the currently set channel upon reset 39 * @channel: the currently set channel upon reset
39 * 40 *
40 * Write the OFDM timings for the AR5212 upon reset. This is a helper for 41 * Write the delta slope coefficient (used on pilot tracking ?) for OFDM
41 * ath5k_hw_reset(). This seems to tune the PLL a specified frequency 42 * operation on the AR5212 upon reset. This is a helper for ath5k_hw_reset().
42 * depending on the bandwidth of the channel.
43 * 43 *
44 * Since delta slope is floating point we split it on its exponent and
45 * mantissa and provide these values on hw.
46 *
47 * For more infos i think this patent is related
48 * http://www.freepatentsonline.com/7184495.html
44 */ 49 */
45static inline int ath5k_hw_write_ofdm_timings(struct ath5k_hw *ah, 50static inline int ath5k_hw_write_ofdm_timings(struct ath5k_hw *ah,
46 struct ieee80211_channel *channel) 51 struct ieee80211_channel *channel)
@@ -53,23 +58,34 @@ static inline int ath5k_hw_write_ofdm_timings(struct ath5k_hw *ah,
53 !(channel->hw_value & CHANNEL_OFDM)) 58 !(channel->hw_value & CHANNEL_OFDM))
54 BUG(); 59 BUG();
55 60
56 /* Seems there are two PLLs, one for baseband sampling and one 61 /* Get coefficient
57 * for tuning. Tuning basebands are 40 MHz or 80MHz when in 62 * ALGO: coef = (5 * clock * carrier_freq) / 2)
58 * turbo. */ 63 * we scale coef by shifting clock value by 24 for
59 clock = channel->hw_value & CHANNEL_TURBO ? 80 : 40; 64 * better precision since we use integers */
60 coef_scaled = ((5 * (clock << 24)) / 2) / 65 /* TODO: Half/quarter rate */
61 channel->center_freq; 66 clock = ath5k_hw_htoclock(1, channel->hw_value & CHANNEL_TURBO);
62 67
63 for (coef_exp = 31; coef_exp > 0; coef_exp--) 68 coef_scaled = ((5 * (clock << 24)) / 2) / channel->center_freq;
64 if ((coef_scaled >> coef_exp) & 0x1) 69
65 break; 70 /* Get exponent
71 * ALGO: coef_exp = 14 - highest set bit position */
72 coef_exp = get_bitmask_order(coef_scaled);
66 73
74 /* Doesn't make sense if it's zero*/
67 if (!coef_exp) 75 if (!coef_exp)
68 return -EINVAL; 76 return -EINVAL;
69 77
78 /* Note: we've shifted coef_scaled by 24 */
70 coef_exp = 14 - (coef_exp - 24); 79 coef_exp = 14 - (coef_exp - 24);
80
81
82 /* Get mantissa (significant digits)
83 * ALGO: coef_mant = floor(coef_scaled* 2^coef_exp+0.5) */
71 coef_man = coef_scaled + 84 coef_man = coef_scaled +
72 (1 << (24 - coef_exp - 1)); 85 (1 << (24 - coef_exp - 1));
86
87 /* Calculate delta slope coefficient exponent
88 * and mantissa (remove scaling) and set them on hw */
73 ds_coef_man = coef_man >> (24 - coef_exp); 89 ds_coef_man = coef_man >> (24 - coef_exp);
74 ds_coef_exp = coef_exp - 16; 90 ds_coef_exp = coef_exp - 16;
75 91
@@ -90,16 +106,23 @@ static int control_rates[] =
90 { 0, 1, 1, 1, 4, 4, 6, 6, 8, 8, 8, 8 }; 106 { 0, 1, 1, 1, 4, 4, 6, 6, 8, 8, 8, 8 };
91 107
92/** 108/**
93 * ath5k_hw_write_rate_duration - set rate duration during hw resets 109 * ath5k_hw_write_rate_duration - fill rate code to duration table
94 * 110 *
95 * @ah: the &struct ath5k_hw 111 * @ah: the &struct ath5k_hw
96 * @mode: one of enum ath5k_driver_mode 112 * @mode: one of enum ath5k_driver_mode
97 * 113 *
98 * Write the rate duration table upon hw reset. This is a helper for 114 * Write the rate code to duration table upon hw reset. This is a helper for
99 * ath5k_hw_reset(). It seems all this is doing is setting an ACK timeout for 115 * ath5k_hw_reset(). It seems all this is doing is setting an ACK timeout on
100 * the hardware for the current mode for each rate. The rates which are capable 116 * the hardware, based on current mode, for each rate. The rates which are
101 * of short preamble (802.11b rates 2Mbps, 5.5Mbps, and 11Mbps) have another 117 * capable of short preamble (802.11b rates 2Mbps, 5.5Mbps, and 11Mbps) have
102 * register for the short preamble ACK timeout calculation. 118 * different rate code so we write their value twice (one for long preample
119 * and one for short).
120 *
121 * Note: Band doesn't matter here, if we set the values for OFDM it works
122 * on both a and g modes. So all we have to do is set values for all g rates
123 * that include all OFDM and CCK rates. If we operate in turbo or xr/half/
124 * quarter rate mode, we need to use another set of bitrates (that's why we
125 * need the mode parameter) but we don't handle these proprietary modes yet.
103 */ 126 */
104static inline void ath5k_hw_write_rate_duration(struct ath5k_hw *ah, 127static inline void ath5k_hw_write_rate_duration(struct ath5k_hw *ah,
105 unsigned int mode) 128 unsigned int mode)
@@ -275,7 +298,8 @@ commit:
275} 298}
276 299
277/* 300/*
278 * Bring up MAC + PHY Chips 301 * Bring up MAC + PHY Chips and program PLL
302 * TODO: Half/Quarter rate support
279 */ 303 */
280int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial) 304int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial)
281{ 305{
@@ -333,7 +357,11 @@ int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial)
333 } 357 }
334 } else if (flags & CHANNEL_5GHZ) { 358 } else if (flags & CHANNEL_5GHZ) {
335 mode |= AR5K_PHY_MODE_FREQ_5GHZ; 359 mode |= AR5K_PHY_MODE_FREQ_5GHZ;
336 clock |= AR5K_PHY_PLL_40MHZ; 360
361 if (ah->ah_radio == AR5K_RF5413)
362 clock |= AR5K_PHY_PLL_40MHZ_5413;
363 else
364 clock |= AR5K_PHY_PLL_40MHZ;
337 365
338 if (flags & CHANNEL_OFDM) 366 if (flags & CHANNEL_OFDM)
339 mode |= AR5K_PHY_MODE_MOD_OFDM; 367 mode |= AR5K_PHY_MODE_MOD_OFDM;
@@ -391,10 +419,14 @@ int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial)
391 } 419 }
392 420
393 if (ah->ah_version != AR5K_AR5210) { 421 if (ah->ah_version != AR5K_AR5210) {
394 /* ...set the PHY operating mode */
395 ath5k_hw_reg_write(ah, clock, AR5K_PHY_PLL);
396 udelay(300);
397 422
423 /* ...update PLL if needed */
424 if (ath5k_hw_reg_read(ah, AR5K_PHY_PLL) != clock) {
425 ath5k_hw_reg_write(ah, clock, AR5K_PHY_PLL);
426 udelay(300);
427 }
428
429 /* ...set the PHY operating mode */
398 ath5k_hw_reg_write(ah, mode, AR5K_PHY_MODE); 430 ath5k_hw_reg_write(ah, mode, AR5K_PHY_MODE);
399 ath5k_hw_reg_write(ah, turbo, AR5K_PHY_TURBO); 431 ath5k_hw_reg_write(ah, turbo, AR5K_PHY_TURBO);
400 } 432 }
@@ -403,22 +435,393 @@ int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial)
403} 435}
404 436
405/* 437/*
438 * If there is an external 32KHz crystal available, use it
439 * as ref. clock instead of 32/40MHz clock and baseband clocks
440 * to save power during sleep or restore normal 32/40MHz
441 * operation.
442 *
443 * XXX: When operating on 32KHz certain PHY registers (27 - 31,
444 * 123 - 127) require delay on access.
445 */
446static void ath5k_hw_set_sleep_clock(struct ath5k_hw *ah, bool enable)
447{
448 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
449 u32 scal, spending, usec32;
450
451 /* Only set 32KHz settings if we have an external
452 * 32KHz crystal present */
453 if ((AR5K_EEPROM_HAS32KHZCRYSTAL(ee->ee_misc1) ||
454 AR5K_EEPROM_HAS32KHZCRYSTAL_OLD(ee->ee_misc1)) &&
455 enable) {
456
457 /* 1 usec/cycle */
458 AR5K_REG_WRITE_BITS(ah, AR5K_USEC_5211, AR5K_USEC_32, 1);
459 /* Set up tsf increment on each cycle */
460 AR5K_REG_WRITE_BITS(ah, AR5K_TSF_PARM, AR5K_TSF_PARM_INC, 61);
461
462 /* Set baseband sleep control registers
463 * and sleep control rate */
464 ath5k_hw_reg_write(ah, 0x1f, AR5K_PHY_SCR);
465
466 if ((ah->ah_radio == AR5K_RF5112) ||
467 (ah->ah_radio == AR5K_RF5413) ||
468 (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4)))
469 spending = 0x14;
470 else
471 spending = 0x18;
472 ath5k_hw_reg_write(ah, spending, AR5K_PHY_SPENDING);
473
474 if ((ah->ah_radio == AR5K_RF5112) ||
475 (ah->ah_radio == AR5K_RF5413) ||
476 (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4))) {
477 ath5k_hw_reg_write(ah, 0x26, AR5K_PHY_SLMT);
478 ath5k_hw_reg_write(ah, 0x0d, AR5K_PHY_SCAL);
479 ath5k_hw_reg_write(ah, 0x07, AR5K_PHY_SCLOCK);
480 ath5k_hw_reg_write(ah, 0x3f, AR5K_PHY_SDELAY);
481 AR5K_REG_WRITE_BITS(ah, AR5K_PCICFG,
482 AR5K_PCICFG_SLEEP_CLOCK_RATE, 0x02);
483 } else {
484 ath5k_hw_reg_write(ah, 0x0a, AR5K_PHY_SLMT);
485 ath5k_hw_reg_write(ah, 0x0c, AR5K_PHY_SCAL);
486 ath5k_hw_reg_write(ah, 0x03, AR5K_PHY_SCLOCK);
487 ath5k_hw_reg_write(ah, 0x20, AR5K_PHY_SDELAY);
488 AR5K_REG_WRITE_BITS(ah, AR5K_PCICFG,
489 AR5K_PCICFG_SLEEP_CLOCK_RATE, 0x03);
490 }
491
492 /* Enable sleep clock operation */
493 AR5K_REG_ENABLE_BITS(ah, AR5K_PCICFG,
494 AR5K_PCICFG_SLEEP_CLOCK_EN);
495
496 } else {
497
498 /* Disable sleep clock operation and
499 * restore default parameters */
500 AR5K_REG_DISABLE_BITS(ah, AR5K_PCICFG,
501 AR5K_PCICFG_SLEEP_CLOCK_EN);
502
503 AR5K_REG_WRITE_BITS(ah, AR5K_PCICFG,
504 AR5K_PCICFG_SLEEP_CLOCK_RATE, 0);
505
506 ath5k_hw_reg_write(ah, 0x1f, AR5K_PHY_SCR);
507 ath5k_hw_reg_write(ah, AR5K_PHY_SLMT_32MHZ, AR5K_PHY_SLMT);
508
509 if (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4))
510 scal = AR5K_PHY_SCAL_32MHZ_2417;
511 else if (ath5k_eeprom_is_hb63(ah))
512 scal = AR5K_PHY_SCAL_32MHZ_HB63;
513 else
514 scal = AR5K_PHY_SCAL_32MHZ;
515 ath5k_hw_reg_write(ah, scal, AR5K_PHY_SCAL);
516
517 ath5k_hw_reg_write(ah, AR5K_PHY_SCLOCK_32MHZ, AR5K_PHY_SCLOCK);
518 ath5k_hw_reg_write(ah, AR5K_PHY_SDELAY_32MHZ, AR5K_PHY_SDELAY);
519
520 if ((ah->ah_radio == AR5K_RF5112) ||
521 (ah->ah_radio == AR5K_RF5413) ||
522 (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4)))
523 spending = 0x14;
524 else
525 spending = 0x18;
526 ath5k_hw_reg_write(ah, spending, AR5K_PHY_SPENDING);
527
528 if ((ah->ah_radio == AR5K_RF5112) ||
529 (ah->ah_radio == AR5K_RF5413))
530 usec32 = 39;
531 else
532 usec32 = 31;
533 AR5K_REG_WRITE_BITS(ah, AR5K_USEC_5211, AR5K_USEC_32, usec32);
534
535 AR5K_REG_WRITE_BITS(ah, AR5K_TSF_PARM, AR5K_TSF_PARM_INC, 1);
536 }
537 return;
538}
539
540static bool ath5k_hw_chan_has_spur_noise(struct ath5k_hw *ah,
541 struct ieee80211_channel *channel)
542{
543 u8 refclk_freq;
544
545 if ((ah->ah_radio == AR5K_RF5112) ||
546 (ah->ah_radio == AR5K_RF5413) ||
547 (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4)))
548 refclk_freq = 40;
549 else
550 refclk_freq = 32;
551
552 if ((channel->center_freq % refclk_freq != 0) &&
553 ((channel->center_freq % refclk_freq < 10) ||
554 (channel->center_freq % refclk_freq > 22)))
555 return true;
556 else
557 return false;
558}
559
560/* TODO: Half/Quarter rate */
561static void ath5k_hw_tweak_initval_settings(struct ath5k_hw *ah,
562 struct ieee80211_channel *channel)
563{
564 if (ah->ah_version == AR5K_AR5212 &&
565 ah->ah_phy_revision >= AR5K_SREV_PHY_5212A) {
566
567 /* Setup ADC control */
568 ath5k_hw_reg_write(ah,
569 (AR5K_REG_SM(2,
570 AR5K_PHY_ADC_CTL_INBUFGAIN_OFF) |
571 AR5K_REG_SM(2,
572 AR5K_PHY_ADC_CTL_INBUFGAIN_ON) |
573 AR5K_PHY_ADC_CTL_PWD_DAC_OFF |
574 AR5K_PHY_ADC_CTL_PWD_ADC_OFF),
575 AR5K_PHY_ADC_CTL);
576
577
578
579 /* Disable barker RSSI threshold */
580 AR5K_REG_DISABLE_BITS(ah, AR5K_PHY_DAG_CCK_CTL,
581 AR5K_PHY_DAG_CCK_CTL_EN_RSSI_THR);
582
583 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_DAG_CCK_CTL,
584 AR5K_PHY_DAG_CCK_CTL_RSSI_THR, 2);
585
586 /* Set the mute mask */
587 ath5k_hw_reg_write(ah, 0x0000000f, AR5K_SEQ_MASK);
588 }
589
590 /* Clear PHY_BLUETOOTH to allow RX_CLEAR line debug */
591 if (ah->ah_phy_revision >= AR5K_SREV_PHY_5212B)
592 ath5k_hw_reg_write(ah, 0, AR5K_PHY_BLUETOOTH);
593
594 /* Enable DCU double buffering */
595 if (ah->ah_phy_revision > AR5K_SREV_PHY_5212B)
596 AR5K_REG_DISABLE_BITS(ah, AR5K_TXCFG,
597 AR5K_TXCFG_DCU_DBL_BUF_DIS);
598
599 /* Set DAC/ADC delays */
600 if (ah->ah_version == AR5K_AR5212) {
601 u32 scal;
602 if (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4))
603 scal = AR5K_PHY_SCAL_32MHZ_2417;
604 else if (ath5k_eeprom_is_hb63(ah))
605 scal = AR5K_PHY_SCAL_32MHZ_HB63;
606 else
607 scal = AR5K_PHY_SCAL_32MHZ;
608 ath5k_hw_reg_write(ah, scal, AR5K_PHY_SCAL);
609 }
610
611 /* Set fast ADC */
612 if ((ah->ah_radio == AR5K_RF5413) ||
613 (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4))) {
614 u32 fast_adc = true;
615
616 if (channel->center_freq == 2462 ||
617 channel->center_freq == 2467)
618 fast_adc = 0;
619
620 /* Only update if needed */
621 if (ath5k_hw_reg_read(ah, AR5K_PHY_FAST_ADC) != fast_adc)
622 ath5k_hw_reg_write(ah, fast_adc,
623 AR5K_PHY_FAST_ADC);
624 }
625
626 /* Fix for first revision of the RF5112 RF chipset */
627 if (ah->ah_radio == AR5K_RF5112 &&
628 ah->ah_radio_5ghz_revision <
629 AR5K_SREV_RAD_5112A) {
630 u32 data;
631 ath5k_hw_reg_write(ah, AR5K_PHY_CCKTXCTL_WORLD,
632 AR5K_PHY_CCKTXCTL);
633 if (channel->hw_value & CHANNEL_5GHZ)
634 data = 0xffb81020;
635 else
636 data = 0xffb80d20;
637 ath5k_hw_reg_write(ah, data, AR5K_PHY_FRAME_CTL);
638 }
639
640 if (ah->ah_mac_srev < AR5K_SREV_AR5211) {
641 u32 usec_reg;
642 /* 5311 has different tx/rx latency masks
643 * from 5211, since we deal 5311 the same
644 * as 5211 when setting initvals, shift
645 * values here to their proper locations */
646 usec_reg = ath5k_hw_reg_read(ah, AR5K_USEC_5211);
647 ath5k_hw_reg_write(ah, usec_reg & (AR5K_USEC_1 |
648 AR5K_USEC_32 |
649 AR5K_USEC_TX_LATENCY_5211 |
650 AR5K_REG_SM(29,
651 AR5K_USEC_RX_LATENCY_5210)),
652 AR5K_USEC_5211);
653 /* Clear QCU/DCU clock gating register */
654 ath5k_hw_reg_write(ah, 0, AR5K_QCUDCU_CLKGT);
655 /* Set DAC/ADC delays */
656 ath5k_hw_reg_write(ah, 0x08, AR5K_PHY_SCAL);
657 /* Enable PCU FIFO corruption ECO */
658 AR5K_REG_ENABLE_BITS(ah, AR5K_DIAG_SW_5211,
659 AR5K_DIAG_SW_ECO_ENABLE);
660 }
661}
662
663static void ath5k_hw_commit_eeprom_settings(struct ath5k_hw *ah,
664 struct ieee80211_channel *channel, u8 *ant, u8 ee_mode)
665{
666 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
667
668 /* Set CCK to OFDM power delta */
669 if (ah->ah_phy_revision >= AR5K_SREV_PHY_5212A) {
670 int16_t cck_ofdm_pwr_delta;
671
672 /* Adjust power delta for channel 14 */
673 if (channel->center_freq == 2484)
674 cck_ofdm_pwr_delta =
675 ((ee->ee_cck_ofdm_power_delta -
676 ee->ee_scaled_cck_delta) * 2) / 10;
677 else
678 cck_ofdm_pwr_delta =
679 (ee->ee_cck_ofdm_power_delta * 2) / 10;
680
681 if (channel->hw_value == CHANNEL_G)
682 ath5k_hw_reg_write(ah,
683 AR5K_REG_SM((ee->ee_cck_ofdm_power_delta * -1),
684 AR5K_PHY_TX_PWR_ADJ_CCK_GAIN_DELTA) |
685 AR5K_REG_SM((cck_ofdm_pwr_delta * -1),
686 AR5K_PHY_TX_PWR_ADJ_CCK_PCDAC_INDEX),
687 AR5K_PHY_TX_PWR_ADJ);
688 else
689 ath5k_hw_reg_write(ah, 0, AR5K_PHY_TX_PWR_ADJ);
690 }
691
692 /* Set antenna idle switch table */
693 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_ANT_CTL,
694 AR5K_PHY_ANT_CTL_SWTABLE_IDLE,
695 (ah->ah_antenna[ee_mode][0] |
696 AR5K_PHY_ANT_CTL_TXRX_EN));
697
698 /* Set antenna switch table */
699 ath5k_hw_reg_write(ah, ah->ah_antenna[ee_mode][ant[0]],
700 AR5K_PHY_ANT_SWITCH_TABLE_0);
701 ath5k_hw_reg_write(ah, ah->ah_antenna[ee_mode][ant[1]],
702 AR5K_PHY_ANT_SWITCH_TABLE_1);
703
704 /* Noise floor threshold */
705 ath5k_hw_reg_write(ah,
706 AR5K_PHY_NF_SVAL(ee->ee_noise_floor_thr[ee_mode]),
707 AR5K_PHY_NFTHRES);
708
709 if ((channel->hw_value & CHANNEL_TURBO) &&
710 (ah->ah_ee_version >= AR5K_EEPROM_VERSION_5_0)) {
711 /* Switch settling time (Turbo) */
712 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_SETTLING,
713 AR5K_PHY_SETTLING_SWITCH,
714 ee->ee_switch_settling_turbo[ee_mode]);
715
716 /* Tx/Rx attenuation (Turbo) */
717 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_GAIN,
718 AR5K_PHY_GAIN_TXRX_ATTEN,
719 ee->ee_atn_tx_rx_turbo[ee_mode]);
720
721 /* ADC/PGA desired size (Turbo) */
722 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_DESIRED_SIZE,
723 AR5K_PHY_DESIRED_SIZE_ADC,
724 ee->ee_adc_desired_size_turbo[ee_mode]);
725
726 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_DESIRED_SIZE,
727 AR5K_PHY_DESIRED_SIZE_PGA,
728 ee->ee_pga_desired_size_turbo[ee_mode]);
729
730 /* Tx/Rx margin (Turbo) */
731 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_GAIN_2GHZ,
732 AR5K_PHY_GAIN_2GHZ_MARGIN_TXRX,
733 ee->ee_margin_tx_rx_turbo[ee_mode]);
734
735 } else {
736 /* Switch settling time */
737 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_SETTLING,
738 AR5K_PHY_SETTLING_SWITCH,
739 ee->ee_switch_settling[ee_mode]);
740
741 /* Tx/Rx attenuation */
742 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_GAIN,
743 AR5K_PHY_GAIN_TXRX_ATTEN,
744 ee->ee_atn_tx_rx[ee_mode]);
745
746 /* ADC/PGA desired size */
747 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_DESIRED_SIZE,
748 AR5K_PHY_DESIRED_SIZE_ADC,
749 ee->ee_adc_desired_size[ee_mode]);
750
751 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_DESIRED_SIZE,
752 AR5K_PHY_DESIRED_SIZE_PGA,
753 ee->ee_pga_desired_size[ee_mode]);
754
755 /* Tx/Rx margin */
756 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_1)
757 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_GAIN_2GHZ,
758 AR5K_PHY_GAIN_2GHZ_MARGIN_TXRX,
759 ee->ee_margin_tx_rx[ee_mode]);
760 }
761
762 /* XPA delays */
763 ath5k_hw_reg_write(ah,
764 (ee->ee_tx_end2xpa_disable[ee_mode] << 24) |
765 (ee->ee_tx_end2xpa_disable[ee_mode] << 16) |
766 (ee->ee_tx_frm2xpa_enable[ee_mode] << 8) |
767 (ee->ee_tx_frm2xpa_enable[ee_mode]), AR5K_PHY_RF_CTL4);
768
769 /* XLNA delay */
770 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_RF_CTL3,
771 AR5K_PHY_RF_CTL3_TXE2XLNA_ON,
772 ee->ee_tx_end2xlna_enable[ee_mode]);
773
774 /* Thresh64 (ANI) */
775 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_NF,
776 AR5K_PHY_NF_THRESH62,
777 ee->ee_thr_62[ee_mode]);
778
779
780 /* False detect backoff for channels
781 * that have spur noise. Write the new
782 * cyclic power RSSI threshold. */
783 if (ath5k_hw_chan_has_spur_noise(ah, channel))
784 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_OFDM_SELFCORR,
785 AR5K_PHY_OFDM_SELFCORR_CYPWR_THR1,
786 AR5K_INIT_CYCRSSI_THR1 +
787 ee->ee_false_detect[ee_mode]);
788 else
789 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_OFDM_SELFCORR,
790 AR5K_PHY_OFDM_SELFCORR_CYPWR_THR1,
791 AR5K_INIT_CYCRSSI_THR1);
792
793 /* I/Q correction
794 * TODO: Per channel i/q infos ? */
795 AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ,
796 AR5K_PHY_IQ_CORR_ENABLE |
797 (ee->ee_i_cal[ee_mode] << AR5K_PHY_IQ_CORR_Q_I_COFF_S) |
798 ee->ee_q_cal[ee_mode]);
799
800 /* Heavy clipping -disable for now */
801 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_5_1)
802 ath5k_hw_reg_write(ah, 0, AR5K_PHY_HEAVY_CLIP_ENABLE);
803
804 return;
805}
806
807/*
406 * Main reset function 808 * Main reset function
407 */ 809 */
408int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, 810int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
409 struct ieee80211_channel *channel, bool change_channel) 811 struct ieee80211_channel *channel, bool change_channel)
410{ 812{
411 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; 813 u32 s_seq[10], s_ant, s_led[3], staid1_flags, tsf_up, tsf_lo;
412 struct pci_dev *pdev = ah->ah_sc->pdev; 814 u32 phy_tst1;
413 u32 data, s_seq, s_ant, s_led[3], dma_size; 815 u8 mode, freq, ee_mode, ant[2];
414 unsigned int i, mode, freq, ee_mode, ant[2]; 816 int i, ret;
415 int ret;
416 817
417 ATH5K_TRACE(ah->ah_sc); 818 ATH5K_TRACE(ah->ah_sc);
418 819
419 s_seq = 0;
420 s_ant = 0; 820 s_ant = 0;
421 ee_mode = 0; 821 ee_mode = 0;
822 staid1_flags = 0;
823 tsf_up = 0;
824 tsf_lo = 0;
422 freq = 0; 825 freq = 0;
423 mode = 0; 826 mode = 0;
424 827
@@ -427,48 +830,6 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
427 */ 830 */
428 /*DCU/Antenna selection not available on 5210*/ 831 /*DCU/Antenna selection not available on 5210*/
429 if (ah->ah_version != AR5K_AR5210) { 832 if (ah->ah_version != AR5K_AR5210) {
430 if (change_channel) {
431 /* Seq number for queue 0 -do this for all queues ? */
432 s_seq = ath5k_hw_reg_read(ah,
433 AR5K_QUEUE_DFS_SEQNUM(0));
434 /*Default antenna*/
435 s_ant = ath5k_hw_reg_read(ah, AR5K_DEFAULT_ANTENNA);
436 }
437 }
438
439 /*GPIOs*/
440 s_led[0] = ath5k_hw_reg_read(ah, AR5K_PCICFG) & AR5K_PCICFG_LEDSTATE;
441 s_led[1] = ath5k_hw_reg_read(ah, AR5K_GPIOCR);
442 s_led[2] = ath5k_hw_reg_read(ah, AR5K_GPIODO);
443
444 if (change_channel && ah->ah_rf_banks != NULL)
445 ath5k_hw_get_rf_gain(ah);
446
447
448 /*Wakeup the device*/
449 ret = ath5k_hw_nic_wakeup(ah, channel->hw_value, false);
450 if (ret)
451 return ret;
452
453 /*
454 * Initialize operating mode
455 */
456 ah->ah_op_mode = op_mode;
457
458 /*
459 * 5111/5112 Settings
460 * 5210 only comes with RF5110
461 */
462 if (ah->ah_version != AR5K_AR5210) {
463 if (ah->ah_radio != AR5K_RF5111 &&
464 ah->ah_radio != AR5K_RF5112 &&
465 ah->ah_radio != AR5K_RF5413 &&
466 ah->ah_radio != AR5K_RF2413 &&
467 ah->ah_radio != AR5K_RF2425) {
468 ATH5K_ERR(ah->ah_sc,
469 "invalid phy radio: %u\n", ah->ah_radio);
470 return -EINVAL;
471 }
472 833
473 switch (channel->hw_value & CHANNEL_MODES) { 834 switch (channel->hw_value & CHANNEL_MODES) {
474 case CHANNEL_A: 835 case CHANNEL_A:
@@ -491,8 +852,12 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
491 freq = AR5K_INI_RFGAIN_5GHZ; 852 freq = AR5K_INI_RFGAIN_5GHZ;
492 ee_mode = AR5K_EEPROM_MODE_11A; 853 ee_mode = AR5K_EEPROM_MODE_11A;
493 break; 854 break;
494 /*Is this ok on 5211 too ?*/
495 case CHANNEL_TG: 855 case CHANNEL_TG:
856 if (ah->ah_version == AR5K_AR5211) {
857 ATH5K_ERR(ah->ah_sc,
858 "TurboG mode not available on 5211");
859 return -EINVAL;
860 }
496 mode = AR5K_MODE_11G_TURBO; 861 mode = AR5K_MODE_11G_TURBO;
497 freq = AR5K_INI_RFGAIN_2GHZ; 862 freq = AR5K_INI_RFGAIN_2GHZ;
498 ee_mode = AR5K_EEPROM_MODE_11G; 863 ee_mode = AR5K_EEPROM_MODE_11G;
@@ -513,11 +878,93 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
513 return -EINVAL; 878 return -EINVAL;
514 } 879 }
515 880
516 /* PHY access enable */ 881 if (change_channel) {
517 ath5k_hw_reg_write(ah, AR5K_PHY_SHIFT_5GHZ, AR5K_PHY(0)); 882 /*
883 * Save frame sequence count
884 * For revs. after Oahu, only save
885 * seq num for DCU 0 (Global seq num)
886 */
887 if (ah->ah_mac_srev < AR5K_SREV_AR5211) {
888
889 for (i = 0; i < 10; i++)
890 s_seq[i] = ath5k_hw_reg_read(ah,
891 AR5K_QUEUE_DCU_SEQNUM(i));
892
893 } else {
894 s_seq[0] = ath5k_hw_reg_read(ah,
895 AR5K_QUEUE_DCU_SEQNUM(0));
896 }
897
898 /* TSF accelerates on AR5211 durring reset
899 * As a workaround save it here and restore
900 * it later so that it's back in time after
901 * reset. This way it'll get re-synced on the
902 * next beacon without breaking ad-hoc.
903 *
904 * On AR5212 TSF is almost preserved across a
905 * reset so it stays back in time anyway and
906 * we don't have to save/restore it.
907 *
908 * XXX: Since this breaks power saving we have
909 * to disable power saving until we receive the
910 * next beacon, so we can resync beacon timers */
911 if (ah->ah_version == AR5K_AR5211) {
912 tsf_up = ath5k_hw_reg_read(ah, AR5K_TSF_U32);
913 tsf_lo = ath5k_hw_reg_read(ah, AR5K_TSF_L32);
914 }
915 }
916
917 /* Save default antenna */
918 s_ant = ath5k_hw_reg_read(ah, AR5K_DEFAULT_ANTENNA);
518 919
920 if (ah->ah_version == AR5K_AR5212) {
921 /* Restore normal 32/40MHz clock operation
922 * to avoid register access delay on certain
923 * PHY registers */
924 ath5k_hw_set_sleep_clock(ah, false);
925
926 /* Since we are going to write rf buffer
927 * check if we have any pending gain_F
928 * optimization settings */
929 if (change_channel && ah->ah_rf_banks != NULL)
930 ath5k_hw_gainf_calibrate(ah);
931 }
519 } 932 }
520 933
934 /*GPIOs*/
935 s_led[0] = ath5k_hw_reg_read(ah, AR5K_PCICFG) &
936 AR5K_PCICFG_LEDSTATE;
937 s_led[1] = ath5k_hw_reg_read(ah, AR5K_GPIOCR);
938 s_led[2] = ath5k_hw_reg_read(ah, AR5K_GPIODO);
939
940 /* AR5K_STA_ID1 flags, only preserve antenna
941 * settings and ack/cts rate mode */
942 staid1_flags = ath5k_hw_reg_read(ah, AR5K_STA_ID1) &
943 (AR5K_STA_ID1_DEFAULT_ANTENNA |
944 AR5K_STA_ID1_DESC_ANTENNA |
945 AR5K_STA_ID1_RTS_DEF_ANTENNA |
946 AR5K_STA_ID1_ACKCTS_6MB |
947 AR5K_STA_ID1_BASE_RATE_11B |
948 AR5K_STA_ID1_SELFGEN_DEF_ANT);
949
950 /* Wakeup the device */
951 ret = ath5k_hw_nic_wakeup(ah, channel->hw_value, false);
952 if (ret)
953 return ret;
954
955 /*
956 * Initialize operating mode
957 */
958 ah->ah_op_mode = op_mode;
959
960 /* PHY access enable */
961 if (ah->ah_mac_srev >= AR5K_SREV_AR5211)
962 ath5k_hw_reg_write(ah, AR5K_PHY_SHIFT_5GHZ, AR5K_PHY(0));
963 else
964 ath5k_hw_reg_write(ah, AR5K_PHY_SHIFT_5GHZ | 0x40,
965 AR5K_PHY(0));
966
967 /* Write initial settings */
521 ret = ath5k_hw_write_initvals(ah, mode, change_channel); 968 ret = ath5k_hw_write_initvals(ah, mode, change_channel);
522 if (ret) 969 if (ret)
523 return ret; 970 return ret;
@@ -526,64 +973,23 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
526 * 5211/5212 Specific 973 * 5211/5212 Specific
527 */ 974 */
528 if (ah->ah_version != AR5K_AR5210) { 975 if (ah->ah_version != AR5K_AR5210) {
976
529 /* 977 /*
530 * Write initial RF gain settings 978 * Write initial RF gain settings
531 * This should work for both 5111/5112 979 * This should work for both 5111/5112
532 */ 980 */
533 ret = ath5k_hw_rfgain(ah, freq); 981 ret = ath5k_hw_rfgain_init(ah, freq);
534 if (ret) 982 if (ret)
535 return ret; 983 return ret;
536 984
537 mdelay(1); 985 mdelay(1);
538 986
539 /* 987 /*
540 * Write some more initial register settings for revised chips 988 * Tweak initval settings for revised
989 * chipsets and add some more config
990 * bits
541 */ 991 */
542 if (ah->ah_version == AR5K_AR5212 && 992 ath5k_hw_tweak_initval_settings(ah, channel);
543 ah->ah_phy_revision > 0x41) {
544 ath5k_hw_reg_write(ah, 0x0002a002, 0x982c);
545
546 if (channel->hw_value == CHANNEL_G)
547 if (ah->ah_mac_srev < AR5K_SREV_AR2413)
548 ath5k_hw_reg_write(ah, 0x00f80d80,
549 0x994c);
550 else if (ah->ah_mac_srev < AR5K_SREV_AR5424)
551 ath5k_hw_reg_write(ah, 0x00380140,
552 0x994c);
553 else if (ah->ah_mac_srev < AR5K_SREV_AR2425)
554 ath5k_hw_reg_write(ah, 0x00fc0ec0,
555 0x994c);
556 else /* 2425 */
557 ath5k_hw_reg_write(ah, 0x00fc0fc0,
558 0x994c);
559 else
560 ath5k_hw_reg_write(ah, 0x00000000, 0x994c);
561
562 /* Got this from legacy-hal */
563 AR5K_REG_DISABLE_BITS(ah, 0xa228, 0x200);
564
565 AR5K_REG_MASKED_BITS(ah, 0xa228, 0x800, 0xfffe03ff);
566
567 /* Just write 0x9b5 ? */
568 /* ath5k_hw_reg_write(ah, 0x000009b5, 0xa228); */
569 ath5k_hw_reg_write(ah, 0x0000000f, AR5K_SEQ_MASK);
570 ath5k_hw_reg_write(ah, 0x00000000, 0xa254);
571 ath5k_hw_reg_write(ah, 0x0000000e, AR5K_PHY_SCAL);
572 }
573
574 /* Fix for first revision of the RF5112 RF chipset */
575 if (ah->ah_radio >= AR5K_RF5112 &&
576 ah->ah_radio_5ghz_revision <
577 AR5K_SREV_RAD_5112A) {
578 ath5k_hw_reg_write(ah, AR5K_PHY_CCKTXCTL_WORLD,
579 AR5K_PHY_CCKTXCTL);
580 if (channel->hw_value & CHANNEL_5GHZ)
581 data = 0xffb81020;
582 else
583 data = 0xffb80d20;
584 ath5k_hw_reg_write(ah, data, AR5K_PHY_FRAME_CTL);
585 data = 0;
586 }
587 993
588 /* 994 /*
589 * Set TX power (FIXME) 995 * Set TX power (FIXME)
@@ -601,15 +1007,12 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
601 ath5k_hw_write_rate_duration(ah, mode); 1007 ath5k_hw_write_rate_duration(ah, mode);
602 1008
603 /* 1009 /*
604 * Write RF registers 1010 * Write RF buffer
605 */ 1011 */
606 ret = ath5k_hw_rfregs(ah, channel, mode); 1012 ret = ath5k_hw_rfregs_init(ah, channel, mode);
607 if (ret) 1013 if (ret)
608 return ret; 1014 return ret;
609 1015
610 /*
611 * Configure additional registers
612 */
613 1016
614 /* Write OFDM timings on 5212*/ 1017 /* Write OFDM timings on 5212*/
615 if (ah->ah_version == AR5K_AR5212 && 1018 if (ah->ah_version == AR5K_AR5212 &&
@@ -631,17 +1034,6 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
631 } 1034 }
632 1035
633 /* 1036 /*
634 * Set channel and calibrate the PHY
635 */
636 ret = ath5k_hw_channel(ah, channel);
637 if (ret)
638 return ret;
639
640 /* Set antenna mode */
641 AR5K_REG_MASKED_BITS(ah, AR5K_PHY_ANT_CTL,
642 ah->ah_antenna[ee_mode][0], 0xfffffc06);
643
644 /*
645 * In case a fixed antenna was set as default 1037 * In case a fixed antenna was set as default
646 * write the same settings on both AR5K_PHY_ANT_SWITCH_TABLE 1038 * write the same settings on both AR5K_PHY_ANT_SWITCH_TABLE
647 * registers. 1039 * registers.
@@ -656,54 +1048,16 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
656 ant[1] = AR5K_ANT_FIXED_B; 1048 ant[1] = AR5K_ANT_FIXED_B;
657 } 1049 }
658 1050
659 ath5k_hw_reg_write(ah, ah->ah_antenna[ee_mode][ant[0]],
660 AR5K_PHY_ANT_SWITCH_TABLE_0);
661 ath5k_hw_reg_write(ah, ah->ah_antenna[ee_mode][ant[1]],
662 AR5K_PHY_ANT_SWITCH_TABLE_1);
663
664 /* Commit values from EEPROM */ 1051 /* Commit values from EEPROM */
665 if (ah->ah_radio == AR5K_RF5111) 1052 ath5k_hw_commit_eeprom_settings(ah, channel, ant, ee_mode);
666 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_FRAME_CTL,
667 AR5K_PHY_FRAME_CTL_TX_CLIP, ee->ee_tx_clip);
668
669 ath5k_hw_reg_write(ah,
670 AR5K_PHY_NF_SVAL(ee->ee_noise_floor_thr[ee_mode]),
671 AR5K_PHY_NFTHRES);
672
673 AR5K_REG_MASKED_BITS(ah, AR5K_PHY_SETTLING,
674 (ee->ee_switch_settling[ee_mode] << 7) & 0x3f80,
675 0xffffc07f);
676 AR5K_REG_MASKED_BITS(ah, AR5K_PHY_GAIN,
677 (ee->ee_atn_tx_rx[ee_mode] << 12) & 0x3f000,
678 0xfffc0fff);
679 AR5K_REG_MASKED_BITS(ah, AR5K_PHY_DESIRED_SIZE,
680 (ee->ee_adc_desired_size[ee_mode] & 0x00ff) |
681 ((ee->ee_pga_desired_size[ee_mode] << 8) & 0xff00),
682 0xffff0000);
683
684 ath5k_hw_reg_write(ah,
685 (ee->ee_tx_end2xpa_disable[ee_mode] << 24) |
686 (ee->ee_tx_end2xpa_disable[ee_mode] << 16) |
687 (ee->ee_tx_frm2xpa_enable[ee_mode] << 8) |
688 (ee->ee_tx_frm2xpa_enable[ee_mode]), AR5K_PHY_RF_CTL4);
689
690 AR5K_REG_MASKED_BITS(ah, AR5K_PHY_RF_CTL3,
691 ee->ee_tx_end2xlna_enable[ee_mode] << 8, 0xffff00ff);
692 AR5K_REG_MASKED_BITS(ah, AR5K_PHY_NF,
693 (ee->ee_thr_62[ee_mode] << 12) & 0x7f000, 0xfff80fff);
694 AR5K_REG_MASKED_BITS(ah, AR5K_PHY_OFDM_SELFCORR, 4, 0xffffff01);
695
696 AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ,
697 AR5K_PHY_IQ_CORR_ENABLE |
698 (ee->ee_i_cal[ee_mode] << AR5K_PHY_IQ_CORR_Q_I_COFF_S) |
699 ee->ee_q_cal[ee_mode]);
700
701 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_1)
702 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_GAIN_2GHZ,
703 AR5K_PHY_GAIN_2GHZ_MARGIN_TXRX,
704 ee->ee_margin_tx_rx[ee_mode]);
705 1053
706 } else { 1054 } else {
1055 /*
1056 * For 5210 we do all initialization using
1057 * initvals, so we don't have to modify
1058 * any settings (5210 also only supports
1059 * a/aturbo modes)
1060 */
707 mdelay(1); 1061 mdelay(1);
708 /* Disable phy and wait */ 1062 /* Disable phy and wait */
709 ath5k_hw_reg_write(ah, AR5K_PHY_ACT_DISABLE, AR5K_PHY_ACT); 1063 ath5k_hw_reg_write(ah, AR5K_PHY_ACT_DISABLE, AR5K_PHY_ACT);
@@ -713,100 +1067,154 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
713 /* 1067 /*
714 * Restore saved values 1068 * Restore saved values
715 */ 1069 */
1070
716 /*DCU/Antenna selection not available on 5210*/ 1071 /*DCU/Antenna selection not available on 5210*/
717 if (ah->ah_version != AR5K_AR5210) { 1072 if (ah->ah_version != AR5K_AR5210) {
718 ath5k_hw_reg_write(ah, s_seq, AR5K_QUEUE_DFS_SEQNUM(0)); 1073
1074 if (change_channel) {
1075 if (ah->ah_mac_srev < AR5K_SREV_AR5211) {
1076 for (i = 0; i < 10; i++)
1077 ath5k_hw_reg_write(ah, s_seq[i],
1078 AR5K_QUEUE_DCU_SEQNUM(i));
1079 } else {
1080 ath5k_hw_reg_write(ah, s_seq[0],
1081 AR5K_QUEUE_DCU_SEQNUM(0));
1082 }
1083
1084
1085 if (ah->ah_version == AR5K_AR5211) {
1086 ath5k_hw_reg_write(ah, tsf_up, AR5K_TSF_U32);
1087 ath5k_hw_reg_write(ah, tsf_lo, AR5K_TSF_L32);
1088 }
1089 }
1090
719 ath5k_hw_reg_write(ah, s_ant, AR5K_DEFAULT_ANTENNA); 1091 ath5k_hw_reg_write(ah, s_ant, AR5K_DEFAULT_ANTENNA);
720 } 1092 }
1093
1094 /* Ledstate */
721 AR5K_REG_ENABLE_BITS(ah, AR5K_PCICFG, s_led[0]); 1095 AR5K_REG_ENABLE_BITS(ah, AR5K_PCICFG, s_led[0]);
1096
1097 /* Gpio settings */
722 ath5k_hw_reg_write(ah, s_led[1], AR5K_GPIOCR); 1098 ath5k_hw_reg_write(ah, s_led[1], AR5K_GPIOCR);
723 ath5k_hw_reg_write(ah, s_led[2], AR5K_GPIODO); 1099 ath5k_hw_reg_write(ah, s_led[2], AR5K_GPIODO);
724 1100
1101 /* Restore sta_id flags and preserve our mac address*/
1102 ath5k_hw_reg_write(ah, AR5K_LOW_ID(ah->ah_sta_id),
1103 AR5K_STA_ID0);
1104 ath5k_hw_reg_write(ah, staid1_flags | AR5K_HIGH_ID(ah->ah_sta_id),
1105 AR5K_STA_ID1);
1106
1107
725 /* 1108 /*
726 * Misc 1109 * Configure PCU
727 */ 1110 */
1111
1112 /* Restore bssid and bssid mask */
728 /* XXX: add ah->aid once mac80211 gives this to us */ 1113 /* XXX: add ah->aid once mac80211 gives this to us */
729 ath5k_hw_set_associd(ah, ah->ah_bssid, 0); 1114 ath5k_hw_set_associd(ah, ah->ah_bssid, 0);
730 1115
1116 /* Set PCU config */
731 ath5k_hw_set_opmode(ah); 1117 ath5k_hw_set_opmode(ah);
732 /*PISR/SISR Not available on 5210*/ 1118
733 if (ah->ah_version != AR5K_AR5210) { 1119 /* Clear any pending interrupts
1120 * PISR/SISR Not available on 5210 */
1121 if (ah->ah_version != AR5K_AR5210)
734 ath5k_hw_reg_write(ah, 0xffffffff, AR5K_PISR); 1122 ath5k_hw_reg_write(ah, 0xffffffff, AR5K_PISR);
735 /* If we later allow tuning for this, store into sc structure */ 1123
736 data = AR5K_TUNE_RSSI_THRES | 1124 /* Set RSSI/BRSSI thresholds
737 AR5K_TUNE_BMISS_THRES << AR5K_RSSI_THR_BMISS_S; 1125 *
738 ath5k_hw_reg_write(ah, data, AR5K_RSSI_THR); 1126 * Note: If we decide to set this value
1127 * dynamicaly, have in mind that when AR5K_RSSI_THR
1128 * register is read it might return 0x40 if we haven't
1129 * wrote anything to it plus BMISS RSSI threshold is zeroed.
1130 * So doing a save/restore procedure here isn't the right
1131 * choice. Instead store it on ath5k_hw */
1132 ath5k_hw_reg_write(ah, (AR5K_TUNE_RSSI_THRES |
1133 AR5K_TUNE_BMISS_THRES <<
1134 AR5K_RSSI_THR_BMISS_S),
1135 AR5K_RSSI_THR);
1136
1137 /* MIC QoS support */
1138 if (ah->ah_mac_srev >= AR5K_SREV_AR2413) {
1139 ath5k_hw_reg_write(ah, 0x000100aa, AR5K_MIC_QOS_CTL);
1140 ath5k_hw_reg_write(ah, 0x00003210, AR5K_MIC_QOS_SEL);
739 } 1141 }
740 1142
1143 /* QoS NOACK Policy */
1144 if (ah->ah_version == AR5K_AR5212) {
1145 ath5k_hw_reg_write(ah,
1146 AR5K_REG_SM(2, AR5K_QOS_NOACK_2BIT_VALUES) |
1147 AR5K_REG_SM(5, AR5K_QOS_NOACK_BIT_OFFSET) |
1148 AR5K_REG_SM(0, AR5K_QOS_NOACK_BYTE_OFFSET),
1149 AR5K_QOS_NOACK);
1150 }
1151
1152
741 /* 1153 /*
742 * Set Rx/Tx DMA Configuration 1154 * Configure PHY
743 *
744 * Set maximum DMA size (512) except for PCI-E cards since
745 * it causes rx overruns and tx errors (tested on 5424 but since
746 * rx overruns also occur on 5416/5418 with madwifi we set 128
747 * for all PCI-E cards to be safe).
748 *
749 * In dumps this is 128 for allchips.
750 *
751 * XXX: need to check 5210 for this
752 * TODO: Check out tx triger level, it's always 64 on dumps but I
753 * guess we can tweak it and see how it goes ;-)
754 */ 1155 */
755 dma_size = (pdev->is_pcie) ? AR5K_DMASIZE_128B : AR5K_DMASIZE_512B; 1156
756 if (ah->ah_version != AR5K_AR5210) { 1157 /* Set channel on PHY */
757 AR5K_REG_WRITE_BITS(ah, AR5K_TXCFG, 1158 ret = ath5k_hw_channel(ah, channel);
758 AR5K_TXCFG_SDMAMR, dma_size); 1159 if (ret)
759 AR5K_REG_WRITE_BITS(ah, AR5K_RXCFG, 1160 return ret;
760 AR5K_RXCFG_SDMAMW, dma_size);
761 }
762 1161
763 /* 1162 /*
764 * Enable the PHY and wait until completion 1163 * Enable the PHY and wait until completion
1164 * This includes BaseBand and Synthesizer
1165 * activation.
765 */ 1166 */
766 ath5k_hw_reg_write(ah, AR5K_PHY_ACT_ENABLE, AR5K_PHY_ACT); 1167 ath5k_hw_reg_write(ah, AR5K_PHY_ACT_ENABLE, AR5K_PHY_ACT);
767 1168
768 /* 1169 /*
769 * On 5211+ read activation -> rx delay 1170 * On 5211+ read activation -> rx delay
770 * and use it. 1171 * and use it.
1172 *
1173 * TODO: Half/quarter rate support
771 */ 1174 */
772 if (ah->ah_version != AR5K_AR5210) { 1175 if (ah->ah_version != AR5K_AR5210) {
773 data = ath5k_hw_reg_read(ah, AR5K_PHY_RX_DELAY) & 1176 u32 delay;
1177 delay = ath5k_hw_reg_read(ah, AR5K_PHY_RX_DELAY) &
774 AR5K_PHY_RX_DELAY_M; 1178 AR5K_PHY_RX_DELAY_M;
775 data = (channel->hw_value & CHANNEL_CCK) ? 1179 delay = (channel->hw_value & CHANNEL_CCK) ?
776 ((data << 2) / 22) : (data / 10); 1180 ((delay << 2) / 22) : (delay / 10);
777 1181
778 udelay(100 + (2 * data)); 1182 udelay(100 + (2 * delay));
779 data = 0;
780 } else { 1183 } else {
781 mdelay(1); 1184 mdelay(1);
782 } 1185 }
783 1186
784 /* 1187 /*
785 * Perform ADC test (?) 1188 * Perform ADC test to see if baseband is ready
1189 * Set tx hold and check adc test register
786 */ 1190 */
787 data = ath5k_hw_reg_read(ah, AR5K_PHY_TST1); 1191 phy_tst1 = ath5k_hw_reg_read(ah, AR5K_PHY_TST1);
788 ath5k_hw_reg_write(ah, AR5K_PHY_TST1_TXHOLD, AR5K_PHY_TST1); 1192 ath5k_hw_reg_write(ah, AR5K_PHY_TST1_TXHOLD, AR5K_PHY_TST1);
789 for (i = 0; i <= 20; i++) { 1193 for (i = 0; i <= 20; i++) {
790 if (!(ath5k_hw_reg_read(ah, AR5K_PHY_ADC_TEST) & 0x10)) 1194 if (!(ath5k_hw_reg_read(ah, AR5K_PHY_ADC_TEST) & 0x10))
791 break; 1195 break;
792 udelay(200); 1196 udelay(200);
793 } 1197 }
794 ath5k_hw_reg_write(ah, data, AR5K_PHY_TST1); 1198 ath5k_hw_reg_write(ah, phy_tst1, AR5K_PHY_TST1);
795 data = 0;
796 1199
797 /* 1200 /*
798 * Start automatic gain calibration 1201 * Start automatic gain control calibration
799 * 1202 *
800 * During AGC calibration RX path is re-routed to 1203 * During AGC calibration RX path is re-routed to
801 * a signal detector so we don't receive anything. 1204 * a power detector so we don't receive anything.
802 * 1205 *
803 * This method is used to calibrate some static offsets 1206 * This method is used to calibrate some static offsets
804 * used together with on-the fly I/Q calibration (the 1207 * used together with on-the fly I/Q calibration (the
805 * one performed via ath5k_hw_phy_calibrate), that doesn't 1208 * one performed via ath5k_hw_phy_calibrate), that doesn't
806 * interrupt rx path. 1209 * interrupt rx path.
807 * 1210 *
1211 * While rx path is re-routed to the power detector we also
1212 * start a noise floor calibration, to measure the
1213 * card's noise floor (the noise we measure when we are not
1214 * transmiting or receiving anything).
1215 *
808 * If we are in a noisy environment AGC calibration may time 1216 * If we are in a noisy environment AGC calibration may time
809 * out. 1217 * out and/or noise floor calibration might timeout.
810 */ 1218 */
811 AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_AGCCTL, 1219 AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_AGCCTL,
812 AR5K_PHY_AGCCTL_CAL); 1220 AR5K_PHY_AGCCTL_CAL);
@@ -828,30 +1236,37 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
828 AR5K_PHY_AGCCTL_CAL, 0, false)) { 1236 AR5K_PHY_AGCCTL_CAL, 0, false)) {
829 ATH5K_ERR(ah->ah_sc, "gain calibration timeout (%uMHz)\n", 1237 ATH5K_ERR(ah->ah_sc, "gain calibration timeout (%uMHz)\n",
830 channel->center_freq); 1238 channel->center_freq);
831 return -EAGAIN;
832 } 1239 }
833 1240
834 /* 1241 /*
835 * Start noise floor calibration
836 *
837 * If we run NF calibration before AGC, it always times out. 1242 * If we run NF calibration before AGC, it always times out.
838 * Binary HAL starts NF and AGC calibration at the same time 1243 * Binary HAL starts NF and AGC calibration at the same time
839 * and only waits for AGC to finish. I believe that's wrong because 1244 * and only waits for AGC to finish. Also if AGC or NF cal.
840 * during NF calibration, rx path is also routed to a detector, so if 1245 * times out, reset doesn't fail on binary HAL. I believe
841 * it doesn't finish we won't have RX. 1246 * that's wrong because since rx path is routed to a detector,
842 * 1247 * if cal. doesn't finish we won't have RX. Sam's HAL for AR5210/5211
843 * XXX: Find an interval that's OK for all cards... 1248 * enables noise floor calibration after offset calibration and if noise
1249 * floor calibration fails, reset fails. I believe that's
1250 * a better approach, we just need to find a polling interval
1251 * that suits best, even if reset continues we need to make
1252 * sure that rx path is ready.
844 */ 1253 */
845 ath5k_hw_noise_floor_calibration(ah, channel->center_freq); 1254 ath5k_hw_noise_floor_calibration(ah, channel->center_freq);
846 1255
1256
1257 /*
1258 * Configure QCUs/DCUs
1259 */
1260
1261 /* TODO: HW Compression support for data queues */
1262 /* TODO: Burst prefetch for data queues */
1263
847 /* 1264 /*
848 * Reset queues and start beacon timers at the end of the reset routine 1265 * Reset queues and start beacon timers at the end of the reset routine
1266 * This also sets QCU mask on each DCU for 1:1 qcu to dcu mapping
1267 * Note: If we want we can assign multiple qcus on one dcu.
849 */ 1268 */
850 for (i = 0; i < ah->ah_capabilities.cap_queues.q_tx_num; i++) { 1269 for (i = 0; i < ah->ah_capabilities.cap_queues.q_tx_num; i++) {
851 /*No QCU on 5210*/
852 if (ah->ah_version != AR5K_AR5210)
853 AR5K_REG_WRITE_Q(ah, AR5K_QUEUE_QCUMASK(i), i);
854
855 ret = ath5k_hw_reset_tx_queue(ah, i); 1270 ret = ath5k_hw_reset_tx_queue(ah, i);
856 if (ret) { 1271 if (ret) {
857 ATH5K_ERR(ah->ah_sc, 1272 ATH5K_ERR(ah->ah_sc,
@@ -860,14 +1275,40 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
860 } 1275 }
861 } 1276 }
862 1277
1278
1279 /*
1280 * Configure DMA/Interrupts
1281 */
1282
1283 /*
1284 * Set Rx/Tx DMA Configuration
1285 *
1286 * Set standard DMA size (128). Note that
1287 * a DMA size of 512 causes rx overruns and tx errors
1288 * on pci-e cards (tested on 5424 but since rx overruns
1289 * also occur on 5416/5418 with madwifi we set 128
1290 * for all PCI-E cards to be safe).
1291 *
1292 * XXX: need to check 5210 for this
1293 * TODO: Check out tx triger level, it's always 64 on dumps but I
1294 * guess we can tweak it and see how it goes ;-)
1295 */
1296 if (ah->ah_version != AR5K_AR5210) {
1297 AR5K_REG_WRITE_BITS(ah, AR5K_TXCFG,
1298 AR5K_TXCFG_SDMAMR, AR5K_DMASIZE_128B);
1299 AR5K_REG_WRITE_BITS(ah, AR5K_RXCFG,
1300 AR5K_RXCFG_SDMAMW, AR5K_DMASIZE_128B);
1301 }
1302
863 /* Pre-enable interrupts on 5211/5212*/ 1303 /* Pre-enable interrupts on 5211/5212*/
864 if (ah->ah_version != AR5K_AR5210) 1304 if (ah->ah_version != AR5K_AR5210)
865 ath5k_hw_set_imr(ah, ah->ah_imr); 1305 ath5k_hw_set_imr(ah, ah->ah_imr);
866 1306
867 /* 1307 /*
868 * Set RF kill flags if supported by the device (read from the EEPROM) 1308 * Setup RFKill interrupt if rfkill flag is set on eeprom.
869 * Disable gpio_intr for now since it results system hang. 1309 * TODO: Use gpio pin and polarity infos from eeprom
870 * TODO: Handle this in ath5k_intr 1310 * TODO: Handle this in ath5k_intr because it'll result
1311 * a nasty interrupt storm.
871 */ 1312 */
872#if 0 1313#if 0
873 if (AR5K_EEPROM_HDR_RFKILL(ah->ah_capabilities.cap_eeprom.ee_header)) { 1314 if (AR5K_EEPROM_HDR_RFKILL(ah->ah_capabilities.cap_eeprom.ee_header)) {
@@ -880,33 +1321,12 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
880 } 1321 }
881#endif 1322#endif
882 1323
883 /* 1324 /* Enable 32KHz clock function for AR5212+ chips
884 * Set the 32MHz reference clock on 5212 phy clock sleep register 1325 * Set clocks to 32KHz operation and use an
885 * 1326 * external 32KHz crystal when sleeping if one
886 * TODO: Find out how to switch to external 32Khz clock to save power 1327 * exists */
887 */ 1328 if (ah->ah_version == AR5K_AR5212)
888 if (ah->ah_version == AR5K_AR5212) { 1329 ath5k_hw_set_sleep_clock(ah, true);
889 ath5k_hw_reg_write(ah, AR5K_PHY_SCR_32MHZ, AR5K_PHY_SCR);
890 ath5k_hw_reg_write(ah, AR5K_PHY_SLMT_32MHZ, AR5K_PHY_SLMT);
891 ath5k_hw_reg_write(ah, AR5K_PHY_SCAL_32MHZ, AR5K_PHY_SCAL);
892 ath5k_hw_reg_write(ah, AR5K_PHY_SCLOCK_32MHZ, AR5K_PHY_SCLOCK);
893 ath5k_hw_reg_write(ah, AR5K_PHY_SDELAY_32MHZ, AR5K_PHY_SDELAY);
894 ath5k_hw_reg_write(ah, ah->ah_phy_spending, AR5K_PHY_SPENDING);
895
896 data = ath5k_hw_reg_read(ah, AR5K_USEC_5211) & 0xffffc07f ;
897 data |= (ah->ah_phy_spending == AR5K_PHY_SPENDING_18) ?
898 0x00000f80 : 0x00001380 ;
899 ath5k_hw_reg_write(ah, data, AR5K_USEC_5211);
900 data = 0;
901 }
902
903 if (ah->ah_version == AR5K_AR5212) {
904 ath5k_hw_reg_write(ah, 0x000100aa, 0x8118);
905 ath5k_hw_reg_write(ah, 0x00003210, 0x811c);
906 ath5k_hw_reg_write(ah, 0x00000052, 0x8108);
907 if (ah->ah_mac_srev >= AR5K_SREV_AR2413)
908 ath5k_hw_reg_write(ah, 0x00000004, 0x8120);
909 }
910 1330
911 /* 1331 /*
912 * Disable beacons and reset the register 1332 * Disable beacons and reset the register
diff --git a/drivers/net/wireless/ath5k/rfbuffer.h b/drivers/net/wireless/ath5k/rfbuffer.h
new file mode 100644
index 000000000000..e50baff66175
--- /dev/null
+++ b/drivers/net/wireless/ath5k/rfbuffer.h
@@ -0,0 +1,1181 @@
1/*
2 * RF Buffer handling functions
3 *
4 * Copyright (c) 2009 Nick Kossifidis <mickflemm@gmail.com>
5 *
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 *
18 */
19
20
21/*
22 * There are some special registers on the RF chip
23 * that control various operation settings related mostly to
24 * the analog parts (channel, gain adjustment etc).
25 *
26 * We don't write on those registers directly but
27 * we send a data packet on the chip, using a special register,
28 * that holds all the settings we need. After we 've sent the
29 * data packet, we write on another special register to notify hw
30 * to apply the settings. This is done so that control registers
31 * can be dynamicaly programmed during operation and the settings
32 * are applied faster on the hw.
33 *
34 * We call each data packet an "RF Bank" and all the data we write
35 * (all RF Banks) "RF Buffer". This file holds initial RF Buffer
36 * data for the different RF chips, and various info to match RF
37 * Buffer offsets with specific RF registers so that we can access
38 * them. We tweak these settings on rfregs_init function.
39 *
40 * Also check out reg.h and U.S. Patent 6677779 B1 (about buffer
41 * registers and control registers):
42 *
43 * http://www.google.com/patents?id=qNURAAAAEBAJ
44 */
45
46
47/*
48 * Struct to hold default mode specific RF
49 * register values (RF Banks)
50 */
51struct ath5k_ini_rfbuffer {
52 u8 rfb_bank; /* RF Bank number */
53 u16 rfb_ctrl_register; /* RF Buffer control register */
54 u32 rfb_mode_data[5]; /* RF Buffer data for each mode */
55};
56
57/*
58 * Struct to hold RF Buffer field
59 * infos used to access certain RF
60 * analog registers
61 */
62struct ath5k_rfb_field {
63 u8 len; /* Field length */
64 u16 pos; /* Offset on the raw packet */
65 u8 col; /* Column -used for shifting */
66};
67
68/*
69 * RF analog register definition
70 */
71struct ath5k_rf_reg {
72 u8 bank; /* RF Buffer Bank number */
73 u8 index; /* Register's index on rf_regs_idx */
74 struct ath5k_rfb_field field; /* RF Buffer field for this register */
75};
76
77/* Map RF registers to indexes
78 * We do this to handle common bits and make our
79 * life easier by using an index for each register
80 * instead of a full rfb_field */
81enum ath5k_rf_regs_idx {
82 /* BANK 6 */
83 AR5K_RF_OB_2GHZ = 0,
84 AR5K_RF_OB_5GHZ,
85 AR5K_RF_DB_2GHZ,
86 AR5K_RF_DB_5GHZ,
87 AR5K_RF_FIXED_BIAS_A,
88 AR5K_RF_FIXED_BIAS_B,
89 AR5K_RF_PWD_XPD,
90 AR5K_RF_XPD_SEL,
91 AR5K_RF_XPD_GAIN,
92 AR5K_RF_PD_GAIN_LO,
93 AR5K_RF_PD_GAIN_HI,
94 AR5K_RF_HIGH_VC_CP,
95 AR5K_RF_MID_VC_CP,
96 AR5K_RF_LOW_VC_CP,
97 AR5K_RF_PUSH_UP,
98 AR5K_RF_PAD2GND,
99 AR5K_RF_XB2_LVL,
100 AR5K_RF_XB5_LVL,
101 AR5K_RF_PWD_ICLOBUF_2G,
102 AR5K_RF_PWD_84,
103 AR5K_RF_PWD_90,
104 AR5K_RF_PWD_130,
105 AR5K_RF_PWD_131,
106 AR5K_RF_PWD_132,
107 AR5K_RF_PWD_136,
108 AR5K_RF_PWD_137,
109 AR5K_RF_PWD_138,
110 AR5K_RF_PWD_166,
111 AR5K_RF_PWD_167,
112 AR5K_RF_DERBY_CHAN_SEL_MODE,
113 /* BANK 7 */
114 AR5K_RF_GAIN_I,
115 AR5K_RF_PLO_SEL,
116 AR5K_RF_RFGAIN_SEL,
117 AR5K_RF_RFGAIN_STEP,
118 AR5K_RF_WAIT_S,
119 AR5K_RF_WAIT_I,
120 AR5K_RF_MAX_TIME,
121 AR5K_RF_MIXVGA_OVR,
122 AR5K_RF_MIXGAIN_OVR,
123 AR5K_RF_MIXGAIN_STEP,
124 AR5K_RF_PD_DELAY_A,
125 AR5K_RF_PD_DELAY_B,
126 AR5K_RF_PD_DELAY_XR,
127 AR5K_RF_PD_PERIOD_A,
128 AR5K_RF_PD_PERIOD_B,
129 AR5K_RF_PD_PERIOD_XR,
130};
131
132
133/*******************\
134* RF5111 (Sombrero) *
135\*******************/
136
137/* BANK 6 len pos col */
138#define AR5K_RF5111_OB_2GHZ { 3, 119, 0 }
139#define AR5K_RF5111_DB_2GHZ { 3, 122, 0 }
140
141#define AR5K_RF5111_OB_5GHZ { 3, 104, 0 }
142#define AR5K_RF5111_DB_5GHZ { 3, 107, 0 }
143
144#define AR5K_RF5111_PWD_XPD { 1, 95, 0 }
145#define AR5K_RF5111_XPD_GAIN { 4, 96, 0 }
146
147/* Access to PWD registers */
148#define AR5K_RF5111_PWD(_n) { 1, (135 - _n), 3 }
149
150/* BANK 7 len pos col */
151#define AR5K_RF5111_GAIN_I { 6, 29, 0 }
152#define AR5K_RF5111_PLO_SEL { 1, 4, 0 }
153#define AR5K_RF5111_RFGAIN_SEL { 1, 36, 0 }
154#define AR5K_RF5111_RFGAIN_STEP { 6, 37, 0 }
155/* Only on AR5212 BaseBand and up */
156#define AR5K_RF5111_WAIT_S { 5, 19, 0 }
157#define AR5K_RF5111_WAIT_I { 5, 24, 0 }
158#define AR5K_RF5111_MAX_TIME { 2, 49, 0 }
159
160static const struct ath5k_rf_reg rf_regs_5111[] = {
161 {6, AR5K_RF_OB_2GHZ, AR5K_RF5111_OB_2GHZ},
162 {6, AR5K_RF_DB_2GHZ, AR5K_RF5111_DB_2GHZ},
163 {6, AR5K_RF_OB_5GHZ, AR5K_RF5111_OB_5GHZ},
164 {6, AR5K_RF_DB_5GHZ, AR5K_RF5111_DB_5GHZ},
165 {6, AR5K_RF_PWD_XPD, AR5K_RF5111_PWD_XPD},
166 {6, AR5K_RF_XPD_GAIN, AR5K_RF5111_XPD_GAIN},
167 {6, AR5K_RF_PWD_84, AR5K_RF5111_PWD(84)},
168 {6, AR5K_RF_PWD_90, AR5K_RF5111_PWD(90)},
169 {7, AR5K_RF_GAIN_I, AR5K_RF5111_GAIN_I},
170 {7, AR5K_RF_PLO_SEL, AR5K_RF5111_PLO_SEL},
171 {7, AR5K_RF_RFGAIN_SEL, AR5K_RF5111_RFGAIN_SEL},
172 {7, AR5K_RF_RFGAIN_STEP, AR5K_RF5111_RFGAIN_STEP},
173 {7, AR5K_RF_WAIT_S, AR5K_RF5111_WAIT_S},
174 {7, AR5K_RF_WAIT_I, AR5K_RF5111_WAIT_I},
175 {7, AR5K_RF_MAX_TIME, AR5K_RF5111_MAX_TIME}
176};
177
178/* Default mode specific settings */
179static const struct ath5k_ini_rfbuffer rfb_5111[] = {
180 { 0, 0x989c,
181 /* mode a/XR mode aTurbo mode b mode g mode gTurbo */
182 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
183 { 0, 0x989c,
184 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
185 { 0, 0x989c,
186 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
187 { 0, 0x989c,
188 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
189 { 0, 0x989c,
190 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
191 { 0, 0x989c,
192 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
193 { 0, 0x989c,
194 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
195 { 0, 0x989c,
196 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
197 { 0, 0x989c,
198 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
199 { 0, 0x989c,
200 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
201 { 0, 0x989c,
202 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
203 { 0, 0x989c,
204 { 0x00380000, 0x00380000, 0x00380000, 0x00380000, 0x00380000 } },
205 { 0, 0x989c,
206 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
207 { 0, 0x989c,
208 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
209 { 0, 0x989c,
210 { 0x00000000, 0x00000000, 0x000000c0, 0x00000080, 0x00000080 } },
211 { 0, 0x989c,
212 { 0x000400f9, 0x000400f9, 0x000400ff, 0x000400fd, 0x000400fd } },
213 { 0, 0x98d4,
214 { 0x00000000, 0x00000000, 0x00000004, 0x00000004, 0x00000004 } },
215 { 1, 0x98d4,
216 { 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020 } },
217 { 2, 0x98d4,
218 { 0x00000010, 0x00000014, 0x00000010, 0x00000010, 0x00000014 } },
219 { 3, 0x98d8,
220 { 0x00601068, 0x00601068, 0x00601068, 0x00601068, 0x00601068 } },
221 { 6, 0x989c,
222 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
223 { 6, 0x989c,
224 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
225 { 6, 0x989c,
226 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
227 { 6, 0x989c,
228 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
229 { 6, 0x989c,
230 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
231 { 6, 0x989c,
232 { 0x10000000, 0x10000000, 0x10000000, 0x10000000, 0x10000000 } },
233 { 6, 0x989c,
234 { 0x04000000, 0x04000000, 0x04000000, 0x04000000, 0x04000000 } },
235 { 6, 0x989c,
236 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
237 { 6, 0x989c,
238 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
239 { 6, 0x989c,
240 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
241 { 6, 0x989c,
242 { 0x00000000, 0x00000000, 0x0a000000, 0x00000000, 0x00000000 } },
243 { 6, 0x989c,
244 { 0x003800c0, 0x00380080, 0x023800c0, 0x003800c0, 0x003800c0 } },
245 { 6, 0x989c,
246 { 0x00020006, 0x00020006, 0x00000006, 0x00020006, 0x00020006 } },
247 { 6, 0x989c,
248 { 0x00000089, 0x00000089, 0x00000089, 0x00000089, 0x00000089 } },
249 { 6, 0x989c,
250 { 0x000000a0, 0x000000a0, 0x000000a0, 0x000000a0, 0x000000a0 } },
251 { 6, 0x989c,
252 { 0x00040007, 0x00040007, 0x00040007, 0x00040007, 0x00040007 } },
253 { 6, 0x98d4,
254 { 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a } },
255 { 7, 0x989c,
256 { 0x00000040, 0x00000048, 0x00000040, 0x00000040, 0x00000040 } },
257 { 7, 0x989c,
258 { 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010 } },
259 { 7, 0x989c,
260 { 0x00000008, 0x00000008, 0x00000008, 0x00000008, 0x00000008 } },
261 { 7, 0x989c,
262 { 0x0000004f, 0x0000004f, 0x0000004f, 0x0000004f, 0x0000004f } },
263 { 7, 0x989c,
264 { 0x000000f1, 0x000000f1, 0x00000061, 0x000000f1, 0x000000f1 } },
265 { 7, 0x989c,
266 { 0x0000904f, 0x0000904f, 0x0000904c, 0x0000904f, 0x0000904f } },
267 { 7, 0x989c,
268 { 0x0000125a, 0x0000125a, 0x0000129a, 0x0000125a, 0x0000125a } },
269 { 7, 0x98cc,
270 { 0x0000000e, 0x0000000e, 0x0000000f, 0x0000000e, 0x0000000e } },
271};
272
273
274
275/***********************\
276* RF5112/RF2112 (Derby) *
277\***********************/
278
279/* BANK 7 (Common) len pos col */
280#define AR5K_RF5112X_GAIN_I { 6, 14, 0 }
281#define AR5K_RF5112X_MIXVGA_OVR { 1, 36, 0 }
282#define AR5K_RF5112X_MIXGAIN_OVR { 2, 37, 0 }
283#define AR5K_RF5112X_MIXGAIN_STEP { 4, 32, 0 }
284#define AR5K_RF5112X_PD_DELAY_A { 4, 58, 0 }
285#define AR5K_RF5112X_PD_DELAY_B { 4, 62, 0 }
286#define AR5K_RF5112X_PD_DELAY_XR { 4, 66, 0 }
287#define AR5K_RF5112X_PD_PERIOD_A { 4, 70, 0 }
288#define AR5K_RF5112X_PD_PERIOD_B { 4, 74, 0 }
289#define AR5K_RF5112X_PD_PERIOD_XR { 4, 78, 0 }
290
291/* RFX112 (Derby 1) */
292
293/* BANK 6 len pos col */
294#define AR5K_RF5112_OB_2GHZ { 3, 269, 0 }
295#define AR5K_RF5112_DB_2GHZ { 3, 272, 0 }
296
297#define AR5K_RF5112_OB_5GHZ { 3, 261, 0 }
298#define AR5K_RF5112_DB_5GHZ { 3, 264, 0 }
299
300#define AR5K_RF5112_FIXED_BIAS_A { 1, 260, 0 }
301#define AR5K_RF5112_FIXED_BIAS_B { 1, 259, 0 }
302
303#define AR5K_RF5112_XPD_SEL { 1, 284, 0 }
304#define AR5K_RF5112_XPD_GAIN { 2, 252, 0 }
305
306/* Access to PWD registers */
307#define AR5K_RF5112_PWD(_n) { 1, (302 - _n), 3 }
308
309static const struct ath5k_rf_reg rf_regs_5112[] = {
310 {6, AR5K_RF_OB_2GHZ, AR5K_RF5112_OB_2GHZ},
311 {6, AR5K_RF_DB_2GHZ, AR5K_RF5112_DB_2GHZ},
312 {6, AR5K_RF_OB_5GHZ, AR5K_RF5112_OB_5GHZ},
313 {6, AR5K_RF_DB_5GHZ, AR5K_RF5112_DB_5GHZ},
314 {6, AR5K_RF_FIXED_BIAS_A, AR5K_RF5112_FIXED_BIAS_A},
315 {6, AR5K_RF_FIXED_BIAS_B, AR5K_RF5112_FIXED_BIAS_B},
316 {6, AR5K_RF_XPD_SEL, AR5K_RF5112_XPD_SEL},
317 {6, AR5K_RF_XPD_GAIN, AR5K_RF5112_XPD_GAIN},
318 {6, AR5K_RF_PWD_130, AR5K_RF5112_PWD(130)},
319 {6, AR5K_RF_PWD_131, AR5K_RF5112_PWD(131)},
320 {6, AR5K_RF_PWD_132, AR5K_RF5112_PWD(132)},
321 {6, AR5K_RF_PWD_136, AR5K_RF5112_PWD(136)},
322 {6, AR5K_RF_PWD_137, AR5K_RF5112_PWD(137)},
323 {6, AR5K_RF_PWD_138, AR5K_RF5112_PWD(138)},
324 {7, AR5K_RF_GAIN_I, AR5K_RF5112X_GAIN_I},
325 {7, AR5K_RF_MIXVGA_OVR, AR5K_RF5112X_MIXVGA_OVR},
326 {7, AR5K_RF_MIXGAIN_OVR, AR5K_RF5112X_MIXGAIN_OVR},
327 {7, AR5K_RF_MIXGAIN_STEP, AR5K_RF5112X_MIXGAIN_STEP},
328 {7, AR5K_RF_PD_DELAY_A, AR5K_RF5112X_PD_DELAY_A},
329 {7, AR5K_RF_PD_DELAY_B, AR5K_RF5112X_PD_DELAY_B},
330 {7, AR5K_RF_PD_DELAY_XR, AR5K_RF5112X_PD_DELAY_XR},
331 {7, AR5K_RF_PD_PERIOD_A, AR5K_RF5112X_PD_PERIOD_A},
332 {7, AR5K_RF_PD_PERIOD_B, AR5K_RF5112X_PD_PERIOD_B},
333 {7, AR5K_RF_PD_PERIOD_XR, AR5K_RF5112X_PD_PERIOD_XR},
334};
335
336/* Default mode specific settings */
337static const struct ath5k_ini_rfbuffer rfb_5112[] = {
338 { 1, 0x98d4,
339 /* mode a/XR mode aTurbo mode b mode g mode gTurbo */
340 { 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020 } },
341 { 2, 0x98d0,
342 { 0x03060408, 0x03070408, 0x03060408, 0x03060408, 0x03070408 } },
343 { 3, 0x98dc,
344 { 0x00a0c0c0, 0x00a0c0c0, 0x00e0c0c0, 0x00e0c0c0, 0x00e0c0c0 } },
345 { 6, 0x989c,
346 { 0x00a00000, 0x00a00000, 0x00a00000, 0x00a00000, 0x00a00000 } },
347 { 6, 0x989c,
348 { 0x000a0000, 0x000a0000, 0x000a0000, 0x000a0000, 0x000a0000 } },
349 { 6, 0x989c,
350 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
351 { 6, 0x989c,
352 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
353 { 6, 0x989c,
354 { 0x00660000, 0x00660000, 0x00660000, 0x00660000, 0x00660000 } },
355 { 6, 0x989c,
356 { 0x00db0000, 0x00db0000, 0x00db0000, 0x00db0000, 0x00db0000 } },
357 { 6, 0x989c,
358 { 0x00f10000, 0x00f10000, 0x00f10000, 0x00f10000, 0x00f10000 } },
359 { 6, 0x989c,
360 { 0x00120000, 0x00120000, 0x00120000, 0x00120000, 0x00120000 } },
361 { 6, 0x989c,
362 { 0x00120000, 0x00120000, 0x00120000, 0x00120000, 0x00120000 } },
363 { 6, 0x989c,
364 { 0x00730000, 0x00730000, 0x00730000, 0x00730000, 0x00730000 } },
365 { 6, 0x989c,
366 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
367 { 6, 0x989c,
368 { 0x000c0000, 0x000c0000, 0x000c0000, 0x000c0000, 0x000c0000 } },
369 { 6, 0x989c,
370 { 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000 } },
371 { 6, 0x989c,
372 { 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000 } },
373 { 6, 0x989c,
374 { 0x008b0000, 0x008b0000, 0x008b0000, 0x008b0000, 0x008b0000 } },
375 { 6, 0x989c,
376 { 0x00600000, 0x00600000, 0x00600000, 0x00600000, 0x00600000 } },
377 { 6, 0x989c,
378 { 0x000c0000, 0x000c0000, 0x000c0000, 0x000c0000, 0x000c0000 } },
379 { 6, 0x989c,
380 { 0x00840000, 0x00840000, 0x00840000, 0x00840000, 0x00840000 } },
381 { 6, 0x989c,
382 { 0x00640000, 0x00640000, 0x00640000, 0x00640000, 0x00640000 } },
383 { 6, 0x989c,
384 { 0x00200000, 0x00200000, 0x00200000, 0x00200000, 0x00200000 } },
385 { 6, 0x989c,
386 { 0x00240000, 0x00240000, 0x00240000, 0x00240000, 0x00240000 } },
387 { 6, 0x989c,
388 { 0x00250000, 0x00250000, 0x00250000, 0x00250000, 0x00250000 } },
389 { 6, 0x989c,
390 { 0x00110000, 0x00110000, 0x00110000, 0x00110000, 0x00110000 } },
391 { 6, 0x989c,
392 { 0x00110000, 0x00110000, 0x00110000, 0x00110000, 0x00110000 } },
393 { 6, 0x989c,
394 { 0x00510000, 0x00510000, 0x00510000, 0x00510000, 0x00510000 } },
395 { 6, 0x989c,
396 { 0x1c040000, 0x1c040000, 0x1c040000, 0x1c040000, 0x1c040000 } },
397 { 6, 0x989c,
398 { 0x000a0000, 0x000a0000, 0x000a0000, 0x000a0000, 0x000a0000 } },
399 { 6, 0x989c,
400 { 0x00a10000, 0x00a10000, 0x00a10000, 0x00a10000, 0x00a10000 } },
401 { 6, 0x989c,
402 { 0x00400000, 0x00400000, 0x00400000, 0x00400000, 0x00400000 } },
403 { 6, 0x989c,
404 { 0x03090000, 0x03090000, 0x03090000, 0x03090000, 0x03090000 } },
405 { 6, 0x989c,
406 { 0x06000000, 0x06000000, 0x06000000, 0x06000000, 0x06000000 } },
407 { 6, 0x989c,
408 { 0x000000b0, 0x000000b0, 0x000000a8, 0x000000a8, 0x000000a8 } },
409 { 6, 0x989c,
410 { 0x0000002e, 0x0000002e, 0x0000002e, 0x0000002e, 0x0000002e } },
411 { 6, 0x989c,
412 { 0x006c4a41, 0x006c4a41, 0x006c4af1, 0x006c4a61, 0x006c4a61 } },
413 { 6, 0x989c,
414 { 0x0050892a, 0x0050892a, 0x0050892b, 0x0050892b, 0x0050892b } },
415 { 6, 0x989c,
416 { 0x00842400, 0x00842400, 0x00842400, 0x00842400, 0x00842400 } },
417 { 6, 0x989c,
418 { 0x00c69200, 0x00c69200, 0x00c69200, 0x00c69200, 0x00c69200 } },
419 { 6, 0x98d0,
420 { 0x0002000c, 0x0002000c, 0x0002000c, 0x0002000c, 0x0002000c } },
421 { 7, 0x989c,
422 { 0x00000094, 0x00000094, 0x00000094, 0x00000094, 0x00000094 } },
423 { 7, 0x989c,
424 { 0x00000091, 0x00000091, 0x00000091, 0x00000091, 0x00000091 } },
425 { 7, 0x989c,
426 { 0x0000000a, 0x0000000a, 0x00000012, 0x00000012, 0x00000012 } },
427 { 7, 0x989c,
428 { 0x00000080, 0x00000080, 0x00000080, 0x00000080, 0x00000080 } },
429 { 7, 0x989c,
430 { 0x000000c1, 0x000000c1, 0x000000c1, 0x000000c1, 0x000000c1 } },
431 { 7, 0x989c,
432 { 0x00000060, 0x00000060, 0x00000060, 0x00000060, 0x00000060 } },
433 { 7, 0x989c,
434 { 0x000000f0, 0x000000f0, 0x000000f0, 0x000000f0, 0x000000f0 } },
435 { 7, 0x989c,
436 { 0x00000022, 0x00000022, 0x00000022, 0x00000022, 0x00000022 } },
437 { 7, 0x989c,
438 { 0x00000092, 0x00000092, 0x00000092, 0x00000092, 0x00000092 } },
439 { 7, 0x989c,
440 { 0x000000d4, 0x000000d4, 0x000000d4, 0x000000d4, 0x000000d4 } },
441 { 7, 0x989c,
442 { 0x000014cc, 0x000014cc, 0x000014cc, 0x000014cc, 0x000014cc } },
443 { 7, 0x989c,
444 { 0x0000048c, 0x0000048c, 0x0000048c, 0x0000048c, 0x0000048c } },
445 { 7, 0x98c4,
446 { 0x00000003, 0x00000003, 0x00000003, 0x00000003, 0x00000003 } },
447};
448
449/* RFX112A (Derby 2) */
450
451/* BANK 6 len pos col */
452#define AR5K_RF5112A_OB_2GHZ { 3, 287, 0 }
453#define AR5K_RF5112A_DB_2GHZ { 3, 290, 0 }
454
455#define AR5K_RF5112A_OB_5GHZ { 3, 279, 0 }
456#define AR5K_RF5112A_DB_5GHZ { 3, 282, 0 }
457
458#define AR5K_RF5112A_FIXED_BIAS_A { 1, 278, 0 }
459#define AR5K_RF5112A_FIXED_BIAS_B { 1, 277, 0 }
460
461#define AR5K_RF5112A_XPD_SEL { 1, 302, 0 }
462#define AR5K_RF5112A_PDGAINLO { 2, 270, 0 }
463#define AR5K_RF5112A_PDGAINHI { 2, 257, 0 }
464
465/* Access to PWD registers */
466#define AR5K_RF5112A_PWD(_n) { 1, (306 - _n), 3 }
467
468/* Voltage regulators */
469#define AR5K_RF5112A_HIGH_VC_CP { 2, 90, 2 }
470#define AR5K_RF5112A_MID_VC_CP { 2, 92, 2 }
471#define AR5K_RF5112A_LOW_VC_CP { 2, 94, 2 }
472#define AR5K_RF5112A_PUSH_UP { 1, 254, 2 }
473
474/* Power consumption */
475#define AR5K_RF5112A_PAD2GND { 1, 281, 1 }
476#define AR5K_RF5112A_XB2_LVL { 2, 1, 3 }
477#define AR5K_RF5112A_XB5_LVL { 2, 3, 3 }
478
479static const struct ath5k_rf_reg rf_regs_5112a[] = {
480 {6, AR5K_RF_OB_2GHZ, AR5K_RF5112A_OB_2GHZ},
481 {6, AR5K_RF_DB_2GHZ, AR5K_RF5112A_DB_2GHZ},
482 {6, AR5K_RF_OB_5GHZ, AR5K_RF5112A_OB_5GHZ},
483 {6, AR5K_RF_DB_5GHZ, AR5K_RF5112A_DB_5GHZ},
484 {6, AR5K_RF_FIXED_BIAS_A, AR5K_RF5112A_FIXED_BIAS_A},
485 {6, AR5K_RF_FIXED_BIAS_B, AR5K_RF5112A_FIXED_BIAS_B},
486 {6, AR5K_RF_XPD_SEL, AR5K_RF5112A_XPD_SEL},
487 {6, AR5K_RF_PD_GAIN_LO, AR5K_RF5112A_PDGAINLO},
488 {6, AR5K_RF_PD_GAIN_HI, AR5K_RF5112A_PDGAINHI},
489 {6, AR5K_RF_PWD_130, AR5K_RF5112A_PWD(130)},
490 {6, AR5K_RF_PWD_131, AR5K_RF5112A_PWD(131)},
491 {6, AR5K_RF_PWD_132, AR5K_RF5112A_PWD(132)},
492 {6, AR5K_RF_PWD_136, AR5K_RF5112A_PWD(136)},
493 {6, AR5K_RF_PWD_137, AR5K_RF5112A_PWD(137)},
494 {6, AR5K_RF_PWD_138, AR5K_RF5112A_PWD(138)},
495 {6, AR5K_RF_PWD_166, AR5K_RF5112A_PWD(166)},
496 {6, AR5K_RF_PWD_167, AR5K_RF5112A_PWD(167)},
497 {6, AR5K_RF_HIGH_VC_CP, AR5K_RF5112A_HIGH_VC_CP},
498 {6, AR5K_RF_MID_VC_CP, AR5K_RF5112A_MID_VC_CP},
499 {6, AR5K_RF_LOW_VC_CP, AR5K_RF5112A_LOW_VC_CP},
500 {6, AR5K_RF_PUSH_UP, AR5K_RF5112A_PUSH_UP},
501 {6, AR5K_RF_PAD2GND, AR5K_RF5112A_PAD2GND},
502 {6, AR5K_RF_XB2_LVL, AR5K_RF5112A_XB2_LVL},
503 {6, AR5K_RF_XB5_LVL, AR5K_RF5112A_XB5_LVL},
504 {7, AR5K_RF_GAIN_I, AR5K_RF5112X_GAIN_I},
505 {7, AR5K_RF_MIXVGA_OVR, AR5K_RF5112X_MIXVGA_OVR},
506 {7, AR5K_RF_MIXGAIN_OVR, AR5K_RF5112X_MIXGAIN_OVR},
507 {7, AR5K_RF_MIXGAIN_STEP, AR5K_RF5112X_MIXGAIN_STEP},
508 {7, AR5K_RF_PD_DELAY_A, AR5K_RF5112X_PD_DELAY_A},
509 {7, AR5K_RF_PD_DELAY_B, AR5K_RF5112X_PD_DELAY_B},
510 {7, AR5K_RF_PD_DELAY_XR, AR5K_RF5112X_PD_DELAY_XR},
511 {7, AR5K_RF_PD_PERIOD_A, AR5K_RF5112X_PD_PERIOD_A},
512 {7, AR5K_RF_PD_PERIOD_B, AR5K_RF5112X_PD_PERIOD_B},
513 {7, AR5K_RF_PD_PERIOD_XR, AR5K_RF5112X_PD_PERIOD_XR},
514};
515
516/* Default mode specific settings */
517static const struct ath5k_ini_rfbuffer rfb_5112a[] = {
518 { 1, 0x98d4,
519 /* mode a/XR mode aTurbo mode b mode g mode gTurbo */
520 { 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020 } },
521 { 2, 0x98d0,
522 { 0x03060408, 0x03070408, 0x03060408, 0x03060408, 0x03070408 } },
523 { 3, 0x98dc,
524 { 0x00a020c0, 0x00a020c0, 0x00e020c0, 0x00e020c0, 0x00e020c0 } },
525 { 6, 0x989c,
526 { 0x0f000000, 0x0f000000, 0x0f000000, 0x0f000000, 0x0f000000 } },
527 { 6, 0x989c,
528 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
529 { 6, 0x989c,
530 { 0x00800000, 0x00800000, 0x00800000, 0x00800000, 0x00800000 } },
531 { 6, 0x989c,
532 { 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000 } },
533 { 6, 0x989c,
534 { 0x00010000, 0x00010000, 0x00010000, 0x00010000, 0x00010000 } },
535 { 6, 0x989c,
536 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
537 { 6, 0x989c,
538 { 0x00180000, 0x00180000, 0x00180000, 0x00180000, 0x00180000 } },
539 { 6, 0x989c,
540 { 0x00600000, 0x00600000, 0x006e0000, 0x006e0000, 0x006e0000 } },
541 { 6, 0x989c,
542 { 0x00c70000, 0x00c70000, 0x00c70000, 0x00c70000, 0x00c70000 } },
543 { 6, 0x989c,
544 { 0x004b0000, 0x004b0000, 0x004b0000, 0x004b0000, 0x004b0000 } },
545 { 6, 0x989c,
546 { 0x04480000, 0x04480000, 0x04480000, 0x04480000, 0x04480000 } },
547 { 6, 0x989c,
548 { 0x004c0000, 0x004c0000, 0x004c0000, 0x004c0000, 0x004c0000 } },
549 { 6, 0x989c,
550 { 0x00e40000, 0x00e40000, 0x00e40000, 0x00e40000, 0x00e40000 } },
551 { 6, 0x989c,
552 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
553 { 6, 0x989c,
554 { 0x00fc0000, 0x00fc0000, 0x00fc0000, 0x00fc0000, 0x00fc0000 } },
555 { 6, 0x989c,
556 { 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000 } },
557 { 6, 0x989c,
558 { 0x043f0000, 0x043f0000, 0x043f0000, 0x043f0000, 0x043f0000 } },
559 { 6, 0x989c,
560 { 0x000c0000, 0x000c0000, 0x000c0000, 0x000c0000, 0x000c0000 } },
561 { 6, 0x989c,
562 { 0x02190000, 0x02190000, 0x02190000, 0x02190000, 0x02190000 } },
563 { 6, 0x989c,
564 { 0x00240000, 0x00240000, 0x00240000, 0x00240000, 0x00240000 } },
565 { 6, 0x989c,
566 { 0x00b40000, 0x00b40000, 0x00b40000, 0x00b40000, 0x00b40000 } },
567 { 6, 0x989c,
568 { 0x00990000, 0x00990000, 0x00990000, 0x00990000, 0x00990000 } },
569 { 6, 0x989c,
570 { 0x00500000, 0x00500000, 0x00500000, 0x00500000, 0x00500000 } },
571 { 6, 0x989c,
572 { 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000 } },
573 { 6, 0x989c,
574 { 0x00120000, 0x00120000, 0x00120000, 0x00120000, 0x00120000 } },
575 { 6, 0x989c,
576 { 0xc0320000, 0xc0320000, 0xc0320000, 0xc0320000, 0xc0320000 } },
577 { 6, 0x989c,
578 { 0x01740000, 0x01740000, 0x01740000, 0x01740000, 0x01740000 } },
579 { 6, 0x989c,
580 { 0x00110000, 0x00110000, 0x00110000, 0x00110000, 0x00110000 } },
581 { 6, 0x989c,
582 { 0x86280000, 0x86280000, 0x86280000, 0x86280000, 0x86280000 } },
583 { 6, 0x989c,
584 { 0x31840000, 0x31840000, 0x31840000, 0x31840000, 0x31840000 } },
585 { 6, 0x989c,
586 { 0x00f20080, 0x00f20080, 0x00f20080, 0x00f20080, 0x00f20080 } },
587 { 6, 0x989c,
588 { 0x00270019, 0x00270019, 0x00270019, 0x00270019, 0x00270019 } },
589 { 6, 0x989c,
590 { 0x00000003, 0x00000003, 0x00000003, 0x00000003, 0x00000003 } },
591 { 6, 0x989c,
592 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
593 { 6, 0x989c,
594 { 0x000000b2, 0x000000b2, 0x000000b2, 0x000000b2, 0x000000b2 } },
595 { 6, 0x989c,
596 { 0x00b02084, 0x00b02084, 0x00b02084, 0x00b02084, 0x00b02084 } },
597 { 6, 0x989c,
598 { 0x004125a4, 0x004125a4, 0x004125a4, 0x004125a4, 0x004125a4 } },
599 { 6, 0x989c,
600 { 0x00119220, 0x00119220, 0x00119220, 0x00119220, 0x00119220 } },
601 { 6, 0x989c,
602 { 0x001a4800, 0x001a4800, 0x001a4800, 0x001a4800, 0x001a4800 } },
603 { 6, 0x98d8,
604 { 0x000b0230, 0x000b0230, 0x000b0230, 0x000b0230, 0x000b0230 } },
605 { 7, 0x989c,
606 { 0x00000094, 0x00000094, 0x00000094, 0x00000094, 0x00000094 } },
607 { 7, 0x989c,
608 { 0x00000091, 0x00000091, 0x00000091, 0x00000091, 0x00000091 } },
609 { 7, 0x989c,
610 { 0x00000012, 0x00000012, 0x00000012, 0x00000012, 0x00000012 } },
611 { 7, 0x989c,
612 { 0x00000080, 0x00000080, 0x00000080, 0x00000080, 0x00000080 } },
613 { 7, 0x989c,
614 { 0x000000d9, 0x000000d9, 0x000000d9, 0x000000d9, 0x000000d9 } },
615 { 7, 0x989c,
616 { 0x00000060, 0x00000060, 0x00000060, 0x00000060, 0x00000060 } },
617 { 7, 0x989c,
618 { 0x000000f0, 0x000000f0, 0x000000f0, 0x000000f0, 0x000000f0 } },
619 { 7, 0x989c,
620 { 0x000000a2, 0x000000a2, 0x000000a2, 0x000000a2, 0x000000a2 } },
621 { 7, 0x989c,
622 { 0x00000052, 0x00000052, 0x00000052, 0x00000052, 0x00000052 } },
623 { 7, 0x989c,
624 { 0x000000d4, 0x000000d4, 0x000000d4, 0x000000d4, 0x000000d4 } },
625 { 7, 0x989c,
626 { 0x000014cc, 0x000014cc, 0x000014cc, 0x000014cc, 0x000014cc } },
627 { 7, 0x989c,
628 { 0x0000048c, 0x0000048c, 0x0000048c, 0x0000048c, 0x0000048c } },
629 { 7, 0x98c4,
630 { 0x00000003, 0x00000003, 0x00000003, 0x00000003, 0x00000003 } },
631};
632
633
634
635/******************\
636* RF2413 (Griffin) *
637\******************/
638
639/* BANK 6 len pos col */
640#define AR5K_RF2413_OB_2GHZ { 3, 168, 0 }
641#define AR5K_RF2413_DB_2GHZ { 3, 165, 0 }
642
643static const struct ath5k_rf_reg rf_regs_2413[] = {
644 {6, AR5K_RF_OB_2GHZ, AR5K_RF2413_OB_2GHZ},
645 {6, AR5K_RF_DB_2GHZ, AR5K_RF2413_DB_2GHZ},
646};
647
648/* Default mode specific settings
649 * XXX: a/aTurbo ???
650 */
651static const struct ath5k_ini_rfbuffer rfb_2413[] = {
652 { 1, 0x98d4,
653 /* mode a/XR mode aTurbo mode b mode g mode gTurbo */
654 { 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020 } },
655 { 2, 0x98d0,
656 { 0x02001408, 0x02011408, 0x02001408, 0x02001408, 0x02011408 } },
657 { 3, 0x98dc,
658 { 0x00a020c0, 0x00a020c0, 0x00e020c0, 0x00e020c0, 0x00e020c0 } },
659 { 6, 0x989c,
660 { 0xf0000000, 0xf0000000, 0xf0000000, 0xf0000000, 0xf0000000 } },
661 { 6, 0x989c,
662 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
663 { 6, 0x989c,
664 { 0x03000000, 0x03000000, 0x03000000, 0x03000000, 0x03000000 } },
665 { 6, 0x989c,
666 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
667 { 6, 0x989c,
668 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
669 { 6, 0x989c,
670 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
671 { 6, 0x989c,
672 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
673 { 6, 0x989c,
674 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
675 { 6, 0x989c,
676 { 0x40400000, 0x40400000, 0x40400000, 0x40400000, 0x40400000 } },
677 { 6, 0x989c,
678 { 0x65050000, 0x65050000, 0x65050000, 0x65050000, 0x65050000 } },
679 { 6, 0x989c,
680 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
681 { 6, 0x989c,
682 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
683 { 6, 0x989c,
684 { 0x00420000, 0x00420000, 0x00420000, 0x00420000, 0x00420000 } },
685 { 6, 0x989c,
686 { 0x00b50000, 0x00b50000, 0x00b50000, 0x00b50000, 0x00b50000 } },
687 { 6, 0x989c,
688 { 0x00030000, 0x00030000, 0x00030000, 0x00030000, 0x00030000 } },
689 { 6, 0x989c,
690 { 0x00f70000, 0x00f70000, 0x00f70000, 0x00f70000, 0x00f70000 } },
691 { 6, 0x989c,
692 { 0x009d0000, 0x009d0000, 0x009d0000, 0x009d0000, 0x009d0000 } },
693 { 6, 0x989c,
694 { 0x00220000, 0x00220000, 0x00220000, 0x00220000, 0x00220000 } },
695 { 6, 0x989c,
696 { 0x04220000, 0x04220000, 0x04220000, 0x04220000, 0x04220000 } },
697 { 6, 0x989c,
698 { 0x00230018, 0x00230018, 0x00230018, 0x00230018, 0x00230018 } },
699 { 6, 0x989c,
700 { 0x00280000, 0x00280000, 0x00280060, 0x00280060, 0x00280060 } },
701 { 6, 0x989c,
702 { 0x005000c0, 0x005000c0, 0x005000c3, 0x005000c3, 0x005000c3 } },
703 { 6, 0x989c,
704 { 0x0004007f, 0x0004007f, 0x0004007f, 0x0004007f, 0x0004007f } },
705 { 6, 0x989c,
706 { 0x00000458, 0x00000458, 0x00000458, 0x00000458, 0x00000458 } },
707 { 6, 0x989c,
708 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
709 { 6, 0x989c,
710 { 0x0000c000, 0x0000c000, 0x0000c000, 0x0000c000, 0x0000c000 } },
711 { 6, 0x98d8,
712 { 0x00400230, 0x00400230, 0x00400230, 0x00400230, 0x00400230 } },
713 { 7, 0x989c,
714 { 0x00006400, 0x00006400, 0x00006400, 0x00006400, 0x00006400 } },
715 { 7, 0x989c,
716 { 0x00000800, 0x00000800, 0x00000800, 0x00000800, 0x00000800 } },
717 { 7, 0x98cc,
718 { 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e } },
719};
720
721
722
723/***************************\
724* RF2315/RF2316 (Cobra SoC) *
725\***************************/
726
727/* BANK 6 len pos col */
728#define AR5K_RF2316_OB_2GHZ { 3, 178, 0 }
729#define AR5K_RF2316_DB_2GHZ { 3, 175, 0 }
730
731static const struct ath5k_rf_reg rf_regs_2316[] = {
732 {6, AR5K_RF_OB_2GHZ, AR5K_RF2316_OB_2GHZ},
733 {6, AR5K_RF_DB_2GHZ, AR5K_RF2316_DB_2GHZ},
734};
735
736/* Default mode specific settings */
737static const struct ath5k_ini_rfbuffer rfb_2316[] = {
738 { 1, 0x98d4,
739 /* mode a/XR mode aTurbo mode b mode g mode gTurbo */
740 { 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020 } },
741 { 2, 0x98d0,
742 { 0x02001408, 0x02011408, 0x02001408, 0x02001408, 0x02011408 } },
743 { 3, 0x98dc,
744 { 0x00a020c0, 0x00a020c0, 0x00e020c0, 0x00e020c0, 0x00e020c0 } },
745 { 6, 0x989c,
746 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
747 { 6, 0x989c,
748 { 0xc0000000, 0xc0000000, 0xc0000000, 0xc0000000, 0xc0000000 } },
749 { 6, 0x989c,
750 { 0x0f000000, 0x0f000000, 0x0f000000, 0x0f000000, 0x0f000000 } },
751 { 6, 0x989c,
752 { 0x02000000, 0x02000000, 0x02000000, 0x02000000, 0x02000000 } },
753 { 6, 0x989c,
754 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
755 { 6, 0x989c,
756 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
757 { 6, 0x989c,
758 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
759 { 6, 0x989c,
760 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
761 { 6, 0x989c,
762 { 0xf8000000, 0xf8000000, 0xf8000000, 0xf8000000, 0xf8000000 } },
763 { 6, 0x989c,
764 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
765 { 6, 0x989c,
766 { 0x95150000, 0x95150000, 0x95150000, 0x95150000, 0x95150000 } },
767 { 6, 0x989c,
768 { 0xc1000000, 0xc1000000, 0xc1000000, 0xc1000000, 0xc1000000 } },
769 { 6, 0x989c,
770 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
771 { 6, 0x989c,
772 { 0x00080000, 0x00080000, 0x00080000, 0x00080000, 0x00080000 } },
773 { 6, 0x989c,
774 { 0x00d50000, 0x00d50000, 0x00d50000, 0x00d50000, 0x00d50000 } },
775 { 6, 0x989c,
776 { 0x000e0000, 0x000e0000, 0x000e0000, 0x000e0000, 0x000e0000 } },
777 { 6, 0x989c,
778 { 0x00dc0000, 0x00dc0000, 0x00dc0000, 0x00dc0000, 0x00dc0000 } },
779 { 6, 0x989c,
780 { 0x00770000, 0x00770000, 0x00770000, 0x00770000, 0x00770000 } },
781 { 6, 0x989c,
782 { 0x008a0000, 0x008a0000, 0x008a0000, 0x008a0000, 0x008a0000 } },
783 { 6, 0x989c,
784 { 0x10880000, 0x10880000, 0x10880000, 0x10880000, 0x10880000 } },
785 { 6, 0x989c,
786 { 0x008c0060, 0x008c0060, 0x008c0060, 0x008c0060, 0x008c0060 } },
787 { 6, 0x989c,
788 { 0x00a00000, 0x00a00000, 0x00a00080, 0x00a00080, 0x00a00080 } },
789 { 6, 0x989c,
790 { 0x00400000, 0x00400000, 0x0040000d, 0x0040000d, 0x0040000d } },
791 { 6, 0x989c,
792 { 0x00110400, 0x00110400, 0x00110400, 0x00110400, 0x00110400 } },
793 { 6, 0x989c,
794 { 0x00000060, 0x00000060, 0x00000060, 0x00000060, 0x00000060 } },
795 { 6, 0x989c,
796 { 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001 } },
797 { 6, 0x989c,
798 { 0x00000b00, 0x00000b00, 0x00000b00, 0x00000b00, 0x00000b00 } },
799 { 6, 0x989c,
800 { 0x00000be8, 0x00000be8, 0x00000be8, 0x00000be8, 0x00000be8 } },
801 { 6, 0x98c0,
802 { 0x00010000, 0x00010000, 0x00010000, 0x00010000, 0x00010000 } },
803 { 7, 0x989c,
804 { 0x00006400, 0x00006400, 0x00006400, 0x00006400, 0x00006400 } },
805 { 7, 0x989c,
806 { 0x00000800, 0x00000800, 0x00000800, 0x00000800, 0x00000800 } },
807 { 7, 0x98cc,
808 { 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e } },
809};
810
811
812
813/******************************\
814* RF5413/RF5424 (Eagle/Condor) *
815\******************************/
816
817/* BANK 6 len pos col */
818#define AR5K_RF5413_OB_2GHZ { 3, 241, 0 }
819#define AR5K_RF5413_DB_2GHZ { 3, 238, 0 }
820
821#define AR5K_RF5413_OB_5GHZ { 3, 247, 0 }
822#define AR5K_RF5413_DB_5GHZ { 3, 244, 0 }
823
824#define AR5K_RF5413_PWD_ICLOBUF2G { 3, 131, 3 }
825#define AR5K_RF5413_DERBY_CHAN_SEL_MODE { 1, 291, 2 }
826
827static const struct ath5k_rf_reg rf_regs_5413[] = {
828 {6, AR5K_RF_OB_2GHZ, AR5K_RF5413_OB_2GHZ},
829 {6, AR5K_RF_DB_2GHZ, AR5K_RF5413_DB_2GHZ},
830 {6, AR5K_RF_OB_5GHZ, AR5K_RF5413_OB_5GHZ},
831 {6, AR5K_RF_DB_5GHZ, AR5K_RF5413_DB_5GHZ},
832 {6, AR5K_RF_PWD_ICLOBUF_2G, AR5K_RF5413_PWD_ICLOBUF2G},
833 {6, AR5K_RF_DERBY_CHAN_SEL_MODE, AR5K_RF5413_DERBY_CHAN_SEL_MODE},
834};
835
836/* Default mode specific settings */
837static const struct ath5k_ini_rfbuffer rfb_5413[] = {
838 { 1, 0x98d4,
839 /* mode a/XR mode aTurbo mode b mode g mode gTurbo */
840 { 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020 } },
841 { 2, 0x98d0,
842 { 0x00000008, 0x00000008, 0x00000008, 0x00000008, 0x00000008 } },
843 { 3, 0x98dc,
844 { 0x00a000c0, 0x00a000c0, 0x00e000c0, 0x00e000c0, 0x00e000c0 } },
845 { 6, 0x989c,
846 { 0x33000000, 0x33000000, 0x33000000, 0x33000000, 0x33000000 } },
847 { 6, 0x989c,
848 { 0x01000000, 0x01000000, 0x01000000, 0x01000000, 0x01000000 } },
849 { 6, 0x989c,
850 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
851 { 6, 0x989c,
852 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
853 { 6, 0x989c,
854 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
855 { 6, 0x989c,
856 { 0x1f000000, 0x1f000000, 0x1f000000, 0x1f000000, 0x1f000000 } },
857 { 6, 0x989c,
858 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
859 { 6, 0x989c,
860 { 0x00b80000, 0x00b80000, 0x00b80000, 0x00b80000, 0x00b80000 } },
861 { 6, 0x989c,
862 { 0x00b70000, 0x00b70000, 0x00b70000, 0x00b70000, 0x00b70000 } },
863 { 6, 0x989c,
864 { 0x00840000, 0x00840000, 0x00840000, 0x00840000, 0x00840000 } },
865 { 6, 0x989c,
866 { 0x00980000, 0x00980000, 0x00980000, 0x00980000, 0x00980000 } },
867 { 6, 0x989c,
868 { 0x00c00000, 0x00c00000, 0x00c00000, 0x00c00000, 0x00c00000 } },
869 { 6, 0x989c,
870 { 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000 } },
871 { 6, 0x989c,
872 { 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000 } },
873 { 6, 0x989c,
874 { 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000 } },
875 { 6, 0x989c,
876 { 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000 } },
877 { 6, 0x989c,
878 { 0x00d70000, 0x00d70000, 0x00d70000, 0x00d70000, 0x00d70000 } },
879 { 6, 0x989c,
880 { 0x00610000, 0x00610000, 0x00610000, 0x00610000, 0x00610000 } },
881 { 6, 0x989c,
882 { 0x00fe0000, 0x00fe0000, 0x00fe0000, 0x00fe0000, 0x00fe0000 } },
883 { 6, 0x989c,
884 { 0x00de0000, 0x00de0000, 0x00de0000, 0x00de0000, 0x00de0000 } },
885 { 6, 0x989c,
886 { 0x007f0000, 0x007f0000, 0x007f0000, 0x007f0000, 0x007f0000 } },
887 { 6, 0x989c,
888 { 0x043d0000, 0x043d0000, 0x043d0000, 0x043d0000, 0x043d0000 } },
889 { 6, 0x989c,
890 { 0x00770000, 0x00770000, 0x00770000, 0x00770000, 0x00770000 } },
891 { 6, 0x989c,
892 { 0x00440000, 0x00440000, 0x00440000, 0x00440000, 0x00440000 } },
893 { 6, 0x989c,
894 { 0x00980000, 0x00980000, 0x00980000, 0x00980000, 0x00980000 } },
895 { 6, 0x989c,
896 { 0x00100080, 0x00100080, 0x00100080, 0x00100080, 0x00100080 } },
897 { 6, 0x989c,
898 { 0x0005c034, 0x0005c034, 0x0005c034, 0x0005c034, 0x0005c034 } },
899 { 6, 0x989c,
900 { 0x003100f0, 0x003100f0, 0x003100f0, 0x003100f0, 0x003100f0 } },
901 { 6, 0x989c,
902 { 0x000c011f, 0x000c011f, 0x000c011f, 0x000c011f, 0x000c011f } },
903 { 6, 0x989c,
904 { 0x00510040, 0x00510040, 0x00510040, 0x00510040, 0x00510040 } },
905 { 6, 0x989c,
906 { 0x005000da, 0x005000da, 0x005000da, 0x005000da, 0x005000da } },
907 { 6, 0x989c,
908 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
909 { 6, 0x989c,
910 { 0x00004044, 0x00004044, 0x00004044, 0x00004044, 0x00004044 } },
911 { 6, 0x989c,
912 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
913 { 6, 0x989c,
914 { 0x000060c0, 0x000060c0, 0x000060c0, 0x000060c0, 0x000060c0 } },
915 { 6, 0x989c,
916 { 0x00002c00, 0x00002c00, 0x00003600, 0x00003600, 0x00002c00 } },
917 { 6, 0x98c8,
918 { 0x00000403, 0x00000403, 0x00040403, 0x00040403, 0x00040403 } },
919 { 7, 0x989c,
920 { 0x00006400, 0x00006400, 0x00006400, 0x00006400, 0x00006400 } },
921 { 7, 0x989c,
922 { 0x00000800, 0x00000800, 0x00000800, 0x00000800, 0x00000800 } },
923 { 7, 0x98cc,
924 { 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e } },
925};
926
927
928
929/***************************\
930* RF2425/RF2417 (Swan/Nala) *
931* AR2317 (Spider SoC) *
932\***************************/
933
934/* BANK 6 len pos col */
935#define AR5K_RF2425_OB_2GHZ { 3, 193, 0 }
936#define AR5K_RF2425_DB_2GHZ { 3, 190, 0 }
937
938static const struct ath5k_rf_reg rf_regs_2425[] = {
939 {6, AR5K_RF_OB_2GHZ, AR5K_RF2425_OB_2GHZ},
940 {6, AR5K_RF_DB_2GHZ, AR5K_RF2425_DB_2GHZ},
941};
942
943/* Default mode specific settings
944 * XXX: a/aTurbo ?
945 */
946static const struct ath5k_ini_rfbuffer rfb_2425[] = {
947 { 1, 0x98d4,
948 /* mode a/XR mode aTurbo mode b mode g mode gTurbo */
949 { 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020 } },
950 { 2, 0x98d0,
951 { 0x02001408, 0x02001408, 0x02001408, 0x02001408, 0x02001408 } },
952 { 3, 0x98dc,
953 { 0x00a020c0, 0x00a020c0, 0x00e020c0, 0x00e020c0, 0x00e020c0 } },
954 { 6, 0x989c,
955 { 0x10000000, 0x10000000, 0x10000000, 0x10000000, 0x10000000 } },
956 { 6, 0x989c,
957 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
958 { 6, 0x989c,
959 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
960 { 6, 0x989c,
961 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
962 { 6, 0x989c,
963 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
964 { 6, 0x989c,
965 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
966 { 6, 0x989c,
967 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
968 { 6, 0x989c,
969 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
970 { 6, 0x989c,
971 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
972 { 6, 0x989c,
973 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
974 { 6, 0x989c,
975 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
976 { 6, 0x989c,
977 { 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000 } },
978 { 6, 0x989c,
979 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
980 { 6, 0x989c,
981 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
982 { 6, 0x989c,
983 { 0x00100000, 0x00100000, 0x00100000, 0x00100000, 0x00100000 } },
984 { 6, 0x989c,
985 { 0x00020000, 0x00020000, 0x00020000, 0x00020000, 0x00020000 } },
986 { 6, 0x989c,
987 { 0x00730000, 0x00730000, 0x00730000, 0x00730000, 0x00730000 } },
988 { 6, 0x989c,
989 { 0x00f80000, 0x00f80000, 0x00f80000, 0x00f80000, 0x00f80000 } },
990 { 6, 0x989c,
991 { 0x00e70000, 0x00e70000, 0x00e70000, 0x00e70000, 0x00e70000 } },
992 { 6, 0x989c,
993 { 0x00140000, 0x00140000, 0x00140000, 0x00140000, 0x00140000 } },
994 { 6, 0x989c,
995 { 0x00910040, 0x00910040, 0x00910040, 0x00910040, 0x00910040 } },
996 { 6, 0x989c,
997 { 0x0007001a, 0x0007001a, 0x0007001a, 0x0007001a, 0x0007001a } },
998 { 6, 0x989c,
999 { 0x00410000, 0x00410000, 0x00410000, 0x00410000, 0x00410000 } },
1000 { 6, 0x989c,
1001 { 0x00810000, 0x00810000, 0x00810060, 0x00810060, 0x00810060 } },
1002 { 6, 0x989c,
1003 { 0x00020800, 0x00020800, 0x00020803, 0x00020803, 0x00020803 } },
1004 { 6, 0x989c,
1005 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
1006 { 6, 0x989c,
1007 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
1008 { 6, 0x989c,
1009 { 0x00001660, 0x00001660, 0x00001660, 0x00001660, 0x00001660 } },
1010 { 6, 0x989c,
1011 { 0x00001688, 0x00001688, 0x00001688, 0x00001688, 0x00001688 } },
1012 { 6, 0x98c4,
1013 { 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001 } },
1014 { 7, 0x989c,
1015 { 0x00006400, 0x00006400, 0x00006400, 0x00006400, 0x00006400 } },
1016 { 7, 0x989c,
1017 { 0x00000800, 0x00000800, 0x00000800, 0x00000800, 0x00000800 } },
1018 { 7, 0x98cc,
1019 { 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e } },
1020};
1021
1022/*
1023 * TODO: Handle the few differences with swan during
1024 * bank modification and get rid of this
1025 */
1026static const struct ath5k_ini_rfbuffer rfb_2317[] = {
1027 { 1, 0x98d4,
1028 /* mode a/XR mode aTurbo mode b mode g mode gTurbo */
1029 { 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020 } },
1030 { 2, 0x98d0,
1031 { 0x02001408, 0x02011408, 0x02001408, 0x02001408, 0x02011408 } },
1032 { 3, 0x98dc,
1033 { 0x00a020c0, 0x00a020c0, 0x00e020c0, 0x00e020c0, 0x00e020c0 } },
1034 { 6, 0x989c,
1035 { 0x10000000, 0x10000000, 0x10000000, 0x10000000, 0x10000000 } },
1036 { 6, 0x989c,
1037 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
1038 { 6, 0x989c,
1039 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
1040 { 6, 0x989c,
1041 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
1042 { 6, 0x989c,
1043 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
1044 { 6, 0x989c,
1045 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
1046 { 6, 0x989c,
1047 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
1048 { 6, 0x989c,
1049 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
1050 { 6, 0x989c,
1051 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
1052 { 6, 0x989c,
1053 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
1054 { 6, 0x989c,
1055 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
1056 { 6, 0x989c,
1057 { 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000 } },
1058 { 6, 0x989c,
1059 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
1060 { 6, 0x989c,
1061 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
1062 { 6, 0x989c,
1063 { 0x00100000, 0x00100000, 0x00100000, 0x00100000, 0x00100000 } },
1064 { 6, 0x989c,
1065 { 0x00020000, 0x00020000, 0x00020000, 0x00020000, 0x00020000 } },
1066 { 6, 0x989c,
1067 { 0x00730000, 0x00730000, 0x00730000, 0x00730000, 0x00730000 } },
1068 { 6, 0x989c,
1069 { 0x00f80000, 0x00f80000, 0x00f80000, 0x00f80000, 0x00f80000 } },
1070 { 6, 0x989c,
1071 { 0x00e70000, 0x00e70000, 0x00e70000, 0x00e70000, 0x00e70000 } },
1072 { 6, 0x989c,
1073 { 0x00140100, 0x00140100, 0x00140100, 0x00140100, 0x00140100 } },
1074 { 6, 0x989c,
1075 { 0x00910040, 0x00910040, 0x00910040, 0x00910040, 0x00910040 } },
1076 { 6, 0x989c,
1077 { 0x0007001a, 0x0007001a, 0x0007001a, 0x0007001a, 0x0007001a } },
1078 { 6, 0x989c,
1079 { 0x00410000, 0x00410000, 0x00410000, 0x00410000, 0x00410000 } },
1080 { 6, 0x989c,
1081 { 0x00810000, 0x00810000, 0x00810060, 0x00810060, 0x00810060 } },
1082 { 6, 0x989c,
1083 { 0x00020800, 0x00020800, 0x00020803, 0x00020803, 0x00020803 } },
1084 { 6, 0x989c,
1085 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
1086 { 6, 0x989c,
1087 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
1088 { 6, 0x989c,
1089 { 0x00001660, 0x00001660, 0x00001660, 0x00001660, 0x00001660 } },
1090 { 6, 0x989c,
1091 { 0x00009688, 0x00009688, 0x00009688, 0x00009688, 0x00009688 } },
1092 { 6, 0x98c4,
1093 { 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001 } },
1094 { 7, 0x989c,
1095 { 0x00006400, 0x00006400, 0x00006400, 0x00006400, 0x00006400 } },
1096 { 7, 0x989c,
1097 { 0x00000800, 0x00000800, 0x00000800, 0x00000800, 0x00000800 } },
1098 { 7, 0x98cc,
1099 { 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e } },
1100};
1101
1102/*
1103 * TODO: Handle the few differences with swan during
1104 * bank modification and get rid of this
1105 * XXX: a/aTurbo ?
1106 */
1107static const struct ath5k_ini_rfbuffer rfb_2417[] = {
1108 { 1, 0x98d4,
1109 /* mode a/XR mode aTurbo mode b mode g mode gTurbo */
1110 { 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020 } },
1111 { 2, 0x98d0,
1112 { 0x02001408, 0x02001408, 0x02001408, 0x02001408, 0x02001408 } },
1113 { 3, 0x98dc,
1114 { 0x00a020c0, 0x00a020c0, 0x00e020c0, 0x00e020c0, 0x00e020c0 } },
1115 { 6, 0x989c,
1116 { 0x10000000, 0x10000000, 0x10000000, 0x10000000, 0x10000000 } },
1117 { 6, 0x989c,
1118 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
1119 { 6, 0x989c,
1120 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
1121 { 6, 0x989c,
1122 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
1123 { 6, 0x989c,
1124 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
1125 { 6, 0x989c,
1126 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
1127 { 6, 0x989c,
1128 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
1129 { 6, 0x989c,
1130 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
1131 { 6, 0x989c,
1132 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
1133 { 6, 0x989c,
1134 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
1135 { 6, 0x989c,
1136 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
1137 { 6, 0x989c,
1138 { 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000 } },
1139 { 6, 0x989c,
1140 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
1141 { 6, 0x989c,
1142 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
1143 { 6, 0x989c,
1144 { 0x00100000, 0x00100000, 0x00100000, 0x00100000, 0x00100000 } },
1145 { 6, 0x989c,
1146 { 0x00020000, 0x00020000, 0x00020000, 0x00020000, 0x00020000 } },
1147 { 6, 0x989c,
1148 { 0x00730000, 0x00730000, 0x00730000, 0x00730000, 0x00730000 } },
1149 { 6, 0x989c,
1150 { 0x00f80000, 0x00f80000, 0x00f80000, 0x00f80000, 0x00f80000 } },
1151 { 6, 0x989c,
1152 { 0x00e70000, 0x00e70000, 0x80e70000, 0x80e70000, 0x00e70000 } },
1153 { 6, 0x989c,
1154 { 0x00140000, 0x00140000, 0x00140000, 0x00140000, 0x00140000 } },
1155 { 6, 0x989c,
1156 { 0x00910040, 0x00910040, 0x00910040, 0x00910040, 0x00910040 } },
1157 { 6, 0x989c,
1158 { 0x0007001a, 0x0007001a, 0x0207001a, 0x0207001a, 0x0007001a } },
1159 { 6, 0x989c,
1160 { 0x00410000, 0x00410000, 0x00410000, 0x00410000, 0x00410000 } },
1161 { 6, 0x989c,
1162 { 0x00810000, 0x00810000, 0x00810060, 0x00810060, 0x00810060 } },
1163 { 6, 0x989c,
1164 { 0x00020800, 0x00020800, 0x00020803, 0x00020803, 0x00020803 } },
1165 { 6, 0x989c,
1166 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
1167 { 6, 0x989c,
1168 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
1169 { 6, 0x989c,
1170 { 0x00001660, 0x00001660, 0x00001660, 0x00001660, 0x00001660 } },
1171 { 6, 0x989c,
1172 { 0x00001688, 0x00001688, 0x00001688, 0x00001688, 0x00001688 } },
1173 { 6, 0x98c4,
1174 { 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001 } },
1175 { 7, 0x989c,
1176 { 0x00006400, 0x00006400, 0x00006400, 0x00006400, 0x00006400 } },
1177 { 7, 0x989c,
1178 { 0x00000800, 0x00000800, 0x00000800, 0x00000800, 0x00000800 } },
1179 { 7, 0x98cc,
1180 { 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e } },
1181};
diff --git a/drivers/net/wireless/ath5k/rfgain.h b/drivers/net/wireless/ath5k/rfgain.h
new file mode 100644
index 000000000000..1354d8c392c8
--- /dev/null
+++ b/drivers/net/wireless/ath5k/rfgain.h
@@ -0,0 +1,516 @@
1/*
2 * RF Gain optimization
3 *
4 * Copyright (c) 2004-2009 Reyk Floeter <reyk@openbsd.org>
5 * Copyright (c) 2006-2009 Nick Kossifidis <mickflemm@gmail.com>
6 *
7 * Permission to use, copy, modify, and distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
10 *
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 *
19 */
20
21/*
22 * Mode-specific RF Gain table (64bytes) for RF5111/5112
23 * (RF5110 only comes with AR5210 and only supports a/turbo a mode so initial
24 * RF Gain values are included in AR5K_AR5210_INI)
25 */
26struct ath5k_ini_rfgain {
27 u16 rfg_register; /* RF Gain register address */
28 u32 rfg_value[2]; /* [freq (see below)] */
29};
30
31/* Initial RF Gain settings for RF5111 */
32static const struct ath5k_ini_rfgain rfgain_5111[] = {
33 /* 5Ghz 2Ghz */
34 { AR5K_RF_GAIN(0), { 0x000001a9, 0x00000000 } },
35 { AR5K_RF_GAIN(1), { 0x000001e9, 0x00000040 } },
36 { AR5K_RF_GAIN(2), { 0x00000029, 0x00000080 } },
37 { AR5K_RF_GAIN(3), { 0x00000069, 0x00000150 } },
38 { AR5K_RF_GAIN(4), { 0x00000199, 0x00000190 } },
39 { AR5K_RF_GAIN(5), { 0x000001d9, 0x000001d0 } },
40 { AR5K_RF_GAIN(6), { 0x00000019, 0x00000010 } },
41 { AR5K_RF_GAIN(7), { 0x00000059, 0x00000044 } },
42 { AR5K_RF_GAIN(8), { 0x00000099, 0x00000084 } },
43 { AR5K_RF_GAIN(9), { 0x000001a5, 0x00000148 } },
44 { AR5K_RF_GAIN(10), { 0x000001e5, 0x00000188 } },
45 { AR5K_RF_GAIN(11), { 0x00000025, 0x000001c8 } },
46 { AR5K_RF_GAIN(12), { 0x000001c8, 0x00000014 } },
47 { AR5K_RF_GAIN(13), { 0x00000008, 0x00000042 } },
48 { AR5K_RF_GAIN(14), { 0x00000048, 0x00000082 } },
49 { AR5K_RF_GAIN(15), { 0x00000088, 0x00000178 } },
50 { AR5K_RF_GAIN(16), { 0x00000198, 0x000001b8 } },
51 { AR5K_RF_GAIN(17), { 0x000001d8, 0x000001f8 } },
52 { AR5K_RF_GAIN(18), { 0x00000018, 0x00000012 } },
53 { AR5K_RF_GAIN(19), { 0x00000058, 0x00000052 } },
54 { AR5K_RF_GAIN(20), { 0x00000098, 0x00000092 } },
55 { AR5K_RF_GAIN(21), { 0x000001a4, 0x0000017c } },
56 { AR5K_RF_GAIN(22), { 0x000001e4, 0x000001bc } },
57 { AR5K_RF_GAIN(23), { 0x00000024, 0x000001fc } },
58 { AR5K_RF_GAIN(24), { 0x00000064, 0x0000000a } },
59 { AR5K_RF_GAIN(25), { 0x000000a4, 0x0000004a } },
60 { AR5K_RF_GAIN(26), { 0x000000e4, 0x0000008a } },
61 { AR5K_RF_GAIN(27), { 0x0000010a, 0x0000015a } },
62 { AR5K_RF_GAIN(28), { 0x0000014a, 0x0000019a } },
63 { AR5K_RF_GAIN(29), { 0x0000018a, 0x000001da } },
64 { AR5K_RF_GAIN(30), { 0x000001ca, 0x0000000e } },
65 { AR5K_RF_GAIN(31), { 0x0000000a, 0x0000004e } },
66 { AR5K_RF_GAIN(32), { 0x0000004a, 0x0000008e } },
67 { AR5K_RF_GAIN(33), { 0x0000008a, 0x0000015e } },
68 { AR5K_RF_GAIN(34), { 0x000001ba, 0x0000019e } },
69 { AR5K_RF_GAIN(35), { 0x000001fa, 0x000001de } },
70 { AR5K_RF_GAIN(36), { 0x0000003a, 0x00000009 } },
71 { AR5K_RF_GAIN(37), { 0x0000007a, 0x00000049 } },
72 { AR5K_RF_GAIN(38), { 0x00000186, 0x00000089 } },
73 { AR5K_RF_GAIN(39), { 0x000001c6, 0x00000179 } },
74 { AR5K_RF_GAIN(40), { 0x00000006, 0x000001b9 } },
75 { AR5K_RF_GAIN(41), { 0x00000046, 0x000001f9 } },
76 { AR5K_RF_GAIN(42), { 0x00000086, 0x00000039 } },
77 { AR5K_RF_GAIN(43), { 0x000000c6, 0x00000079 } },
78 { AR5K_RF_GAIN(44), { 0x000000c6, 0x000000b9 } },
79 { AR5K_RF_GAIN(45), { 0x000000c6, 0x000001bd } },
80 { AR5K_RF_GAIN(46), { 0x000000c6, 0x000001fd } },
81 { AR5K_RF_GAIN(47), { 0x000000c6, 0x0000003d } },
82 { AR5K_RF_GAIN(48), { 0x000000c6, 0x0000007d } },
83 { AR5K_RF_GAIN(49), { 0x000000c6, 0x000000bd } },
84 { AR5K_RF_GAIN(50), { 0x000000c6, 0x000000fd } },
85 { AR5K_RF_GAIN(51), { 0x000000c6, 0x000000fd } },
86 { AR5K_RF_GAIN(52), { 0x000000c6, 0x000000fd } },
87 { AR5K_RF_GAIN(53), { 0x000000c6, 0x000000fd } },
88 { AR5K_RF_GAIN(54), { 0x000000c6, 0x000000fd } },
89 { AR5K_RF_GAIN(55), { 0x000000c6, 0x000000fd } },
90 { AR5K_RF_GAIN(56), { 0x000000c6, 0x000000fd } },
91 { AR5K_RF_GAIN(57), { 0x000000c6, 0x000000fd } },
92 { AR5K_RF_GAIN(58), { 0x000000c6, 0x000000fd } },
93 { AR5K_RF_GAIN(59), { 0x000000c6, 0x000000fd } },
94 { AR5K_RF_GAIN(60), { 0x000000c6, 0x000000fd } },
95 { AR5K_RF_GAIN(61), { 0x000000c6, 0x000000fd } },
96 { AR5K_RF_GAIN(62), { 0x000000c6, 0x000000fd } },
97 { AR5K_RF_GAIN(63), { 0x000000c6, 0x000000fd } },
98};
99
100/* Initial RF Gain settings for RF5112 */
101static const struct ath5k_ini_rfgain rfgain_5112[] = {
102 /* 5Ghz 2Ghz */
103 { AR5K_RF_GAIN(0), { 0x00000007, 0x00000007 } },
104 { AR5K_RF_GAIN(1), { 0x00000047, 0x00000047 } },
105 { AR5K_RF_GAIN(2), { 0x00000087, 0x00000087 } },
106 { AR5K_RF_GAIN(3), { 0x000001a0, 0x000001a0 } },
107 { AR5K_RF_GAIN(4), { 0x000001e0, 0x000001e0 } },
108 { AR5K_RF_GAIN(5), { 0x00000020, 0x00000020 } },
109 { AR5K_RF_GAIN(6), { 0x00000060, 0x00000060 } },
110 { AR5K_RF_GAIN(7), { 0x000001a1, 0x000001a1 } },
111 { AR5K_RF_GAIN(8), { 0x000001e1, 0x000001e1 } },
112 { AR5K_RF_GAIN(9), { 0x00000021, 0x00000021 } },
113 { AR5K_RF_GAIN(10), { 0x00000061, 0x00000061 } },
114 { AR5K_RF_GAIN(11), { 0x00000162, 0x00000162 } },
115 { AR5K_RF_GAIN(12), { 0x000001a2, 0x000001a2 } },
116 { AR5K_RF_GAIN(13), { 0x000001e2, 0x000001e2 } },
117 { AR5K_RF_GAIN(14), { 0x00000022, 0x00000022 } },
118 { AR5K_RF_GAIN(15), { 0x00000062, 0x00000062 } },
119 { AR5K_RF_GAIN(16), { 0x00000163, 0x00000163 } },
120 { AR5K_RF_GAIN(17), { 0x000001a3, 0x000001a3 } },
121 { AR5K_RF_GAIN(18), { 0x000001e3, 0x000001e3 } },
122 { AR5K_RF_GAIN(19), { 0x00000023, 0x00000023 } },
123 { AR5K_RF_GAIN(20), { 0x00000063, 0x00000063 } },
124 { AR5K_RF_GAIN(21), { 0x00000184, 0x00000184 } },
125 { AR5K_RF_GAIN(22), { 0x000001c4, 0x000001c4 } },
126 { AR5K_RF_GAIN(23), { 0x00000004, 0x00000004 } },
127 { AR5K_RF_GAIN(24), { 0x000001ea, 0x0000000b } },
128 { AR5K_RF_GAIN(25), { 0x0000002a, 0x0000004b } },
129 { AR5K_RF_GAIN(26), { 0x0000006a, 0x0000008b } },
130 { AR5K_RF_GAIN(27), { 0x000000aa, 0x000001ac } },
131 { AR5K_RF_GAIN(28), { 0x000001ab, 0x000001ec } },
132 { AR5K_RF_GAIN(29), { 0x000001eb, 0x0000002c } },
133 { AR5K_RF_GAIN(30), { 0x0000002b, 0x00000012 } },
134 { AR5K_RF_GAIN(31), { 0x0000006b, 0x00000052 } },
135 { AR5K_RF_GAIN(32), { 0x000000ab, 0x00000092 } },
136 { AR5K_RF_GAIN(33), { 0x000001ac, 0x00000193 } },
137 { AR5K_RF_GAIN(34), { 0x000001ec, 0x000001d3 } },
138 { AR5K_RF_GAIN(35), { 0x0000002c, 0x00000013 } },
139 { AR5K_RF_GAIN(36), { 0x0000003a, 0x00000053 } },
140 { AR5K_RF_GAIN(37), { 0x0000007a, 0x00000093 } },
141 { AR5K_RF_GAIN(38), { 0x000000ba, 0x00000194 } },
142 { AR5K_RF_GAIN(39), { 0x000001bb, 0x000001d4 } },
143 { AR5K_RF_GAIN(40), { 0x000001fb, 0x00000014 } },
144 { AR5K_RF_GAIN(41), { 0x0000003b, 0x0000003a } },
145 { AR5K_RF_GAIN(42), { 0x0000007b, 0x0000007a } },
146 { AR5K_RF_GAIN(43), { 0x000000bb, 0x000000ba } },
147 { AR5K_RF_GAIN(44), { 0x000001bc, 0x000001bb } },
148 { AR5K_RF_GAIN(45), { 0x000001fc, 0x000001fb } },
149 { AR5K_RF_GAIN(46), { 0x0000003c, 0x0000003b } },
150 { AR5K_RF_GAIN(47), { 0x0000007c, 0x0000007b } },
151 { AR5K_RF_GAIN(48), { 0x000000bc, 0x000000bb } },
152 { AR5K_RF_GAIN(49), { 0x000000fc, 0x000001bc } },
153 { AR5K_RF_GAIN(50), { 0x000000fc, 0x000001fc } },
154 { AR5K_RF_GAIN(51), { 0x000000fc, 0x0000003c } },
155 { AR5K_RF_GAIN(52), { 0x000000fc, 0x0000007c } },
156 { AR5K_RF_GAIN(53), { 0x000000fc, 0x000000bc } },
157 { AR5K_RF_GAIN(54), { 0x000000fc, 0x000000fc } },
158 { AR5K_RF_GAIN(55), { 0x000000fc, 0x000000fc } },
159 { AR5K_RF_GAIN(56), { 0x000000fc, 0x000000fc } },
160 { AR5K_RF_GAIN(57), { 0x000000fc, 0x000000fc } },
161 { AR5K_RF_GAIN(58), { 0x000000fc, 0x000000fc } },
162 { AR5K_RF_GAIN(59), { 0x000000fc, 0x000000fc } },
163 { AR5K_RF_GAIN(60), { 0x000000fc, 0x000000fc } },
164 { AR5K_RF_GAIN(61), { 0x000000fc, 0x000000fc } },
165 { AR5K_RF_GAIN(62), { 0x000000fc, 0x000000fc } },
166 { AR5K_RF_GAIN(63), { 0x000000fc, 0x000000fc } },
167};
168
169/* Initial RF Gain settings for RF2413 */
170static const struct ath5k_ini_rfgain rfgain_2413[] = {
171 { AR5K_RF_GAIN(0), { 0x00000000, 0x00000000 } },
172 { AR5K_RF_GAIN(1), { 0x00000000, 0x00000040 } },
173 { AR5K_RF_GAIN(2), { 0x00000000, 0x00000080 } },
174 { AR5K_RF_GAIN(3), { 0x00000000, 0x00000181 } },
175 { AR5K_RF_GAIN(4), { 0x00000000, 0x000001c1 } },
176 { AR5K_RF_GAIN(5), { 0x00000000, 0x00000001 } },
177 { AR5K_RF_GAIN(6), { 0x00000000, 0x00000041 } },
178 { AR5K_RF_GAIN(7), { 0x00000000, 0x00000081 } },
179 { AR5K_RF_GAIN(8), { 0x00000000, 0x00000168 } },
180 { AR5K_RF_GAIN(9), { 0x00000000, 0x000001a8 } },
181 { AR5K_RF_GAIN(10), { 0x00000000, 0x000001e8 } },
182 { AR5K_RF_GAIN(11), { 0x00000000, 0x00000028 } },
183 { AR5K_RF_GAIN(12), { 0x00000000, 0x00000068 } },
184 { AR5K_RF_GAIN(13), { 0x00000000, 0x00000189 } },
185 { AR5K_RF_GAIN(14), { 0x00000000, 0x000001c9 } },
186 { AR5K_RF_GAIN(15), { 0x00000000, 0x00000009 } },
187 { AR5K_RF_GAIN(16), { 0x00000000, 0x00000049 } },
188 { AR5K_RF_GAIN(17), { 0x00000000, 0x00000089 } },
189 { AR5K_RF_GAIN(18), { 0x00000000, 0x00000190 } },
190 { AR5K_RF_GAIN(19), { 0x00000000, 0x000001d0 } },
191 { AR5K_RF_GAIN(20), { 0x00000000, 0x00000010 } },
192 { AR5K_RF_GAIN(21), { 0x00000000, 0x00000050 } },
193 { AR5K_RF_GAIN(22), { 0x00000000, 0x00000090 } },
194 { AR5K_RF_GAIN(23), { 0x00000000, 0x00000191 } },
195 { AR5K_RF_GAIN(24), { 0x00000000, 0x000001d1 } },
196 { AR5K_RF_GAIN(25), { 0x00000000, 0x00000011 } },
197 { AR5K_RF_GAIN(26), { 0x00000000, 0x00000051 } },
198 { AR5K_RF_GAIN(27), { 0x00000000, 0x00000091 } },
199 { AR5K_RF_GAIN(28), { 0x00000000, 0x00000178 } },
200 { AR5K_RF_GAIN(29), { 0x00000000, 0x000001b8 } },
201 { AR5K_RF_GAIN(30), { 0x00000000, 0x000001f8 } },
202 { AR5K_RF_GAIN(31), { 0x00000000, 0x00000038 } },
203 { AR5K_RF_GAIN(32), { 0x00000000, 0x00000078 } },
204 { AR5K_RF_GAIN(33), { 0x00000000, 0x00000199 } },
205 { AR5K_RF_GAIN(34), { 0x00000000, 0x000001d9 } },
206 { AR5K_RF_GAIN(35), { 0x00000000, 0x00000019 } },
207 { AR5K_RF_GAIN(36), { 0x00000000, 0x00000059 } },
208 { AR5K_RF_GAIN(37), { 0x00000000, 0x00000099 } },
209 { AR5K_RF_GAIN(38), { 0x00000000, 0x000000d9 } },
210 { AR5K_RF_GAIN(39), { 0x00000000, 0x000000f9 } },
211 { AR5K_RF_GAIN(40), { 0x00000000, 0x000000f9 } },
212 { AR5K_RF_GAIN(41), { 0x00000000, 0x000000f9 } },
213 { AR5K_RF_GAIN(42), { 0x00000000, 0x000000f9 } },
214 { AR5K_RF_GAIN(43), { 0x00000000, 0x000000f9 } },
215 { AR5K_RF_GAIN(44), { 0x00000000, 0x000000f9 } },
216 { AR5K_RF_GAIN(45), { 0x00000000, 0x000000f9 } },
217 { AR5K_RF_GAIN(46), { 0x00000000, 0x000000f9 } },
218 { AR5K_RF_GAIN(47), { 0x00000000, 0x000000f9 } },
219 { AR5K_RF_GAIN(48), { 0x00000000, 0x000000f9 } },
220 { AR5K_RF_GAIN(49), { 0x00000000, 0x000000f9 } },
221 { AR5K_RF_GAIN(50), { 0x00000000, 0x000000f9 } },
222 { AR5K_RF_GAIN(51), { 0x00000000, 0x000000f9 } },
223 { AR5K_RF_GAIN(52), { 0x00000000, 0x000000f9 } },
224 { AR5K_RF_GAIN(53), { 0x00000000, 0x000000f9 } },
225 { AR5K_RF_GAIN(54), { 0x00000000, 0x000000f9 } },
226 { AR5K_RF_GAIN(55), { 0x00000000, 0x000000f9 } },
227 { AR5K_RF_GAIN(56), { 0x00000000, 0x000000f9 } },
228 { AR5K_RF_GAIN(57), { 0x00000000, 0x000000f9 } },
229 { AR5K_RF_GAIN(58), { 0x00000000, 0x000000f9 } },
230 { AR5K_RF_GAIN(59), { 0x00000000, 0x000000f9 } },
231 { AR5K_RF_GAIN(60), { 0x00000000, 0x000000f9 } },
232 { AR5K_RF_GAIN(61), { 0x00000000, 0x000000f9 } },
233 { AR5K_RF_GAIN(62), { 0x00000000, 0x000000f9 } },
234 { AR5K_RF_GAIN(63), { 0x00000000, 0x000000f9 } },
235};
236
237/* Initial RF Gain settings for AR2316 */
238static const struct ath5k_ini_rfgain rfgain_2316[] = {
239 { AR5K_RF_GAIN(0), { 0x00000000, 0x00000000 } },
240 { AR5K_RF_GAIN(1), { 0x00000000, 0x00000040 } },
241 { AR5K_RF_GAIN(2), { 0x00000000, 0x00000080 } },
242 { AR5K_RF_GAIN(3), { 0x00000000, 0x000000c0 } },
243 { AR5K_RF_GAIN(4), { 0x00000000, 0x000000e0 } },
244 { AR5K_RF_GAIN(5), { 0x00000000, 0x000000e0 } },
245 { AR5K_RF_GAIN(6), { 0x00000000, 0x00000128 } },
246 { AR5K_RF_GAIN(7), { 0x00000000, 0x00000128 } },
247 { AR5K_RF_GAIN(8), { 0x00000000, 0x00000128 } },
248 { AR5K_RF_GAIN(9), { 0x00000000, 0x00000168 } },
249 { AR5K_RF_GAIN(10), { 0x00000000, 0x000001a8 } },
250 { AR5K_RF_GAIN(11), { 0x00000000, 0x000001e8 } },
251 { AR5K_RF_GAIN(12), { 0x00000000, 0x00000028 } },
252 { AR5K_RF_GAIN(13), { 0x00000000, 0x00000068 } },
253 { AR5K_RF_GAIN(14), { 0x00000000, 0x000000a8 } },
254 { AR5K_RF_GAIN(15), { 0x00000000, 0x000000e8 } },
255 { AR5K_RF_GAIN(16), { 0x00000000, 0x000000e8 } },
256 { AR5K_RF_GAIN(17), { 0x00000000, 0x00000130 } },
257 { AR5K_RF_GAIN(18), { 0x00000000, 0x00000130 } },
258 { AR5K_RF_GAIN(19), { 0x00000000, 0x00000170 } },
259 { AR5K_RF_GAIN(20), { 0x00000000, 0x000001b0 } },
260 { AR5K_RF_GAIN(21), { 0x00000000, 0x000001f0 } },
261 { AR5K_RF_GAIN(22), { 0x00000000, 0x00000030 } },
262 { AR5K_RF_GAIN(23), { 0x00000000, 0x00000070 } },
263 { AR5K_RF_GAIN(24), { 0x00000000, 0x000000b0 } },
264 { AR5K_RF_GAIN(25), { 0x00000000, 0x000000f0 } },
265 { AR5K_RF_GAIN(26), { 0x00000000, 0x000000f0 } },
266 { AR5K_RF_GAIN(27), { 0x00000000, 0x000000f0 } },
267 { AR5K_RF_GAIN(28), { 0x00000000, 0x000000f0 } },
268 { AR5K_RF_GAIN(29), { 0x00000000, 0x000000f0 } },
269 { AR5K_RF_GAIN(30), { 0x00000000, 0x000000f0 } },
270 { AR5K_RF_GAIN(31), { 0x00000000, 0x000000f0 } },
271 { AR5K_RF_GAIN(32), { 0x00000000, 0x000000f0 } },
272 { AR5K_RF_GAIN(33), { 0x00000000, 0x000000f0 } },
273 { AR5K_RF_GAIN(34), { 0x00000000, 0x000000f0 } },
274 { AR5K_RF_GAIN(35), { 0x00000000, 0x000000f0 } },
275 { AR5K_RF_GAIN(36), { 0x00000000, 0x000000f0 } },
276 { AR5K_RF_GAIN(37), { 0x00000000, 0x000000f0 } },
277 { AR5K_RF_GAIN(38), { 0x00000000, 0x000000f0 } },
278 { AR5K_RF_GAIN(39), { 0x00000000, 0x000000f0 } },
279 { AR5K_RF_GAIN(40), { 0x00000000, 0x000000f0 } },
280 { AR5K_RF_GAIN(41), { 0x00000000, 0x000000f0 } },
281 { AR5K_RF_GAIN(42), { 0x00000000, 0x000000f0 } },
282 { AR5K_RF_GAIN(43), { 0x00000000, 0x000000f0 } },
283 { AR5K_RF_GAIN(44), { 0x00000000, 0x000000f0 } },
284 { AR5K_RF_GAIN(45), { 0x00000000, 0x000000f0 } },
285 { AR5K_RF_GAIN(46), { 0x00000000, 0x000000f0 } },
286 { AR5K_RF_GAIN(47), { 0x00000000, 0x000000f0 } },
287 { AR5K_RF_GAIN(48), { 0x00000000, 0x000000f0 } },
288 { AR5K_RF_GAIN(49), { 0x00000000, 0x000000f0 } },
289 { AR5K_RF_GAIN(50), { 0x00000000, 0x000000f0 } },
290 { AR5K_RF_GAIN(51), { 0x00000000, 0x000000f0 } },
291 { AR5K_RF_GAIN(52), { 0x00000000, 0x000000f0 } },
292 { AR5K_RF_GAIN(53), { 0x00000000, 0x000000f0 } },
293 { AR5K_RF_GAIN(54), { 0x00000000, 0x000000f0 } },
294 { AR5K_RF_GAIN(55), { 0x00000000, 0x000000f0 } },
295 { AR5K_RF_GAIN(56), { 0x00000000, 0x000000f0 } },
296 { AR5K_RF_GAIN(57), { 0x00000000, 0x000000f0 } },
297 { AR5K_RF_GAIN(58), { 0x00000000, 0x000000f0 } },
298 { AR5K_RF_GAIN(59), { 0x00000000, 0x000000f0 } },
299 { AR5K_RF_GAIN(60), { 0x00000000, 0x000000f0 } },
300 { AR5K_RF_GAIN(61), { 0x00000000, 0x000000f0 } },
301 { AR5K_RF_GAIN(62), { 0x00000000, 0x000000f0 } },
302 { AR5K_RF_GAIN(63), { 0x00000000, 0x000000f0 } },
303};
304
305
306/* Initial RF Gain settings for RF5413 */
307static const struct ath5k_ini_rfgain rfgain_5413[] = {
308 /* 5Ghz 2Ghz */
309 { AR5K_RF_GAIN(0), { 0x00000000, 0x00000000 } },
310 { AR5K_RF_GAIN(1), { 0x00000040, 0x00000040 } },
311 { AR5K_RF_GAIN(2), { 0x00000080, 0x00000080 } },
312 { AR5K_RF_GAIN(3), { 0x000001a1, 0x00000161 } },
313 { AR5K_RF_GAIN(4), { 0x000001e1, 0x000001a1 } },
314 { AR5K_RF_GAIN(5), { 0x00000021, 0x000001e1 } },
315 { AR5K_RF_GAIN(6), { 0x00000061, 0x00000021 } },
316 { AR5K_RF_GAIN(7), { 0x00000188, 0x00000061 } },
317 { AR5K_RF_GAIN(8), { 0x000001c8, 0x00000188 } },
318 { AR5K_RF_GAIN(9), { 0x00000008, 0x000001c8 } },
319 { AR5K_RF_GAIN(10), { 0x00000048, 0x00000008 } },
320 { AR5K_RF_GAIN(11), { 0x00000088, 0x00000048 } },
321 { AR5K_RF_GAIN(12), { 0x000001a9, 0x00000088 } },
322 { AR5K_RF_GAIN(13), { 0x000001e9, 0x00000169 } },
323 { AR5K_RF_GAIN(14), { 0x00000029, 0x000001a9 } },
324 { AR5K_RF_GAIN(15), { 0x00000069, 0x000001e9 } },
325 { AR5K_RF_GAIN(16), { 0x000001d0, 0x00000029 } },
326 { AR5K_RF_GAIN(17), { 0x00000010, 0x00000069 } },
327 { AR5K_RF_GAIN(18), { 0x00000050, 0x00000190 } },
328 { AR5K_RF_GAIN(19), { 0x00000090, 0x000001d0 } },
329 { AR5K_RF_GAIN(20), { 0x000001b1, 0x00000010 } },
330 { AR5K_RF_GAIN(21), { 0x000001f1, 0x00000050 } },
331 { AR5K_RF_GAIN(22), { 0x00000031, 0x00000090 } },
332 { AR5K_RF_GAIN(23), { 0x00000071, 0x00000171 } },
333 { AR5K_RF_GAIN(24), { 0x000001b8, 0x000001b1 } },
334 { AR5K_RF_GAIN(25), { 0x000001f8, 0x000001f1 } },
335 { AR5K_RF_GAIN(26), { 0x00000038, 0x00000031 } },
336 { AR5K_RF_GAIN(27), { 0x00000078, 0x00000071 } },
337 { AR5K_RF_GAIN(28), { 0x00000199, 0x00000198 } },
338 { AR5K_RF_GAIN(29), { 0x000001d9, 0x000001d8 } },
339 { AR5K_RF_GAIN(30), { 0x00000019, 0x00000018 } },
340 { AR5K_RF_GAIN(31), { 0x00000059, 0x00000058 } },
341 { AR5K_RF_GAIN(32), { 0x00000099, 0x00000098 } },
342 { AR5K_RF_GAIN(33), { 0x000000d9, 0x00000179 } },
343 { AR5K_RF_GAIN(34), { 0x000000f9, 0x000001b9 } },
344 { AR5K_RF_GAIN(35), { 0x000000f9, 0x000001f9 } },
345 { AR5K_RF_GAIN(36), { 0x000000f9, 0x00000039 } },
346 { AR5K_RF_GAIN(37), { 0x000000f9, 0x00000079 } },
347 { AR5K_RF_GAIN(38), { 0x000000f9, 0x000000b9 } },
348 { AR5K_RF_GAIN(39), { 0x000000f9, 0x000000f9 } },
349 { AR5K_RF_GAIN(40), { 0x000000f9, 0x000000f9 } },
350 { AR5K_RF_GAIN(41), { 0x000000f9, 0x000000f9 } },
351 { AR5K_RF_GAIN(42), { 0x000000f9, 0x000000f9 } },
352 { AR5K_RF_GAIN(43), { 0x000000f9, 0x000000f9 } },
353 { AR5K_RF_GAIN(44), { 0x000000f9, 0x000000f9 } },
354 { AR5K_RF_GAIN(45), { 0x000000f9, 0x000000f9 } },
355 { AR5K_RF_GAIN(46), { 0x000000f9, 0x000000f9 } },
356 { AR5K_RF_GAIN(47), { 0x000000f9, 0x000000f9 } },
357 { AR5K_RF_GAIN(48), { 0x000000f9, 0x000000f9 } },
358 { AR5K_RF_GAIN(49), { 0x000000f9, 0x000000f9 } },
359 { AR5K_RF_GAIN(50), { 0x000000f9, 0x000000f9 } },
360 { AR5K_RF_GAIN(51), { 0x000000f9, 0x000000f9 } },
361 { AR5K_RF_GAIN(52), { 0x000000f9, 0x000000f9 } },
362 { AR5K_RF_GAIN(53), { 0x000000f9, 0x000000f9 } },
363 { AR5K_RF_GAIN(54), { 0x000000f9, 0x000000f9 } },
364 { AR5K_RF_GAIN(55), { 0x000000f9, 0x000000f9 } },
365 { AR5K_RF_GAIN(56), { 0x000000f9, 0x000000f9 } },
366 { AR5K_RF_GAIN(57), { 0x000000f9, 0x000000f9 } },
367 { AR5K_RF_GAIN(58), { 0x000000f9, 0x000000f9 } },
368 { AR5K_RF_GAIN(59), { 0x000000f9, 0x000000f9 } },
369 { AR5K_RF_GAIN(60), { 0x000000f9, 0x000000f9 } },
370 { AR5K_RF_GAIN(61), { 0x000000f9, 0x000000f9 } },
371 { AR5K_RF_GAIN(62), { 0x000000f9, 0x000000f9 } },
372 { AR5K_RF_GAIN(63), { 0x000000f9, 0x000000f9 } },
373};
374
375
376/* Initial RF Gain settings for RF2425 */
377static const struct ath5k_ini_rfgain rfgain_2425[] = {
378 { AR5K_RF_GAIN(0), { 0x00000000, 0x00000000 } },
379 { AR5K_RF_GAIN(1), { 0x00000000, 0x00000040 } },
380 { AR5K_RF_GAIN(2), { 0x00000000, 0x00000080 } },
381 { AR5K_RF_GAIN(3), { 0x00000000, 0x00000181 } },
382 { AR5K_RF_GAIN(4), { 0x00000000, 0x000001c1 } },
383 { AR5K_RF_GAIN(5), { 0x00000000, 0x00000001 } },
384 { AR5K_RF_GAIN(6), { 0x00000000, 0x00000041 } },
385 { AR5K_RF_GAIN(7), { 0x00000000, 0x00000081 } },
386 { AR5K_RF_GAIN(8), { 0x00000000, 0x00000188 } },
387 { AR5K_RF_GAIN(9), { 0x00000000, 0x000001c8 } },
388 { AR5K_RF_GAIN(10), { 0x00000000, 0x00000008 } },
389 { AR5K_RF_GAIN(11), { 0x00000000, 0x00000048 } },
390 { AR5K_RF_GAIN(12), { 0x00000000, 0x00000088 } },
391 { AR5K_RF_GAIN(13), { 0x00000000, 0x00000189 } },
392 { AR5K_RF_GAIN(14), { 0x00000000, 0x000001c9 } },
393 { AR5K_RF_GAIN(15), { 0x00000000, 0x00000009 } },
394 { AR5K_RF_GAIN(16), { 0x00000000, 0x00000049 } },
395 { AR5K_RF_GAIN(17), { 0x00000000, 0x00000089 } },
396 { AR5K_RF_GAIN(18), { 0x00000000, 0x000001b0 } },
397 { AR5K_RF_GAIN(19), { 0x00000000, 0x000001f0 } },
398 { AR5K_RF_GAIN(20), { 0x00000000, 0x00000030 } },
399 { AR5K_RF_GAIN(21), { 0x00000000, 0x00000070 } },
400 { AR5K_RF_GAIN(22), { 0x00000000, 0x00000171 } },
401 { AR5K_RF_GAIN(23), { 0x00000000, 0x000001b1 } },
402 { AR5K_RF_GAIN(24), { 0x00000000, 0x000001f1 } },
403 { AR5K_RF_GAIN(25), { 0x00000000, 0x00000031 } },
404 { AR5K_RF_GAIN(26), { 0x00000000, 0x00000071 } },
405 { AR5K_RF_GAIN(27), { 0x00000000, 0x000001b8 } },
406 { AR5K_RF_GAIN(28), { 0x00000000, 0x000001f8 } },
407 { AR5K_RF_GAIN(29), { 0x00000000, 0x00000038 } },
408 { AR5K_RF_GAIN(30), { 0x00000000, 0x00000078 } },
409 { AR5K_RF_GAIN(31), { 0x00000000, 0x000000b8 } },
410 { AR5K_RF_GAIN(32), { 0x00000000, 0x000001b9 } },
411 { AR5K_RF_GAIN(33), { 0x00000000, 0x000001f9 } },
412 { AR5K_RF_GAIN(34), { 0x00000000, 0x00000039 } },
413 { AR5K_RF_GAIN(35), { 0x00000000, 0x00000079 } },
414 { AR5K_RF_GAIN(36), { 0x00000000, 0x000000b9 } },
415 { AR5K_RF_GAIN(37), { 0x00000000, 0x000000f9 } },
416 { AR5K_RF_GAIN(38), { 0x00000000, 0x000000f9 } },
417 { AR5K_RF_GAIN(39), { 0x00000000, 0x000000f9 } },
418 { AR5K_RF_GAIN(40), { 0x00000000, 0x000000f9 } },
419 { AR5K_RF_GAIN(41), { 0x00000000, 0x000000f9 } },
420 { AR5K_RF_GAIN(42), { 0x00000000, 0x000000f9 } },
421 { AR5K_RF_GAIN(43), { 0x00000000, 0x000000f9 } },
422 { AR5K_RF_GAIN(44), { 0x00000000, 0x000000f9 } },
423 { AR5K_RF_GAIN(45), { 0x00000000, 0x000000f9 } },
424 { AR5K_RF_GAIN(46), { 0x00000000, 0x000000f9 } },
425 { AR5K_RF_GAIN(47), { 0x00000000, 0x000000f9 } },
426 { AR5K_RF_GAIN(48), { 0x00000000, 0x000000f9 } },
427 { AR5K_RF_GAIN(49), { 0x00000000, 0x000000f9 } },
428 { AR5K_RF_GAIN(50), { 0x00000000, 0x000000f9 } },
429 { AR5K_RF_GAIN(51), { 0x00000000, 0x000000f9 } },
430 { AR5K_RF_GAIN(52), { 0x00000000, 0x000000f9 } },
431 { AR5K_RF_GAIN(53), { 0x00000000, 0x000000f9 } },
432 { AR5K_RF_GAIN(54), { 0x00000000, 0x000000f9 } },
433 { AR5K_RF_GAIN(55), { 0x00000000, 0x000000f9 } },
434 { AR5K_RF_GAIN(56), { 0x00000000, 0x000000f9 } },
435 { AR5K_RF_GAIN(57), { 0x00000000, 0x000000f9 } },
436 { AR5K_RF_GAIN(58), { 0x00000000, 0x000000f9 } },
437 { AR5K_RF_GAIN(59), { 0x00000000, 0x000000f9 } },
438 { AR5K_RF_GAIN(60), { 0x00000000, 0x000000f9 } },
439 { AR5K_RF_GAIN(61), { 0x00000000, 0x000000f9 } },
440 { AR5K_RF_GAIN(62), { 0x00000000, 0x000000f9 } },
441 { AR5K_RF_GAIN(63), { 0x00000000, 0x000000f9 } },
442};
443
444#define AR5K_GAIN_CRN_FIX_BITS_5111 4
445#define AR5K_GAIN_CRN_FIX_BITS_5112 7
446#define AR5K_GAIN_CRN_MAX_FIX_BITS AR5K_GAIN_CRN_FIX_BITS_5112
447#define AR5K_GAIN_DYN_ADJUST_HI_MARGIN 15
448#define AR5K_GAIN_DYN_ADJUST_LO_MARGIN 20
449#define AR5K_GAIN_CCK_PROBE_CORR 5
450#define AR5K_GAIN_CCK_OFDM_GAIN_DELTA 15
451#define AR5K_GAIN_STEP_COUNT 10
452
453/* Check if our current measurement is inside our
454 * current variable attenuation window */
455#define AR5K_GAIN_CHECK_ADJUST(_g) \
456 ((_g)->g_current <= (_g)->g_low || (_g)->g_current >= (_g)->g_high)
457
458struct ath5k_gain_opt_step {
459 s8 gos_param[AR5K_GAIN_CRN_MAX_FIX_BITS];
460 s8 gos_gain;
461};
462
463struct ath5k_gain_opt {
464 u8 go_default;
465 u8 go_steps_count;
466 const struct ath5k_gain_opt_step go_step[AR5K_GAIN_STEP_COUNT];
467};
468
469/*
470 * Parameters on gos_param:
471 * 1) Tx clip PHY register
472 * 2) PWD 90 RF register
473 * 3) PWD 84 RF register
474 * 4) RFGainSel RF register
475 */
476static const struct ath5k_gain_opt rfgain_opt_5111 = {
477 4,
478 9,
479 {
480 { { 4, 1, 1, 1 }, 6 },
481 { { 4, 0, 1, 1 }, 4 },
482 { { 3, 1, 1, 1 }, 3 },
483 { { 4, 0, 0, 1 }, 1 },
484 { { 4, 1, 1, 0 }, 0 },
485 { { 4, 0, 1, 0 }, -2 },
486 { { 3, 1, 1, 0 }, -3 },
487 { { 4, 0, 0, 0 }, -4 },
488 { { 2, 1, 1, 0 }, -6 }
489 }
490};
491
492/*
493 * Parameters on gos_param:
494 * 1) Mixgain ovr RF register
495 * 2) PWD 138 RF register
496 * 3) PWD 137 RF register
497 * 4) PWD 136 RF register
498 * 5) PWD 132 RF register
499 * 6) PWD 131 RF register
500 * 7) PWD 130 RF register
501 */
502static const struct ath5k_gain_opt rfgain_opt_5112 = {
503 1,
504 8,
505 {
506 { { 3, 0, 0, 0, 0, 0, 0 }, 6 },
507 { { 2, 0, 0, 0, 0, 0, 0 }, 0 },
508 { { 1, 0, 0, 0, 0, 0, 0 }, -3 },
509 { { 0, 0, 0, 0, 0, 0, 0 }, -6 },
510 { { 0, 1, 1, 0, 0, 0, 0 }, -8 },
511 { { 0, 1, 1, 0, 1, 1, 0 }, -10 },
512 { { 0, 1, 0, 1, 1, 1, 0 }, -13 },
513 { { 0, 1, 0, 1, 1, 0, 1 }, -16 },
514 }
515};
516
diff --git a/drivers/net/wireless/ath9k/ahb.c b/drivers/net/wireless/ath9k/ahb.c
index 7f2c3a09bcac..391c9fd3b646 100644
--- a/drivers/net/wireless/ath9k/ahb.c
+++ b/drivers/net/wireless/ath9k/ahb.c
@@ -19,9 +19,7 @@
19#include <linux/nl80211.h> 19#include <linux/nl80211.h>
20#include <linux/platform_device.h> 20#include <linux/platform_device.h>
21#include <linux/ath9k_platform.h> 21#include <linux/ath9k_platform.h>
22#include "core.h" 22#include "ath9k.h"
23#include "reg.h"
24#include "hw.h"
25 23
26/* return bus cachesize in 4B word units */ 24/* return bus cachesize in 4B word units */
27static void ath_ahb_read_cachesize(struct ath_softc *sc, int *csz) 25static void ath_ahb_read_cachesize(struct ath_softc *sc, int *csz)
@@ -34,7 +32,7 @@ static void ath_ahb_cleanup(struct ath_softc *sc)
34 iounmap(sc->mem); 32 iounmap(sc->mem);
35} 33}
36 34
37static bool ath_ahb_eeprom_read(struct ath_hal *ah, u32 off, u16 *data) 35static bool ath_ahb_eeprom_read(struct ath_hw *ah, u32 off, u16 *data)
38{ 36{
39 struct ath_softc *sc = ah->ah_sc; 37 struct ath_softc *sc = ah->ah_sc;
40 struct platform_device *pdev = to_platform_device(sc->dev); 38 struct platform_device *pdev = to_platform_device(sc->dev);
@@ -67,7 +65,7 @@ static int ath_ahb_probe(struct platform_device *pdev)
67 struct resource *res; 65 struct resource *res;
68 int irq; 66 int irq;
69 int ret = 0; 67 int ret = 0;
70 struct ath_hal *ah; 68 struct ath_hw *ah;
71 69
72 if (!pdev->dev.platform_data) { 70 if (!pdev->dev.platform_data) {
73 dev_err(&pdev->dev, "no platform data specified\n"); 71 dev_err(&pdev->dev, "no platform data specified\n");
@@ -134,10 +132,10 @@ static int ath_ahb_probe(struct platform_device *pdev)
134 "%s: Atheros AR%s MAC/BB Rev:%x, " 132 "%s: Atheros AR%s MAC/BB Rev:%x, "
135 "AR%s RF Rev:%x, mem=0x%lx, irq=%d\n", 133 "AR%s RF Rev:%x, mem=0x%lx, irq=%d\n",
136 wiphy_name(hw->wiphy), 134 wiphy_name(hw->wiphy),
137 ath_mac_bb_name(ah->ah_macVersion), 135 ath_mac_bb_name(ah->hw_version.macVersion),
138 ah->ah_macRev, 136 ah->hw_version.macRev,
139 ath_rf_name((ah->ah_analog5GhzRev & AR_RADIO_SREV_MAJOR)), 137 ath_rf_name((ah->hw_version.analog5GhzRev & AR_RADIO_SREV_MAJOR)),
140 ah->ah_phyRev, 138 ah->hw_version.phyRev,
141 (unsigned long)mem, irq); 139 (unsigned long)mem, irq);
142 140
143 return 0; 141 return 0;
diff --git a/drivers/net/wireless/ath9k/ani.c b/drivers/net/wireless/ath9k/ani.c
index 42197fff2a47..d4df7e611df5 100644
--- a/drivers/net/wireless/ath9k/ani.c
+++ b/drivers/net/wireless/ath9k/ani.c
@@ -14,23 +14,19 @@
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */ 15 */
16 16
17#include "core.h" 17#include "ath9k.h"
18#include "hw.h"
19#include "reg.h"
20#include "phy.h"
21 18
22static int ath9k_hw_get_ani_channel_idx(struct ath_hal *ah, 19static int ath9k_hw_get_ani_channel_idx(struct ath_hw *ah,
23 struct ath9k_channel *chan) 20 struct ath9k_channel *chan)
24{ 21{
25 struct ath_hal_5416 *ahp = AH5416(ah);
26 int i; 22 int i;
27 23
28 for (i = 0; i < ARRAY_SIZE(ahp->ah_ani); i++) { 24 for (i = 0; i < ARRAY_SIZE(ah->ani); i++) {
29 if (ahp->ah_ani[i].c.channel == chan->channel) 25 if (ah->ani[i].c &&
26 ah->ani[i].c->channel == chan->channel)
30 return i; 27 return i;
31 if (ahp->ah_ani[i].c.channel == 0) { 28 if (ah->ani[i].c == NULL) {
32 ahp->ah_ani[i].c.channel = chan->channel; 29 ah->ani[i].c = chan;
33 ahp->ah_ani[i].c.channelFlags = chan->channelFlags;
34 return i; 30 return i;
35 } 31 }
36 } 32 }
@@ -41,41 +37,40 @@ static int ath9k_hw_get_ani_channel_idx(struct ath_hal *ah,
41 return 0; 37 return 0;
42} 38}
43 39
44static bool ath9k_hw_ani_control(struct ath_hal *ah, 40static bool ath9k_hw_ani_control(struct ath_hw *ah,
45 enum ath9k_ani_cmd cmd, int param) 41 enum ath9k_ani_cmd cmd, int param)
46{ 42{
47 struct ath_hal_5416 *ahp = AH5416(ah); 43 struct ar5416AniState *aniState = ah->curani;
48 struct ar5416AniState *aniState = ahp->ah_curani;
49 44
50 switch (cmd & ahp->ah_ani_function) { 45 switch (cmd & ah->ani_function) {
51 case ATH9K_ANI_NOISE_IMMUNITY_LEVEL:{ 46 case ATH9K_ANI_NOISE_IMMUNITY_LEVEL:{
52 u32 level = param; 47 u32 level = param;
53 48
54 if (level >= ARRAY_SIZE(ahp->ah_totalSizeDesired)) { 49 if (level >= ARRAY_SIZE(ah->totalSizeDesired)) {
55 DPRINTF(ah->ah_sc, ATH_DBG_ANI, 50 DPRINTF(ah->ah_sc, ATH_DBG_ANI,
56 "level out of range (%u > %u)\n", 51 "level out of range (%u > %u)\n",
57 level, 52 level,
58 (unsigned)ARRAY_SIZE(ahp->ah_totalSizeDesired)); 53 (unsigned)ARRAY_SIZE(ah->totalSizeDesired));
59 return false; 54 return false;
60 } 55 }
61 56
62 REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ, 57 REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ,
63 AR_PHY_DESIRED_SZ_TOT_DES, 58 AR_PHY_DESIRED_SZ_TOT_DES,
64 ahp->ah_totalSizeDesired[level]); 59 ah->totalSizeDesired[level]);
65 REG_RMW_FIELD(ah, AR_PHY_AGC_CTL1, 60 REG_RMW_FIELD(ah, AR_PHY_AGC_CTL1,
66 AR_PHY_AGC_CTL1_COARSE_LOW, 61 AR_PHY_AGC_CTL1_COARSE_LOW,
67 ahp->ah_coarseLow[level]); 62 ah->coarse_low[level]);
68 REG_RMW_FIELD(ah, AR_PHY_AGC_CTL1, 63 REG_RMW_FIELD(ah, AR_PHY_AGC_CTL1,
69 AR_PHY_AGC_CTL1_COARSE_HIGH, 64 AR_PHY_AGC_CTL1_COARSE_HIGH,
70 ahp->ah_coarseHigh[level]); 65 ah->coarse_high[level]);
71 REG_RMW_FIELD(ah, AR_PHY_FIND_SIG, 66 REG_RMW_FIELD(ah, AR_PHY_FIND_SIG,
72 AR_PHY_FIND_SIG_FIRPWR, 67 AR_PHY_FIND_SIG_FIRPWR,
73 ahp->ah_firpwr[level]); 68 ah->firpwr[level]);
74 69
75 if (level > aniState->noiseImmunityLevel) 70 if (level > aniState->noiseImmunityLevel)
76 ahp->ah_stats.ast_ani_niup++; 71 ah->stats.ast_ani_niup++;
77 else if (level < aniState->noiseImmunityLevel) 72 else if (level < aniState->noiseImmunityLevel)
78 ahp->ah_stats.ast_ani_nidown++; 73 ah->stats.ast_ani_nidown++;
79 aniState->noiseImmunityLevel = level; 74 aniState->noiseImmunityLevel = level;
80 break; 75 break;
81 } 76 }
@@ -129,9 +124,9 @@ static bool ath9k_hw_ani_control(struct ath_hal *ah,
129 124
130 if (!on != aniState->ofdmWeakSigDetectOff) { 125 if (!on != aniState->ofdmWeakSigDetectOff) {
131 if (on) 126 if (on)
132 ahp->ah_stats.ast_ani_ofdmon++; 127 ah->stats.ast_ani_ofdmon++;
133 else 128 else
134 ahp->ah_stats.ast_ani_ofdmoff++; 129 ah->stats.ast_ani_ofdmoff++;
135 aniState->ofdmWeakSigDetectOff = !on; 130 aniState->ofdmWeakSigDetectOff = !on;
136 } 131 }
137 break; 132 break;
@@ -145,9 +140,9 @@ static bool ath9k_hw_ani_control(struct ath_hal *ah,
145 weakSigThrCck[high]); 140 weakSigThrCck[high]);
146 if (high != aniState->cckWeakSigThreshold) { 141 if (high != aniState->cckWeakSigThreshold) {
147 if (high) 142 if (high)
148 ahp->ah_stats.ast_ani_cckhigh++; 143 ah->stats.ast_ani_cckhigh++;
149 else 144 else
150 ahp->ah_stats.ast_ani_ccklow++; 145 ah->stats.ast_ani_ccklow++;
151 aniState->cckWeakSigThreshold = high; 146 aniState->cckWeakSigThreshold = high;
152 } 147 }
153 break; 148 break;
@@ -167,9 +162,9 @@ static bool ath9k_hw_ani_control(struct ath_hal *ah,
167 AR_PHY_FIND_SIG_FIRSTEP, 162 AR_PHY_FIND_SIG_FIRSTEP,
168 firstep[level]); 163 firstep[level]);
169 if (level > aniState->firstepLevel) 164 if (level > aniState->firstepLevel)
170 ahp->ah_stats.ast_ani_stepup++; 165 ah->stats.ast_ani_stepup++;
171 else if (level < aniState->firstepLevel) 166 else if (level < aniState->firstepLevel)
172 ahp->ah_stats.ast_ani_stepdown++; 167 ah->stats.ast_ani_stepdown++;
173 aniState->firstepLevel = level; 168 aniState->firstepLevel = level;
174 break; 169 break;
175 } 170 }
@@ -190,9 +185,9 @@ static bool ath9k_hw_ani_control(struct ath_hal *ah,
190 AR_PHY_TIMING5_CYCPWR_THR1, 185 AR_PHY_TIMING5_CYCPWR_THR1,
191 cycpwrThr1[level]); 186 cycpwrThr1[level]);
192 if (level > aniState->spurImmunityLevel) 187 if (level > aniState->spurImmunityLevel)
193 ahp->ah_stats.ast_ani_spurup++; 188 ah->stats.ast_ani_spurup++;
194 else if (level < aniState->spurImmunityLevel) 189 else if (level < aniState->spurImmunityLevel)
195 ahp->ah_stats.ast_ani_spurdown++; 190 ah->stats.ast_ani_spurdown++;
196 aniState->spurImmunityLevel = level; 191 aniState->spurImmunityLevel = level;
197 break; 192 break;
198 } 193 }
@@ -223,7 +218,7 @@ static bool ath9k_hw_ani_control(struct ath_hal *ah,
223 return true; 218 return true;
224} 219}
225 220
226static void ath9k_hw_update_mibstats(struct ath_hal *ah, 221static void ath9k_hw_update_mibstats(struct ath_hw *ah,
227 struct ath9k_mib_stats *stats) 222 struct ath9k_mib_stats *stats)
228{ 223{
229 stats->ackrcv_bad += REG_READ(ah, AR_ACK_FAIL); 224 stats->ackrcv_bad += REG_READ(ah, AR_ACK_FAIL);
@@ -233,18 +228,17 @@ static void ath9k_hw_update_mibstats(struct ath_hal *ah,
233 stats->beacons += REG_READ(ah, AR_BEACON_CNT); 228 stats->beacons += REG_READ(ah, AR_BEACON_CNT);
234} 229}
235 230
236static void ath9k_ani_restart(struct ath_hal *ah) 231static void ath9k_ani_restart(struct ath_hw *ah)
237{ 232{
238 struct ath_hal_5416 *ahp = AH5416(ah);
239 struct ar5416AniState *aniState; 233 struct ar5416AniState *aniState;
240 234
241 if (!DO_ANI(ah)) 235 if (!DO_ANI(ah))
242 return; 236 return;
243 237
244 aniState = ahp->ah_curani; 238 aniState = ah->curani;
245 239
246 aniState->listenTime = 0; 240 aniState->listenTime = 0;
247 if (ahp->ah_hasHwPhyCounters) { 241 if (ah->has_hw_phycounters) {
248 if (aniState->ofdmTrigHigh > AR_PHY_COUNTMAX) { 242 if (aniState->ofdmTrigHigh > AR_PHY_COUNTMAX) {
249 aniState->ofdmPhyErrBase = 0; 243 aniState->ofdmPhyErrBase = 0;
250 DPRINTF(ah->ah_sc, ATH_DBG_ANI, 244 DPRINTF(ah->ah_sc, ATH_DBG_ANI,
@@ -270,15 +264,14 @@ static void ath9k_ani_restart(struct ath_hal *ah)
270 REG_WRITE(ah, AR_PHY_ERR_MASK_1, AR_PHY_ERR_OFDM_TIMING); 264 REG_WRITE(ah, AR_PHY_ERR_MASK_1, AR_PHY_ERR_OFDM_TIMING);
271 REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING); 265 REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING);
272 266
273 ath9k_hw_update_mibstats(ah, &ahp->ah_mibStats); 267 ath9k_hw_update_mibstats(ah, &ah->ah_mibStats);
274 } 268 }
275 aniState->ofdmPhyErrCount = 0; 269 aniState->ofdmPhyErrCount = 0;
276 aniState->cckPhyErrCount = 0; 270 aniState->cckPhyErrCount = 0;
277} 271}
278 272
279static void ath9k_hw_ani_ofdm_err_trigger(struct ath_hal *ah) 273static void ath9k_hw_ani_ofdm_err_trigger(struct ath_hw *ah)
280{ 274{
281 struct ath_hal_5416 *ahp = AH5416(ah);
282 struct ieee80211_conf *conf = &ah->ah_sc->hw->conf; 275 struct ieee80211_conf *conf = &ah->ah_sc->hw->conf;
283 struct ar5416AniState *aniState; 276 struct ar5416AniState *aniState;
284 int32_t rssi; 277 int32_t rssi;
@@ -286,7 +279,7 @@ static void ath9k_hw_ani_ofdm_err_trigger(struct ath_hal *ah)
286 if (!DO_ANI(ah)) 279 if (!DO_ANI(ah))
287 return; 280 return;
288 281
289 aniState = ahp->ah_curani; 282 aniState = ah->curani;
290 283
291 if (aniState->noiseImmunityLevel < HAL_NOISE_IMMUNE_MAX) { 284 if (aniState->noiseImmunityLevel < HAL_NOISE_IMMUNE_MAX) {
292 if (ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL, 285 if (ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL,
@@ -302,14 +295,14 @@ static void ath9k_hw_ani_ofdm_err_trigger(struct ath_hal *ah)
302 } 295 }
303 } 296 }
304 297
305 if (ah->ah_opmode == NL80211_IFTYPE_AP) { 298 if (ah->opmode == NL80211_IFTYPE_AP) {
306 if (aniState->firstepLevel < HAL_FIRST_STEP_MAX) { 299 if (aniState->firstepLevel < HAL_FIRST_STEP_MAX) {
307 ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL, 300 ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
308 aniState->firstepLevel + 1); 301 aniState->firstepLevel + 1);
309 } 302 }
310 return; 303 return;
311 } 304 }
312 rssi = BEACON_RSSI(ahp); 305 rssi = BEACON_RSSI(ah);
313 if (rssi > aniState->rssiThrHigh) { 306 if (rssi > aniState->rssiThrHigh) {
314 if (!aniState->ofdmWeakSigDetectOff) { 307 if (!aniState->ofdmWeakSigDetectOff) {
315 if (ath9k_hw_ani_control(ah, 308 if (ath9k_hw_ani_control(ah,
@@ -348,9 +341,8 @@ static void ath9k_hw_ani_ofdm_err_trigger(struct ath_hal *ah)
348 } 341 }
349} 342}
350 343
351static void ath9k_hw_ani_cck_err_trigger(struct ath_hal *ah) 344static void ath9k_hw_ani_cck_err_trigger(struct ath_hw *ah)
352{ 345{
353 struct ath_hal_5416 *ahp = AH5416(ah);
354 struct ieee80211_conf *conf = &ah->ah_sc->hw->conf; 346 struct ieee80211_conf *conf = &ah->ah_sc->hw->conf;
355 struct ar5416AniState *aniState; 347 struct ar5416AniState *aniState;
356 int32_t rssi; 348 int32_t rssi;
@@ -358,21 +350,21 @@ static void ath9k_hw_ani_cck_err_trigger(struct ath_hal *ah)
358 if (!DO_ANI(ah)) 350 if (!DO_ANI(ah))
359 return; 351 return;
360 352
361 aniState = ahp->ah_curani; 353 aniState = ah->curani;
362 if (aniState->noiseImmunityLevel < HAL_NOISE_IMMUNE_MAX) { 354 if (aniState->noiseImmunityLevel < HAL_NOISE_IMMUNE_MAX) {
363 if (ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL, 355 if (ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL,
364 aniState->noiseImmunityLevel + 1)) { 356 aniState->noiseImmunityLevel + 1)) {
365 return; 357 return;
366 } 358 }
367 } 359 }
368 if (ah->ah_opmode == NL80211_IFTYPE_AP) { 360 if (ah->opmode == NL80211_IFTYPE_AP) {
369 if (aniState->firstepLevel < HAL_FIRST_STEP_MAX) { 361 if (aniState->firstepLevel < HAL_FIRST_STEP_MAX) {
370 ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL, 362 ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
371 aniState->firstepLevel + 1); 363 aniState->firstepLevel + 1);
372 } 364 }
373 return; 365 return;
374 } 366 }
375 rssi = BEACON_RSSI(ahp); 367 rssi = BEACON_RSSI(ah);
376 if (rssi > aniState->rssiThrLow) { 368 if (rssi > aniState->rssiThrLow) {
377 if (aniState->firstepLevel < HAL_FIRST_STEP_MAX) 369 if (aniState->firstepLevel < HAL_FIRST_STEP_MAX)
378 ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL, 370 ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
@@ -386,22 +378,21 @@ static void ath9k_hw_ani_cck_err_trigger(struct ath_hal *ah)
386 } 378 }
387} 379}
388 380
389static void ath9k_hw_ani_lower_immunity(struct ath_hal *ah) 381static void ath9k_hw_ani_lower_immunity(struct ath_hw *ah)
390{ 382{
391 struct ath_hal_5416 *ahp = AH5416(ah);
392 struct ar5416AniState *aniState; 383 struct ar5416AniState *aniState;
393 int32_t rssi; 384 int32_t rssi;
394 385
395 aniState = ahp->ah_curani; 386 aniState = ah->curani;
396 387
397 if (ah->ah_opmode == NL80211_IFTYPE_AP) { 388 if (ah->opmode == NL80211_IFTYPE_AP) {
398 if (aniState->firstepLevel > 0) { 389 if (aniState->firstepLevel > 0) {
399 if (ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL, 390 if (ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
400 aniState->firstepLevel - 1)) 391 aniState->firstepLevel - 1))
401 return; 392 return;
402 } 393 }
403 } else { 394 } else {
404 rssi = BEACON_RSSI(ahp); 395 rssi = BEACON_RSSI(ah);
405 if (rssi > aniState->rssiThrHigh) { 396 if (rssi > aniState->rssiThrHigh) {
406 /* XXX: Handle me */ 397 /* XXX: Handle me */
407 } else if (rssi > aniState->rssiThrLow) { 398 } else if (rssi > aniState->rssiThrLow) {
@@ -440,9 +431,8 @@ static void ath9k_hw_ani_lower_immunity(struct ath_hal *ah)
440 } 431 }
441} 432}
442 433
443static int32_t ath9k_hw_ani_get_listen_time(struct ath_hal *ah) 434static int32_t ath9k_hw_ani_get_listen_time(struct ath_hw *ah)
444{ 435{
445 struct ath_hal_5416 *ahp = AH5416(ah);
446 struct ar5416AniState *aniState; 436 struct ar5416AniState *aniState;
447 u32 txFrameCount, rxFrameCount, cycleCount; 437 u32 txFrameCount, rxFrameCount, cycleCount;
448 int32_t listenTime; 438 int32_t listenTime;
@@ -451,11 +441,11 @@ static int32_t ath9k_hw_ani_get_listen_time(struct ath_hal *ah)
451 rxFrameCount = REG_READ(ah, AR_RFCNT); 441 rxFrameCount = REG_READ(ah, AR_RFCNT);
452 cycleCount = REG_READ(ah, AR_CCCNT); 442 cycleCount = REG_READ(ah, AR_CCCNT);
453 443
454 aniState = ahp->ah_curani; 444 aniState = ah->curani;
455 if (aniState->cycleCount == 0 || aniState->cycleCount > cycleCount) { 445 if (aniState->cycleCount == 0 || aniState->cycleCount > cycleCount) {
456 446
457 listenTime = 0; 447 listenTime = 0;
458 ahp->ah_stats.ast_ani_lzero++; 448 ah->stats.ast_ani_lzero++;
459 } else { 449 } else {
460 int32_t ccdelta = cycleCount - aniState->cycleCount; 450 int32_t ccdelta = cycleCount - aniState->cycleCount;
461 int32_t rfdelta = rxFrameCount - aniState->rxFrameCount; 451 int32_t rfdelta = rxFrameCount - aniState->rxFrameCount;
@@ -469,25 +459,24 @@ static int32_t ath9k_hw_ani_get_listen_time(struct ath_hal *ah)
469 return listenTime; 459 return listenTime;
470} 460}
471 461
472void ath9k_ani_reset(struct ath_hal *ah) 462void ath9k_ani_reset(struct ath_hw *ah)
473{ 463{
474 struct ath_hal_5416 *ahp = AH5416(ah);
475 struct ar5416AniState *aniState; 464 struct ar5416AniState *aniState;
476 struct ath9k_channel *chan = ah->ah_curchan; 465 struct ath9k_channel *chan = ah->curchan;
477 int index; 466 int index;
478 467
479 if (!DO_ANI(ah)) 468 if (!DO_ANI(ah))
480 return; 469 return;
481 470
482 index = ath9k_hw_get_ani_channel_idx(ah, chan); 471 index = ath9k_hw_get_ani_channel_idx(ah, chan);
483 aniState = &ahp->ah_ani[index]; 472 aniState = &ah->ani[index];
484 ahp->ah_curani = aniState; 473 ah->curani = aniState;
485 474
486 if (DO_ANI(ah) && ah->ah_opmode != NL80211_IFTYPE_STATION 475 if (DO_ANI(ah) && ah->opmode != NL80211_IFTYPE_STATION
487 && ah->ah_opmode != NL80211_IFTYPE_ADHOC) { 476 && ah->opmode != NL80211_IFTYPE_ADHOC) {
488 DPRINTF(ah->ah_sc, ATH_DBG_ANI, 477 DPRINTF(ah->ah_sc, ATH_DBG_ANI,
489 "Reset ANI state opmode %u\n", ah->ah_opmode); 478 "Reset ANI state opmode %u\n", ah->opmode);
490 ahp->ah_stats.ast_ani_reset++; 479 ah->stats.ast_ani_reset++;
491 480
492 ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL, 0); 481 ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL, 0);
493 ath9k_hw_ani_control(ah, ATH9K_ANI_SPUR_IMMUNITY_LEVEL, 0); 482 ath9k_hw_ani_control(ah, ATH9K_ANI_SPUR_IMMUNITY_LEVEL, 0);
@@ -500,15 +489,15 @@ void ath9k_ani_reset(struct ath_hal *ah)
500 ath9k_hw_setrxfilter(ah, ath9k_hw_getrxfilter(ah) | 489 ath9k_hw_setrxfilter(ah, ath9k_hw_getrxfilter(ah) |
501 ATH9K_RX_FILTER_PHYERR); 490 ATH9K_RX_FILTER_PHYERR);
502 491
503 if (ah->ah_opmode == NL80211_IFTYPE_AP) { 492 if (ah->opmode == NL80211_IFTYPE_AP) {
504 ahp->ah_curani->ofdmTrigHigh = 493 ah->curani->ofdmTrigHigh =
505 ah->ah_config.ofdm_trig_high; 494 ah->config.ofdm_trig_high;
506 ahp->ah_curani->ofdmTrigLow = 495 ah->curani->ofdmTrigLow =
507 ah->ah_config.ofdm_trig_low; 496 ah->config.ofdm_trig_low;
508 ahp->ah_curani->cckTrigHigh = 497 ah->curani->cckTrigHigh =
509 ah->ah_config.cck_trig_high; 498 ah->config.cck_trig_high;
510 ahp->ah_curani->cckTrigLow = 499 ah->curani->cckTrigLow =
511 ah->ah_config.cck_trig_low; 500 ah->config.cck_trig_low;
512 } 501 }
513 ath9k_ani_restart(ah); 502 ath9k_ani_restart(ah);
514 return; 503 return;
@@ -529,7 +518,7 @@ void ath9k_ani_reset(struct ath_hal *ah)
529 if (aniState->firstepLevel != 0) 518 if (aniState->firstepLevel != 0)
530 ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL, 519 ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
531 aniState->firstepLevel); 520 aniState->firstepLevel);
532 if (ahp->ah_hasHwPhyCounters) { 521 if (ah->has_hw_phycounters) {
533 ath9k_hw_setrxfilter(ah, ath9k_hw_getrxfilter(ah) & 522 ath9k_hw_setrxfilter(ah, ath9k_hw_getrxfilter(ah) &
534 ~ATH9K_RX_FILTER_PHYERR); 523 ~ATH9K_RX_FILTER_PHYERR);
535 ath9k_ani_restart(ah); 524 ath9k_ani_restart(ah);
@@ -543,34 +532,33 @@ void ath9k_ani_reset(struct ath_hal *ah)
543 } 532 }
544} 533}
545 534
546void ath9k_hw_ani_monitor(struct ath_hal *ah, 535void ath9k_hw_ani_monitor(struct ath_hw *ah,
547 const struct ath9k_node_stats *stats, 536 const struct ath9k_node_stats *stats,
548 struct ath9k_channel *chan) 537 struct ath9k_channel *chan)
549{ 538{
550 struct ath_hal_5416 *ahp = AH5416(ah);
551 struct ar5416AniState *aniState; 539 struct ar5416AniState *aniState;
552 int32_t listenTime; 540 int32_t listenTime;
553 541
554 if (!DO_ANI(ah)) 542 if (!DO_ANI(ah))
555 return; 543 return;
556 544
557 aniState = ahp->ah_curani; 545 aniState = ah->curani;
558 ahp->ah_stats.ast_nodestats = *stats; 546 ah->stats.ast_nodestats = *stats;
559 547
560 listenTime = ath9k_hw_ani_get_listen_time(ah); 548 listenTime = ath9k_hw_ani_get_listen_time(ah);
561 if (listenTime < 0) { 549 if (listenTime < 0) {
562 ahp->ah_stats.ast_ani_lneg++; 550 ah->stats.ast_ani_lneg++;
563 ath9k_ani_restart(ah); 551 ath9k_ani_restart(ah);
564 return; 552 return;
565 } 553 }
566 554
567 aniState->listenTime += listenTime; 555 aniState->listenTime += listenTime;
568 556
569 if (ahp->ah_hasHwPhyCounters) { 557 if (ah->has_hw_phycounters) {
570 u32 phyCnt1, phyCnt2; 558 u32 phyCnt1, phyCnt2;
571 u32 ofdmPhyErrCnt, cckPhyErrCnt; 559 u32 ofdmPhyErrCnt, cckPhyErrCnt;
572 560
573 ath9k_hw_update_mibstats(ah, &ahp->ah_mibStats); 561 ath9k_hw_update_mibstats(ah, &ah->ah_mibStats);
574 562
575 phyCnt1 = REG_READ(ah, AR_PHY_ERR_1); 563 phyCnt1 = REG_READ(ah, AR_PHY_ERR_1);
576 phyCnt2 = REG_READ(ah, AR_PHY_ERR_2); 564 phyCnt2 = REG_READ(ah, AR_PHY_ERR_2);
@@ -603,24 +591,24 @@ void ath9k_hw_ani_monitor(struct ath_hal *ah,
603 } 591 }
604 592
605 ofdmPhyErrCnt = phyCnt1 - aniState->ofdmPhyErrBase; 593 ofdmPhyErrCnt = phyCnt1 - aniState->ofdmPhyErrBase;
606 ahp->ah_stats.ast_ani_ofdmerrs += 594 ah->stats.ast_ani_ofdmerrs +=
607 ofdmPhyErrCnt - aniState->ofdmPhyErrCount; 595 ofdmPhyErrCnt - aniState->ofdmPhyErrCount;
608 aniState->ofdmPhyErrCount = ofdmPhyErrCnt; 596 aniState->ofdmPhyErrCount = ofdmPhyErrCnt;
609 597
610 cckPhyErrCnt = phyCnt2 - aniState->cckPhyErrBase; 598 cckPhyErrCnt = phyCnt2 - aniState->cckPhyErrBase;
611 ahp->ah_stats.ast_ani_cckerrs += 599 ah->stats.ast_ani_cckerrs +=
612 cckPhyErrCnt - aniState->cckPhyErrCount; 600 cckPhyErrCnt - aniState->cckPhyErrCount;
613 aniState->cckPhyErrCount = cckPhyErrCnt; 601 aniState->cckPhyErrCount = cckPhyErrCnt;
614 } 602 }
615 603
616 if (aniState->listenTime > 5 * ahp->ah_aniPeriod) { 604 if (aniState->listenTime > 5 * ah->aniperiod) {
617 if (aniState->ofdmPhyErrCount <= aniState->listenTime * 605 if (aniState->ofdmPhyErrCount <= aniState->listenTime *
618 aniState->ofdmTrigLow / 1000 && 606 aniState->ofdmTrigLow / 1000 &&
619 aniState->cckPhyErrCount <= aniState->listenTime * 607 aniState->cckPhyErrCount <= aniState->listenTime *
620 aniState->cckTrigLow / 1000) 608 aniState->cckTrigLow / 1000)
621 ath9k_hw_ani_lower_immunity(ah); 609 ath9k_hw_ani_lower_immunity(ah);
622 ath9k_ani_restart(ah); 610 ath9k_ani_restart(ah);
623 } else if (aniState->listenTime > ahp->ah_aniPeriod) { 611 } else if (aniState->listenTime > ah->aniperiod) {
624 if (aniState->ofdmPhyErrCount > aniState->listenTime * 612 if (aniState->ofdmPhyErrCount > aniState->listenTime *
625 aniState->ofdmTrigHigh / 1000) { 613 aniState->ofdmTrigHigh / 1000) {
626 ath9k_hw_ani_ofdm_err_trigger(ah); 614 ath9k_hw_ani_ofdm_err_trigger(ah);
@@ -634,20 +622,16 @@ void ath9k_hw_ani_monitor(struct ath_hal *ah,
634 } 622 }
635} 623}
636 624
637bool ath9k_hw_phycounters(struct ath_hal *ah) 625bool ath9k_hw_phycounters(struct ath_hw *ah)
638{ 626{
639 struct ath_hal_5416 *ahp = AH5416(ah); 627 return ah->has_hw_phycounters ? true : false;
640
641 return ahp->ah_hasHwPhyCounters ? true : false;
642} 628}
643 629
644void ath9k_enable_mib_counters(struct ath_hal *ah) 630void ath9k_enable_mib_counters(struct ath_hw *ah)
645{ 631{
646 struct ath_hal_5416 *ahp = AH5416(ah);
647
648 DPRINTF(ah->ah_sc, ATH_DBG_ANI, "Enable MIB counters\n"); 632 DPRINTF(ah->ah_sc, ATH_DBG_ANI, "Enable MIB counters\n");
649 633
650 ath9k_hw_update_mibstats(ah, &ahp->ah_mibStats); 634 ath9k_hw_update_mibstats(ah, &ah->ah_mibStats);
651 635
652 REG_WRITE(ah, AR_FILT_OFDM, 0); 636 REG_WRITE(ah, AR_FILT_OFDM, 0);
653 REG_WRITE(ah, AR_FILT_CCK, 0); 637 REG_WRITE(ah, AR_FILT_CCK, 0);
@@ -658,21 +642,19 @@ void ath9k_enable_mib_counters(struct ath_hal *ah)
658 REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING); 642 REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING);
659} 643}
660 644
661void ath9k_hw_disable_mib_counters(struct ath_hal *ah) 645void ath9k_hw_disable_mib_counters(struct ath_hw *ah)
662{ 646{
663 struct ath_hal_5416 *ahp = AH5416(ah);
664
665 DPRINTF(ah->ah_sc, ATH_DBG_ANI, "Disable MIB counters\n"); 647 DPRINTF(ah->ah_sc, ATH_DBG_ANI, "Disable MIB counters\n");
666 648
667 REG_WRITE(ah, AR_MIBC, AR_MIBC_FMC | AR_MIBC_CMC); 649 REG_WRITE(ah, AR_MIBC, AR_MIBC_FMC | AR_MIBC_CMC);
668 650
669 ath9k_hw_update_mibstats(ah, &ahp->ah_mibStats); 651 ath9k_hw_update_mibstats(ah, &ah->ah_mibStats);
670 652
671 REG_WRITE(ah, AR_FILT_OFDM, 0); 653 REG_WRITE(ah, AR_FILT_OFDM, 0);
672 REG_WRITE(ah, AR_FILT_CCK, 0); 654 REG_WRITE(ah, AR_FILT_CCK, 0);
673} 655}
674 656
675u32 ath9k_hw_GetMibCycleCountsPct(struct ath_hal *ah, 657u32 ath9k_hw_GetMibCycleCountsPct(struct ath_hw *ah,
676 u32 *rxc_pcnt, 658 u32 *rxc_pcnt,
677 u32 *rxf_pcnt, 659 u32 *rxf_pcnt,
678 u32 *txf_pcnt) 660 u32 *txf_pcnt)
@@ -717,10 +699,9 @@ u32 ath9k_hw_GetMibCycleCountsPct(struct ath_hal *ah,
717 * any of the MIB counters overflow/trigger so don't assume we're 699 * any of the MIB counters overflow/trigger so don't assume we're
718 * here because a PHY error counter triggered. 700 * here because a PHY error counter triggered.
719 */ 701 */
720void ath9k_hw_procmibevent(struct ath_hal *ah, 702void ath9k_hw_procmibevent(struct ath_hw *ah,
721 const struct ath9k_node_stats *stats) 703 const struct ath9k_node_stats *stats)
722{ 704{
723 struct ath_hal_5416 *ahp = AH5416(ah);
724 u32 phyCnt1, phyCnt2; 705 u32 phyCnt1, phyCnt2;
725 706
726 /* Reset these counters regardless */ 707 /* Reset these counters regardless */
@@ -730,8 +711,8 @@ void ath9k_hw_procmibevent(struct ath_hal *ah,
730 REG_WRITE(ah, AR_SLP_MIB_CTRL, AR_SLP_MIB_CLEAR); 711 REG_WRITE(ah, AR_SLP_MIB_CTRL, AR_SLP_MIB_CLEAR);
731 712
732 /* Clear the mib counters and save them in the stats */ 713 /* Clear the mib counters and save them in the stats */
733 ath9k_hw_update_mibstats(ah, &ahp->ah_mibStats); 714 ath9k_hw_update_mibstats(ah, &ah->ah_mibStats);
734 ahp->ah_stats.ast_nodestats = *stats; 715 ah->stats.ast_nodestats = *stats;
735 716
736 if (!DO_ANI(ah)) 717 if (!DO_ANI(ah))
737 return; 718 return;
@@ -741,17 +722,17 @@ void ath9k_hw_procmibevent(struct ath_hal *ah,
741 phyCnt2 = REG_READ(ah, AR_PHY_ERR_2); 722 phyCnt2 = REG_READ(ah, AR_PHY_ERR_2);
742 if (((phyCnt1 & AR_MIBCNT_INTRMASK) == AR_MIBCNT_INTRMASK) || 723 if (((phyCnt1 & AR_MIBCNT_INTRMASK) == AR_MIBCNT_INTRMASK) ||
743 ((phyCnt2 & AR_MIBCNT_INTRMASK) == AR_MIBCNT_INTRMASK)) { 724 ((phyCnt2 & AR_MIBCNT_INTRMASK) == AR_MIBCNT_INTRMASK)) {
744 struct ar5416AniState *aniState = ahp->ah_curani; 725 struct ar5416AniState *aniState = ah->curani;
745 u32 ofdmPhyErrCnt, cckPhyErrCnt; 726 u32 ofdmPhyErrCnt, cckPhyErrCnt;
746 727
747 /* NB: only use ast_ani_*errs with AH_PRIVATE_DIAG */ 728 /* NB: only use ast_ani_*errs with AH_PRIVATE_DIAG */
748 ofdmPhyErrCnt = phyCnt1 - aniState->ofdmPhyErrBase; 729 ofdmPhyErrCnt = phyCnt1 - aniState->ofdmPhyErrBase;
749 ahp->ah_stats.ast_ani_ofdmerrs += 730 ah->stats.ast_ani_ofdmerrs +=
750 ofdmPhyErrCnt - aniState->ofdmPhyErrCount; 731 ofdmPhyErrCnt - aniState->ofdmPhyErrCount;
751 aniState->ofdmPhyErrCount = ofdmPhyErrCnt; 732 aniState->ofdmPhyErrCount = ofdmPhyErrCnt;
752 733
753 cckPhyErrCnt = phyCnt2 - aniState->cckPhyErrBase; 734 cckPhyErrCnt = phyCnt2 - aniState->cckPhyErrBase;
754 ahp->ah_stats.ast_ani_cckerrs += 735 ah->stats.ast_ani_cckerrs +=
755 cckPhyErrCnt - aniState->cckPhyErrCount; 736 cckPhyErrCnt - aniState->cckPhyErrCount;
756 aniState->cckPhyErrCount = cckPhyErrCnt; 737 aniState->cckPhyErrCount = cckPhyErrCnt;
757 738
@@ -770,9 +751,8 @@ void ath9k_hw_procmibevent(struct ath_hal *ah,
770 } 751 }
771} 752}
772 753
773void ath9k_hw_ani_setup(struct ath_hal *ah) 754void ath9k_hw_ani_setup(struct ath_hw *ah)
774{ 755{
775 struct ath_hal_5416 *ahp = AH5416(ah);
776 int i; 756 int i;
777 757
778 const int totalSizeDesired[] = { -55, -55, -55, -55, -62 }; 758 const int totalSizeDesired[] = { -55, -55, -55, -55, -62 };
@@ -781,66 +761,63 @@ void ath9k_hw_ani_setup(struct ath_hal *ah)
781 const int firpwr[] = { -78, -78, -78, -78, -80 }; 761 const int firpwr[] = { -78, -78, -78, -78, -80 };
782 762
783 for (i = 0; i < 5; i++) { 763 for (i = 0; i < 5; i++) {
784 ahp->ah_totalSizeDesired[i] = totalSizeDesired[i]; 764 ah->totalSizeDesired[i] = totalSizeDesired[i];
785 ahp->ah_coarseHigh[i] = coarseHigh[i]; 765 ah->coarse_high[i] = coarseHigh[i];
786 ahp->ah_coarseLow[i] = coarseLow[i]; 766 ah->coarse_low[i] = coarseLow[i];
787 ahp->ah_firpwr[i] = firpwr[i]; 767 ah->firpwr[i] = firpwr[i];
788 } 768 }
789} 769}
790 770
791void ath9k_hw_ani_attach(struct ath_hal *ah) 771void ath9k_hw_ani_attach(struct ath_hw *ah)
792{ 772{
793 struct ath_hal_5416 *ahp = AH5416(ah);
794 int i; 773 int i;
795 774
796 DPRINTF(ah->ah_sc, ATH_DBG_ANI, "Attach ANI\n"); 775 DPRINTF(ah->ah_sc, ATH_DBG_ANI, "Attach ANI\n");
797 776
798 ahp->ah_hasHwPhyCounters = 1; 777 ah->has_hw_phycounters = 1;
799 778
800 memset(ahp->ah_ani, 0, sizeof(ahp->ah_ani)); 779 memset(ah->ani, 0, sizeof(ah->ani));
801 for (i = 0; i < ARRAY_SIZE(ahp->ah_ani); i++) { 780 for (i = 0; i < ARRAY_SIZE(ah->ani); i++) {
802 ahp->ah_ani[i].ofdmTrigHigh = ATH9K_ANI_OFDM_TRIG_HIGH; 781 ah->ani[i].ofdmTrigHigh = ATH9K_ANI_OFDM_TRIG_HIGH;
803 ahp->ah_ani[i].ofdmTrigLow = ATH9K_ANI_OFDM_TRIG_LOW; 782 ah->ani[i].ofdmTrigLow = ATH9K_ANI_OFDM_TRIG_LOW;
804 ahp->ah_ani[i].cckTrigHigh = ATH9K_ANI_CCK_TRIG_HIGH; 783 ah->ani[i].cckTrigHigh = ATH9K_ANI_CCK_TRIG_HIGH;
805 ahp->ah_ani[i].cckTrigLow = ATH9K_ANI_CCK_TRIG_LOW; 784 ah->ani[i].cckTrigLow = ATH9K_ANI_CCK_TRIG_LOW;
806 ahp->ah_ani[i].rssiThrHigh = ATH9K_ANI_RSSI_THR_HIGH; 785 ah->ani[i].rssiThrHigh = ATH9K_ANI_RSSI_THR_HIGH;
807 ahp->ah_ani[i].rssiThrLow = ATH9K_ANI_RSSI_THR_LOW; 786 ah->ani[i].rssiThrLow = ATH9K_ANI_RSSI_THR_LOW;
808 ahp->ah_ani[i].ofdmWeakSigDetectOff = 787 ah->ani[i].ofdmWeakSigDetectOff =
809 !ATH9K_ANI_USE_OFDM_WEAK_SIG; 788 !ATH9K_ANI_USE_OFDM_WEAK_SIG;
810 ahp->ah_ani[i].cckWeakSigThreshold = 789 ah->ani[i].cckWeakSigThreshold =
811 ATH9K_ANI_CCK_WEAK_SIG_THR; 790 ATH9K_ANI_CCK_WEAK_SIG_THR;
812 ahp->ah_ani[i].spurImmunityLevel = ATH9K_ANI_SPUR_IMMUNE_LVL; 791 ah->ani[i].spurImmunityLevel = ATH9K_ANI_SPUR_IMMUNE_LVL;
813 ahp->ah_ani[i].firstepLevel = ATH9K_ANI_FIRSTEP_LVL; 792 ah->ani[i].firstepLevel = ATH9K_ANI_FIRSTEP_LVL;
814 if (ahp->ah_hasHwPhyCounters) { 793 if (ah->has_hw_phycounters) {
815 ahp->ah_ani[i].ofdmPhyErrBase = 794 ah->ani[i].ofdmPhyErrBase =
816 AR_PHY_COUNTMAX - ATH9K_ANI_OFDM_TRIG_HIGH; 795 AR_PHY_COUNTMAX - ATH9K_ANI_OFDM_TRIG_HIGH;
817 ahp->ah_ani[i].cckPhyErrBase = 796 ah->ani[i].cckPhyErrBase =
818 AR_PHY_COUNTMAX - ATH9K_ANI_CCK_TRIG_HIGH; 797 AR_PHY_COUNTMAX - ATH9K_ANI_CCK_TRIG_HIGH;
819 } 798 }
820 } 799 }
821 if (ahp->ah_hasHwPhyCounters) { 800 if (ah->has_hw_phycounters) {
822 DPRINTF(ah->ah_sc, ATH_DBG_ANI, 801 DPRINTF(ah->ah_sc, ATH_DBG_ANI,
823 "Setting OfdmErrBase = 0x%08x\n", 802 "Setting OfdmErrBase = 0x%08x\n",
824 ahp->ah_ani[0].ofdmPhyErrBase); 803 ah->ani[0].ofdmPhyErrBase);
825 DPRINTF(ah->ah_sc, ATH_DBG_ANI, "Setting cckErrBase = 0x%08x\n", 804 DPRINTF(ah->ah_sc, ATH_DBG_ANI, "Setting cckErrBase = 0x%08x\n",
826 ahp->ah_ani[0].cckPhyErrBase); 805 ah->ani[0].cckPhyErrBase);
827 806
828 REG_WRITE(ah, AR_PHY_ERR_1, ahp->ah_ani[0].ofdmPhyErrBase); 807 REG_WRITE(ah, AR_PHY_ERR_1, ah->ani[0].ofdmPhyErrBase);
829 REG_WRITE(ah, AR_PHY_ERR_2, ahp->ah_ani[0].cckPhyErrBase); 808 REG_WRITE(ah, AR_PHY_ERR_2, ah->ani[0].cckPhyErrBase);
830 ath9k_enable_mib_counters(ah); 809 ath9k_enable_mib_counters(ah);
831 } 810 }
832 ahp->ah_aniPeriod = ATH9K_ANI_PERIOD; 811 ah->aniperiod = ATH9K_ANI_PERIOD;
833 if (ah->ah_config.enable_ani) 812 if (ah->config.enable_ani)
834 ahp->ah_procPhyErr |= HAL_PROCESS_ANI; 813 ah->proc_phyerr |= HAL_PROCESS_ANI;
835} 814}
836 815
837void ath9k_hw_ani_detach(struct ath_hal *ah) 816void ath9k_hw_ani_detach(struct ath_hw *ah)
838{ 817{
839 struct ath_hal_5416 *ahp = AH5416(ah);
840
841 DPRINTF(ah->ah_sc, ATH_DBG_ANI, "Detach ANI\n"); 818 DPRINTF(ah->ah_sc, ATH_DBG_ANI, "Detach ANI\n");
842 819
843 if (ahp->ah_hasHwPhyCounters) { 820 if (ah->has_hw_phycounters) {
844 ath9k_hw_disable_mib_counters(ah); 821 ath9k_hw_disable_mib_counters(ah);
845 REG_WRITE(ah, AR_PHY_ERR_1, 0); 822 REG_WRITE(ah, AR_PHY_ERR_1, 0);
846 REG_WRITE(ah, AR_PHY_ERR_2, 0); 823 REG_WRITE(ah, AR_PHY_ERR_2, 0);
diff --git a/drivers/net/wireless/ath9k/ani.h b/drivers/net/wireless/ath9k/ani.h
new file mode 100644
index 000000000000..7315761f6d74
--- /dev/null
+++ b/drivers/net/wireless/ath9k/ani.h
@@ -0,0 +1,138 @@
1/*
2 * Copyright (c) 2008 Atheros Communications Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#ifndef ANI_H
18#define ANI_H
19
20#define HAL_PROCESS_ANI 0x00000001
21#define ATH9K_RSSI_EP_MULTIPLIER (1<<7)
22
23#define DO_ANI(ah) (((ah)->proc_phyerr & HAL_PROCESS_ANI))
24
25#define HAL_EP_RND(x, mul) \
26 ((((x)%(mul)) >= ((mul)/2)) ? ((x) + ((mul) - 1)) / (mul) : (x)/(mul))
27#define BEACON_RSSI(ahp) \
28 HAL_EP_RND(ahp->stats.ast_nodestats.ns_avgbrssi, \
29 ATH9K_RSSI_EP_MULTIPLIER)
30
31#define ATH9K_ANI_OFDM_TRIG_HIGH 500
32#define ATH9K_ANI_OFDM_TRIG_LOW 200
33#define ATH9K_ANI_CCK_TRIG_HIGH 200
34#define ATH9K_ANI_CCK_TRIG_LOW 100
35#define ATH9K_ANI_NOISE_IMMUNE_LVL 4
36#define ATH9K_ANI_USE_OFDM_WEAK_SIG true
37#define ATH9K_ANI_CCK_WEAK_SIG_THR false
38#define ATH9K_ANI_SPUR_IMMUNE_LVL 7
39#define ATH9K_ANI_FIRSTEP_LVL 0
40#define ATH9K_ANI_RSSI_THR_HIGH 40
41#define ATH9K_ANI_RSSI_THR_LOW 7
42#define ATH9K_ANI_PERIOD 100
43
44#define HAL_NOISE_IMMUNE_MAX 4
45#define HAL_SPUR_IMMUNE_MAX 7
46#define HAL_FIRST_STEP_MAX 2
47
48enum ath9k_ani_cmd {
49 ATH9K_ANI_PRESENT = 0x1,
50 ATH9K_ANI_NOISE_IMMUNITY_LEVEL = 0x2,
51 ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION = 0x4,
52 ATH9K_ANI_CCK_WEAK_SIGNAL_THR = 0x8,
53 ATH9K_ANI_FIRSTEP_LEVEL = 0x10,
54 ATH9K_ANI_SPUR_IMMUNITY_LEVEL = 0x20,
55 ATH9K_ANI_MODE = 0x40,
56 ATH9K_ANI_PHYERR_RESET = 0x80,
57 ATH9K_ANI_ALL = 0xff
58};
59
60struct ath9k_mib_stats {
61 u32 ackrcv_bad;
62 u32 rts_bad;
63 u32 rts_good;
64 u32 fcs_bad;
65 u32 beacons;
66};
67
68struct ath9k_node_stats {
69 u32 ns_avgbrssi;
70 u32 ns_avgrssi;
71 u32 ns_avgtxrssi;
72 u32 ns_avgtxrate;
73};
74
75struct ar5416AniState {
76 struct ath9k_channel *c;
77 u8 noiseImmunityLevel;
78 u8 spurImmunityLevel;
79 u8 firstepLevel;
80 u8 ofdmWeakSigDetectOff;
81 u8 cckWeakSigThreshold;
82 u32 listenTime;
83 u32 ofdmTrigHigh;
84 u32 ofdmTrigLow;
85 int32_t cckTrigHigh;
86 int32_t cckTrigLow;
87 int32_t rssiThrLow;
88 int32_t rssiThrHigh;
89 u32 noiseFloor;
90 u32 txFrameCount;
91 u32 rxFrameCount;
92 u32 cycleCount;
93 u32 ofdmPhyErrCount;
94 u32 cckPhyErrCount;
95 u32 ofdmPhyErrBase;
96 u32 cckPhyErrBase;
97 int16_t pktRssi[2];
98 int16_t ofdmErrRssi[2];
99 int16_t cckErrRssi[2];
100};
101
102struct ar5416Stats {
103 u32 ast_ani_niup;
104 u32 ast_ani_nidown;
105 u32 ast_ani_spurup;
106 u32 ast_ani_spurdown;
107 u32 ast_ani_ofdmon;
108 u32 ast_ani_ofdmoff;
109 u32 ast_ani_cckhigh;
110 u32 ast_ani_ccklow;
111 u32 ast_ani_stepup;
112 u32 ast_ani_stepdown;
113 u32 ast_ani_ofdmerrs;
114 u32 ast_ani_cckerrs;
115 u32 ast_ani_reset;
116 u32 ast_ani_lzero;
117 u32 ast_ani_lneg;
118 struct ath9k_mib_stats ast_mibstats;
119 struct ath9k_node_stats ast_nodestats;
120};
121#define ah_mibStats stats.ast_mibstats
122
123void ath9k_ani_reset(struct ath_hw *ah);
124void ath9k_hw_ani_monitor(struct ath_hw *ah,
125 const struct ath9k_node_stats *stats,
126 struct ath9k_channel *chan);
127bool ath9k_hw_phycounters(struct ath_hw *ah);
128void ath9k_enable_mib_counters(struct ath_hw *ah);
129void ath9k_hw_disable_mib_counters(struct ath_hw *ah);
130u32 ath9k_hw_GetMibCycleCountsPct(struct ath_hw *ah, u32 *rxc_pcnt,
131 u32 *rxf_pcnt, u32 *txf_pcnt);
132void ath9k_hw_procmibevent(struct ath_hw *ah,
133 const struct ath9k_node_stats *stats);
134void ath9k_hw_ani_setup(struct ath_hw *ah);
135void ath9k_hw_ani_attach(struct ath_hw *ah);
136void ath9k_hw_ani_detach(struct ath_hw *ah);
137
138#endif /* ANI_H */
diff --git a/drivers/net/wireless/ath9k/ath9k.h b/drivers/net/wireless/ath9k/ath9k.h
index 5289d2878111..0b0f82c83ffc 100644
--- a/drivers/net/wireless/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath9k/ath9k.h
@@ -17,1028 +17,670 @@
17#ifndef ATH9K_H 17#ifndef ATH9K_H
18#define ATH9K_H 18#define ATH9K_H
19 19
20#include <linux/io.h> 20#include <linux/etherdevice.h>
21 21#include <linux/device.h>
22#define ATHEROS_VENDOR_ID 0x168c 22#include <net/mac80211.h>
23 23#include <linux/leds.h>
24#define AR5416_DEVID_PCI 0x0023 24#include <linux/rfkill.h>
25#define AR5416_DEVID_PCIE 0x0024 25
26#define AR9160_DEVID_PCI 0x0027 26#include "hw.h"
27#define AR9280_DEVID_PCI 0x0029 27#include "rc.h"
28#define AR9280_DEVID_PCIE 0x002a 28#include "debug.h"
29#define AR9285_DEVID_PCIE 0x002b 29
30 30struct ath_node;
31#define AR5416_AR9100_DEVID 0x000b 31
32 32/* Macro to expand scalars to 64-bit objects */
33#define AR_SUBVENDOR_ID_NOG 0x0e11 33
34#define AR_SUBVENDOR_ID_NEW_A 0x7065 34#define ito64(x) (sizeof(x) == 8) ? \
35 35 (((unsigned long long int)(x)) & (0xff)) : \
36#define ATH9K_TXERR_XRETRY 0x01 36 (sizeof(x) == 16) ? \
37#define ATH9K_TXERR_FILT 0x02 37 (((unsigned long long int)(x)) & 0xffff) : \
38#define ATH9K_TXERR_FIFO 0x04 38 ((sizeof(x) == 32) ? \
39#define ATH9K_TXERR_XTXOP 0x08 39 (((unsigned long long int)(x)) & 0xffffffff) : \
40#define ATH9K_TXERR_TIMER_EXPIRED 0x10 40 (unsigned long long int)(x))
41 41
42#define ATH9K_TX_BA 0x01 42/* increment with wrap-around */
43#define ATH9K_TX_PWRMGMT 0x02 43#define INCR(_l, _sz) do { \
44#define ATH9K_TX_DESC_CFG_ERR 0x04 44 (_l)++; \
45#define ATH9K_TX_DATA_UNDERRUN 0x08 45 (_l) &= ((_sz) - 1); \
46#define ATH9K_TX_DELIM_UNDERRUN 0x10 46 } while (0)
47#define ATH9K_TX_SW_ABORTED 0x40 47
48#define ATH9K_TX_SW_FILTERED 0x80 48/* decrement with wrap-around */
49 49#define DECR(_l, _sz) do { \
50#define NBBY 8 50 (_l)--; \
51 51 (_l) &= ((_sz) - 1); \
52struct ath_tx_status { 52 } while (0)
53 u32 ts_tstamp; 53
54 u16 ts_seqnum; 54#define A_MAX(a, b) ((a) > (b) ? (a) : (b))
55 u8 ts_status; 55
56 u8 ts_ratecode; 56#define ASSERT(exp) do { \
57 u8 ts_rateindex; 57 if (unlikely(!(exp))) { \
58 int8_t ts_rssi; 58 BUG(); \
59 u8 ts_shortretry; 59 } \
60 u8 ts_longretry; 60 } while (0)
61 u8 ts_virtcol; 61
62 u8 ts_antenna; 62#define TSF_TO_TU(_h,_l) \
63 u8 ts_flags; 63 ((((u32)(_h)) << 22) | (((u32)(_l)) >> 10))
64 int8_t ts_rssi_ctl0; 64
65 int8_t ts_rssi_ctl1; 65#define ATH_TXQ_SETUP(sc, i) ((sc)->tx.txqsetup & (1<<i))
66 int8_t ts_rssi_ctl2; 66
67 int8_t ts_rssi_ext0; 67static const u8 ath_bcast_mac[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
68 int8_t ts_rssi_ext1; 68
69 int8_t ts_rssi_ext2; 69struct ath_config {
70 u8 pad[3]; 70 u32 ath_aggr_prot;
71 u32 ba_low; 71 u16 txpowlimit;
72 u32 ba_high; 72 u8 cabqReadytime;
73 u32 evm0; 73 u8 swBeaconProcess;
74 u32 evm1; 74};
75 u32 evm2; 75
76}; 76/*************************/
77 77/* Descriptor Management */
78struct ath_rx_status { 78/*************************/
79 u32 rs_tstamp; 79
80 u16 rs_datalen; 80#define ATH_TXBUF_RESET(_bf) do { \
81 u8 rs_status; 81 (_bf)->bf_status = 0; \
82 u8 rs_phyerr; 82 (_bf)->bf_lastbf = NULL; \
83 int8_t rs_rssi; 83 (_bf)->bf_next = NULL; \
84 u8 rs_keyix; 84 memset(&((_bf)->bf_state), 0, \
85 u8 rs_rate; 85 sizeof(struct ath_buf_state)); \
86 u8 rs_antenna; 86 } while (0)
87 u8 rs_more; 87
88 int8_t rs_rssi_ctl0; 88/**
89 int8_t rs_rssi_ctl1; 89 * enum buffer_type - Buffer type flags
90 int8_t rs_rssi_ctl2; 90 *
91 int8_t rs_rssi_ext0; 91 * @BUF_HT: Send this buffer using HT capabilities
92 int8_t rs_rssi_ext1; 92 * @BUF_AMPDU: This buffer is an ampdu, as part of an aggregate (during TX)
93 int8_t rs_rssi_ext2; 93 * @BUF_AGGR: Indicates whether the buffer can be aggregated
94 u8 rs_isaggr; 94 * (used in aggregation scheduling)
95 u8 rs_moreaggr; 95 * @BUF_RETRY: Indicates whether the buffer is retried
96 u8 rs_num_delims; 96 * @BUF_XRETRY: To denote excessive retries of the buffer
97 u8 rs_flags; 97 */
98 u32 evm0; 98enum buffer_type {
99 u32 evm1; 99 BUF_HT = BIT(1),
100 u32 evm2; 100 BUF_AMPDU = BIT(2),
101}; 101 BUF_AGGR = BIT(3),
102 102 BUF_RETRY = BIT(4),
103#define ATH9K_RXERR_CRC 0x01 103 BUF_XRETRY = BIT(5),
104#define ATH9K_RXERR_PHY 0x02 104};
105#define ATH9K_RXERR_FIFO 0x04 105
106#define ATH9K_RXERR_DECRYPT 0x08 106struct ath_buf_state {
107#define ATH9K_RXERR_MIC 0x10 107 int bfs_nframes;
108 108 u16 bfs_al;
109#define ATH9K_RX_MORE 0x01 109 u16 bfs_frmlen;
110#define ATH9K_RX_MORE_AGGR 0x02 110 int bfs_seqno;
111#define ATH9K_RX_GI 0x04 111 int bfs_tidno;
112#define ATH9K_RX_2040 0x08 112 int bfs_retries;
113#define ATH9K_RX_DELIM_CRC_PRE 0x10 113 u32 bf_type;
114#define ATH9K_RX_DELIM_CRC_POST 0x20 114 u32 bfs_keyix;
115#define ATH9K_RX_DECRYPT_BUSY 0x40 115 enum ath9k_key_type bfs_keytype;
116 116};
117#define ATH9K_RXKEYIX_INVALID ((u8)-1) 117
118#define ATH9K_TXKEYIX_INVALID ((u32)-1) 118#define bf_nframes bf_state.bfs_nframes
119 119#define bf_al bf_state.bfs_al
120struct ath_desc { 120#define bf_frmlen bf_state.bfs_frmlen
121 u32 ds_link; 121#define bf_retries bf_state.bfs_retries
122 u32 ds_data; 122#define bf_seqno bf_state.bfs_seqno
123 u32 ds_ctl0; 123#define bf_tidno bf_state.bfs_tidno
124 u32 ds_ctl1; 124#define bf_keyix bf_state.bfs_keyix
125 u32 ds_hw[20]; 125#define bf_keytype bf_state.bfs_keytype
126 union { 126#define bf_isht(bf) (bf->bf_state.bf_type & BUF_HT)
127 struct ath_tx_status tx; 127#define bf_isampdu(bf) (bf->bf_state.bf_type & BUF_AMPDU)
128 struct ath_rx_status rx; 128#define bf_isaggr(bf) (bf->bf_state.bf_type & BUF_AGGR)
129 void *stats; 129#define bf_isretried(bf) (bf->bf_state.bf_type & BUF_RETRY)
130 } ds_us; 130#define bf_isxretried(bf) (bf->bf_state.bf_type & BUF_XRETRY)
131 void *ds_vdata; 131
132} __packed; 132struct ath_buf {
133 133 struct list_head list;
134#define ds_txstat ds_us.tx 134 struct ath_buf *bf_lastbf; /* last buf of this unit (a frame or
135#define ds_rxstat ds_us.rx 135 an aggregate) */
136#define ds_stat ds_us.stats 136 struct ath_buf *bf_next; /* next subframe in the aggregate */
137 137 void *bf_mpdu; /* enclosing frame structure */
138#define ATH9K_TXDESC_CLRDMASK 0x0001 138 struct ath_desc *bf_desc; /* virtual addr of desc */
139#define ATH9K_TXDESC_NOACK 0x0002 139 dma_addr_t bf_daddr; /* physical addr of desc */
140#define ATH9K_TXDESC_RTSENA 0x0004 140 dma_addr_t bf_buf_addr; /* physical addr of data buffer */
141#define ATH9K_TXDESC_CTSENA 0x0008 141 u32 bf_status;
142/* ATH9K_TXDESC_INTREQ forces a tx interrupt to be generated for 142 u16 bf_flags;
143 * the descriptor its marked on. We take a tx interrupt to reap 143 struct ath_buf_state bf_state;
144 * descriptors when the h/w hits an EOL condition or 144 dma_addr_t bf_dmacontext;
145 * when the descriptor is specifically marked to generate 145};
146 * an interrupt with this flag. Descriptors should be 146
147 * marked periodically to insure timely replenishing of the 147#define ATH_RXBUF_RESET(_bf) ((_bf)->bf_status = 0)
148 * supply needed for sending frames. Defering interrupts 148#define ATH_BUFSTATUS_STALE 0x00000002
149 * reduces system load and potentially allows more concurrent 149
150 * work to be done but if done to aggressively can cause 150struct ath_descdma {
151 * senders to backup. When the hardware queue is left too 151 const char *dd_name;
152 * large rate control information may also be too out of 152 struct ath_desc *dd_desc;
153 * date. An Alternative for this is TX interrupt mitigation 153 dma_addr_t dd_desc_paddr;
154 * but this needs more testing. */ 154 u32 dd_desc_len;
155#define ATH9K_TXDESC_INTREQ 0x0010 155 struct ath_buf *dd_bufptr;
156#define ATH9K_TXDESC_VEOL 0x0020 156 dma_addr_t dd_dmacontext;
157#define ATH9K_TXDESC_EXT_ONLY 0x0040 157};
158#define ATH9K_TXDESC_EXT_AND_CTL 0x0080 158
159#define ATH9K_TXDESC_VMF 0x0100 159int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd,
160#define ATH9K_TXDESC_FRAG_IS_ON 0x0200 160 struct list_head *head, const char *name,
161#define ATH9K_TXDESC_CAB 0x0400 161 int nbuf, int ndesc);
162 162void ath_descdma_cleanup(struct ath_softc *sc, struct ath_descdma *dd,
163#define ATH9K_RXDESC_INTREQ 0x0020 163 struct list_head *head);
164 164
165enum wireless_mode { 165/***********/
166 ATH9K_MODE_11A = 0, 166/* RX / TX */
167 ATH9K_MODE_11B = 2, 167/***********/
168 ATH9K_MODE_11G = 3, 168
169 ATH9K_MODE_11NA_HT20 = 6, 169#define ATH_MAX_ANTENNA 3
170 ATH9K_MODE_11NG_HT20 = 7, 170#define ATH_RXBUF 512
171 ATH9K_MODE_11NA_HT40PLUS = 8, 171#define WME_NUM_TID 16
172 ATH9K_MODE_11NA_HT40MINUS = 9, 172#define ATH_TXBUF 512
173 ATH9K_MODE_11NG_HT40PLUS = 10, 173#define ATH_TXMAXTRY 13
174 ATH9K_MODE_11NG_HT40MINUS = 11, 174#define ATH_11N_TXMAXTRY 10
175 ATH9K_MODE_MAX 175#define ATH_MGT_TXMAXTRY 4
176}; 176#define WME_BA_BMP_SIZE 64
177 177#define WME_MAX_BA WME_BA_BMP_SIZE
178enum ath9k_hw_caps { 178#define ATH_TID_MAX_BUFS (2 * WME_MAX_BA)
179 ATH9K_HW_CAP_CHAN_SPREAD = BIT(0), 179
180 ATH9K_HW_CAP_MIC_AESCCM = BIT(1), 180#define TID_TO_WME_AC(_tid) \
181 ATH9K_HW_CAP_MIC_CKIP = BIT(2), 181 ((((_tid) == 0) || ((_tid) == 3)) ? WME_AC_BE : \
182 ATH9K_HW_CAP_MIC_TKIP = BIT(3), 182 (((_tid) == 1) || ((_tid) == 2)) ? WME_AC_BK : \
183 ATH9K_HW_CAP_CIPHER_AESCCM = BIT(4), 183 (((_tid) == 4) || ((_tid) == 5)) ? WME_AC_VI : \
184 ATH9K_HW_CAP_CIPHER_CKIP = BIT(5), 184 WME_AC_VO)
185 ATH9K_HW_CAP_CIPHER_TKIP = BIT(6), 185
186 ATH9K_HW_CAP_VEOL = BIT(7), 186#define WME_AC_BE 0
187 ATH9K_HW_CAP_BSSIDMASK = BIT(8), 187#define WME_AC_BK 1
188 ATH9K_HW_CAP_MCAST_KEYSEARCH = BIT(9), 188#define WME_AC_VI 2
189 ATH9K_HW_CAP_CHAN_HALFRATE = BIT(10), 189#define WME_AC_VO 3
190 ATH9K_HW_CAP_CHAN_QUARTERRATE = BIT(11), 190#define WME_NUM_AC 4
191 ATH9K_HW_CAP_HT = BIT(12), 191
192 ATH9K_HW_CAP_GTT = BIT(13), 192#define ADDBA_EXCHANGE_ATTEMPTS 10
193 ATH9K_HW_CAP_FASTCC = BIT(14), 193#define ATH_AGGR_DELIM_SZ 4
194 ATH9K_HW_CAP_RFSILENT = BIT(15), 194#define ATH_AGGR_MINPLEN 256 /* in bytes, minimum packet length */
195 ATH9K_HW_CAP_WOW = BIT(16), 195/* number of delimiters for encryption padding */
196 ATH9K_HW_CAP_CST = BIT(17), 196#define ATH_AGGR_ENCRYPTDELIM 10
197 ATH9K_HW_CAP_ENHANCEDPM = BIT(18), 197/* minimum h/w qdepth to be sustained to maximize aggregation */
198 ATH9K_HW_CAP_AUTOSLEEP = BIT(19), 198#define ATH_AGGR_MIN_QDEPTH 2
199 ATH9K_HW_CAP_4KB_SPLITTRANS = BIT(20), 199#define ATH_AMPDU_SUBFRAME_DEFAULT 32
200 ATH9K_HW_CAP_WOW_MATCHPATTERN_EXACT = BIT(21), 200#define ATH_AMPDU_LIMIT_MAX (64 * 1024 - 1)
201 ATH9K_HW_CAP_BT_COEX = BIT(22) 201#define ATH_AMPDU_LIMIT_DEFAULT ATH_AMPDU_LIMIT_MAX
202}; 202
203 203#define IEEE80211_SEQ_SEQ_SHIFT 4
204enum ath9k_capability_type { 204#define IEEE80211_SEQ_MAX 4096
205 ATH9K_CAP_CIPHER = 0, 205#define IEEE80211_MIN_AMPDU_BUF 0x8
206 ATH9K_CAP_TKIP_MIC, 206#define IEEE80211_HTCAP_MAXRXAMPDU_FACTOR 13
207 ATH9K_CAP_TKIP_SPLIT, 207#define IEEE80211_WEP_IVLEN 3
208 ATH9K_CAP_PHYCOUNTERS, 208#define IEEE80211_WEP_KIDLEN 1
209 ATH9K_CAP_DIVERSITY, 209#define IEEE80211_WEP_CRCLEN 4
210 ATH9K_CAP_TXPOW, 210#define IEEE80211_MAX_MPDU_LEN (3840 + FCS_LEN + \
211 ATH9K_CAP_PHYDIAG, 211 (IEEE80211_WEP_IVLEN + \
212 ATH9K_CAP_MCAST_KEYSRCH, 212 IEEE80211_WEP_KIDLEN + \
213 ATH9K_CAP_TSF_ADJUST, 213 IEEE80211_WEP_CRCLEN))
214 ATH9K_CAP_WME_TKIPMIC, 214
215 ATH9K_CAP_RFSILENT, 215/* return whether a bit at index _n in bitmap _bm is set
216 ATH9K_CAP_ANT_CFG_2GHZ, 216 * _sz is the size of the bitmap */
217 ATH9K_CAP_ANT_CFG_5GHZ 217#define ATH_BA_ISSET(_bm, _n) (((_n) < (WME_BA_BMP_SIZE)) && \
218}; 218 ((_bm)[(_n) >> 5] & (1 << ((_n) & 31))))
219 219
220struct ath9k_hw_capabilities { 220/* return block-ack bitmap index given sequence and starting sequence */
221 u32 hw_caps; /* ATH9K_HW_CAP_* from ath9k_hw_caps */ 221#define ATH_BA_INDEX(_st, _seq) (((_seq) - (_st)) & (IEEE80211_SEQ_MAX - 1))
222 DECLARE_BITMAP(wireless_modes, ATH9K_MODE_MAX); /* ATH9K_MODE_* */ 222
223 u16 total_queues; 223/* returns delimiter padding required given the packet length */
224 u16 keycache_size; 224#define ATH_AGGR_GET_NDELIM(_len) \
225 u16 low_5ghz_chan, high_5ghz_chan; 225 (((((_len) + ATH_AGGR_DELIM_SZ) < ATH_AGGR_MINPLEN) ? \
226 u16 low_2ghz_chan, high_2ghz_chan; 226 (ATH_AGGR_MINPLEN - (_len) - ATH_AGGR_DELIM_SZ) : 0) >> 2)
227 u16 num_mr_retries; 227
228 u16 rts_aggr_limit; 228#define BAW_WITHIN(_start, _bawsz, _seqno) \
229 u8 tx_chainmask; 229 ((((_seqno) - (_start)) & 4095) < (_bawsz))
230 u8 rx_chainmask; 230
231 u16 tx_triglevel_max; 231#define ATH_DS_BA_SEQ(_ds) ((_ds)->ds_us.tx.ts_seqnum)
232 u16 reg_cap; 232#define ATH_DS_BA_BITMAP(_ds) (&(_ds)->ds_us.tx.ba_low)
233 u8 num_gpio_pins; 233#define ATH_DS_TX_BA(_ds) ((_ds)->ds_us.tx.ts_flags & ATH9K_TX_BA)
234 u8 num_antcfg_2ghz; 234#define ATH_AN_2_TID(_an, _tidno) (&(_an)->tid[(_tidno)])
235 u8 num_antcfg_5ghz; 235
236}; 236enum ATH_AGGR_STATUS {
237 237 ATH_AGGR_DONE,
238struct ath9k_ops_config { 238 ATH_AGGR_BAW_CLOSED,
239 int dma_beacon_response_time; 239 ATH_AGGR_LIMITED,
240 int sw_beacon_response_time; 240};
241 int additional_swba_backoff; 241
242 int ack_6mb; 242struct ath_txq {
243 int cwm_ignore_extcca; 243 u32 axq_qnum;
244 u8 pcie_powersave_enable; 244 u32 *axq_link;
245 u8 pcie_l1skp_enable; 245 struct list_head axq_q;
246 u8 pcie_clock_req; 246 spinlock_t axq_lock;
247 u32 pcie_waen; 247 u32 axq_depth;
248 int pcie_power_reset; 248 u8 axq_aggr_depth;
249 u8 pcie_restore; 249 u32 axq_totalqueued;
250 u8 analog_shiftreg; 250 bool stopped;
251 u8 ht_enable; 251 struct ath_buf *axq_linkbuf;
252 u32 ofdm_trig_low; 252
253 u32 ofdm_trig_high; 253 /* first desc of the last descriptor that contains CTS */
254 u32 cck_trig_high; 254 struct ath_desc *axq_lastdsWithCTS;
255 u32 cck_trig_low; 255
256 u32 enable_ani; 256 /* final desc of the gating desc that determines whether
257 u8 noise_immunity_level; 257 lastdsWithCTS has been DMA'ed or not */
258 u32 ofdm_weaksignal_det; 258 struct ath_desc *axq_gatingds;
259 u32 cck_weaksignal_thr; 259
260 u8 spur_immunity_level; 260 struct list_head axq_acq;
261 u8 firstep_level; 261};
262 int8_t rssi_thr_high; 262
263 int8_t rssi_thr_low; 263#define AGGR_CLEANUP BIT(1)
264 u16 diversity_control; 264#define AGGR_ADDBA_COMPLETE BIT(2)
265 u16 antenna_switch_swap; 265#define AGGR_ADDBA_PROGRESS BIT(3)
266 int serialize_regmode; 266
267 int intr_mitigation; 267struct ath_atx_tid {
268#define SPUR_DISABLE 0 268 struct list_head list;
269#define SPUR_ENABLE_IOCTL 1 269 struct list_head buf_q;
270#define SPUR_ENABLE_EEPROM 2 270 struct ath_node *an;
271#define AR_EEPROM_MODAL_SPURS 5 271 struct ath_atx_ac *ac;
272#define AR_SPUR_5413_1 1640 272 struct ath_buf *tx_buf[ATH_TID_MAX_BUFS];
273#define AR_SPUR_5413_2 1200 273 u16 seq_start;
274#define AR_NO_SPUR 0x8000 274 u16 seq_next;
275#define AR_BASE_FREQ_2GHZ 2300 275 u16 baw_size;
276#define AR_BASE_FREQ_5GHZ 4900 276 int tidno;
277#define AR_SPUR_FEEQ_BOUND_HT40 19 277 int baw_head; /* first un-acked tx buffer */
278#define AR_SPUR_FEEQ_BOUND_HT20 10 278 int baw_tail; /* next unused tx buffer slot */
279 int spurmode; 279 int sched;
280 u16 spurchans[AR_EEPROM_MODAL_SPURS][2]; 280 int paused;
281}; 281 u8 state;
282 282 int addba_exchangeattempts;
283enum ath9k_tx_queue { 283};
284 ATH9K_TX_QUEUE_INACTIVE = 0, 284
285 ATH9K_TX_QUEUE_DATA, 285struct ath_atx_ac {
286 ATH9K_TX_QUEUE_BEACON, 286 int sched;
287 ATH9K_TX_QUEUE_CAB, 287 int qnum;
288 ATH9K_TX_QUEUE_UAPSD, 288 struct list_head list;
289 ATH9K_TX_QUEUE_PSPOLL 289 struct list_head tid_q;
290}; 290};
291 291
292#define ATH9K_NUM_TX_QUEUES 10 292struct ath_tx_control {
293 293 struct ath_txq *txq;
294enum ath9k_tx_queue_subtype { 294 int if_id;
295 ATH9K_WME_AC_BK = 0, 295};
296 ATH9K_WME_AC_BE, 296
297 ATH9K_WME_AC_VI, 297struct ath_xmit_status {
298 ATH9K_WME_AC_VO, 298 int retries;
299 ATH9K_WME_UPSD 299 int flags;
300}; 300#define ATH_TX_ERROR 0x01
301 301#define ATH_TX_XRETRY 0x02
302enum ath9k_tx_queue_flags { 302#define ATH_TX_BAR 0x04
303 TXQ_FLAG_TXOKINT_ENABLE = 0x0001, 303};
304 TXQ_FLAG_TXERRINT_ENABLE = 0x0001, 304
305 TXQ_FLAG_TXDESCINT_ENABLE = 0x0002, 305/* All RSSI values are noise floor adjusted */
306 TXQ_FLAG_TXEOLINT_ENABLE = 0x0004, 306struct ath_tx_stat {
307 TXQ_FLAG_TXURNINT_ENABLE = 0x0008, 307 int rssi;
308 TXQ_FLAG_BACKOFF_DISABLE = 0x0010, 308 int rssictl[ATH_MAX_ANTENNA];
309 TXQ_FLAG_COMPRESSION_ENABLE = 0x0020, 309 int rssiextn[ATH_MAX_ANTENNA];
310 TXQ_FLAG_RDYTIME_EXP_POLICY_ENABLE = 0x0040, 310 int rateieee;
311 TXQ_FLAG_FRAG_BURST_BACKOFF_ENABLE = 0x0080, 311 int rateKbps;
312}; 312 int ratecode;
313 313 int flags;
314#define ATH9K_TXQ_USEDEFAULT ((u32) -1) 314 u32 airtime; /* time on air per final tx rate */
315 315};
316#define ATH9K_DECOMP_MASK_SIZE 128 316
317#define ATH9K_READY_TIME_LO_BOUND 50 317struct aggr_rifs_param {
318#define ATH9K_READY_TIME_HI_BOUND 96 318 int param_max_frames;
319 319 int param_max_len;
320enum ath9k_pkt_type { 320 int param_rl;
321 ATH9K_PKT_TYPE_NORMAL = 0, 321 int param_al;
322 ATH9K_PKT_TYPE_ATIM, 322 struct ath_rc_series *param_rcs;
323 ATH9K_PKT_TYPE_PSPOLL, 323};
324 ATH9K_PKT_TYPE_BEACON, 324
325 ATH9K_PKT_TYPE_PROBE_RESP, 325struct ath_node {
326 ATH9K_PKT_TYPE_CHIRP, 326 struct ath_softc *an_sc;
327 ATH9K_PKT_TYPE_GRP_POLL, 327 struct ath_atx_tid tid[WME_NUM_TID];
328}; 328 struct ath_atx_ac ac[WME_NUM_AC];
329 u16 maxampdu;
330 u8 mpdudensity;
331};
332
333struct ath_tx {
334 u16 seq_no;
335 u32 txqsetup;
336 int hwq_map[ATH9K_WME_AC_VO+1];
337 spinlock_t txbuflock;
338 struct list_head txbuf;
339 struct ath_txq txq[ATH9K_NUM_TX_QUEUES];
340 struct ath_descdma txdma;
341};
342
343struct ath_rx {
344 u8 defant;
345 u8 rxotherant;
346 u32 *rxlink;
347 int bufsize;
348 unsigned int rxfilter;
349 spinlock_t rxflushlock;
350 spinlock_t rxbuflock;
351 struct list_head rxbuf;
352 struct ath_descdma rxdma;
353};
354
355int ath_startrecv(struct ath_softc *sc);
356bool ath_stoprecv(struct ath_softc *sc);
357void ath_flushrecv(struct ath_softc *sc);
358u32 ath_calcrxfilter(struct ath_softc *sc);
359int ath_rx_init(struct ath_softc *sc, int nbufs);
360void ath_rx_cleanup(struct ath_softc *sc);
361int ath_rx_tasklet(struct ath_softc *sc, int flush);
362struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype);
363void ath_tx_cleanupq(struct ath_softc *sc, struct ath_txq *txq);
364int ath_tx_setup(struct ath_softc *sc, int haltype);
365void ath_drain_all_txq(struct ath_softc *sc, bool retry_tx);
366void ath_draintxq(struct ath_softc *sc,
367 struct ath_txq *txq, bool retry_tx);
368void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an);
369void ath_tx_node_cleanup(struct ath_softc *sc, struct ath_node *an);
370void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq);
371int ath_tx_init(struct ath_softc *sc, int nbufs);
372int ath_tx_cleanup(struct ath_softc *sc);
373struct ath_txq *ath_test_get_txq(struct ath_softc *sc, struct sk_buff *skb);
374int ath_txq_update(struct ath_softc *sc, int qnum,
375 struct ath9k_tx_queue_info *q);
376int ath_tx_start(struct ath_softc *sc, struct sk_buff *skb,
377 struct ath_tx_control *txctl);
378void ath_tx_tasklet(struct ath_softc *sc);
379void ath_tx_cabq(struct ath_softc *sc, struct sk_buff *skb);
380bool ath_tx_aggr_check(struct ath_softc *sc, struct ath_node *an, u8 tidno);
381int ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta,
382 u16 tid, u16 *ssn);
383int ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid);
384void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid);
385
386/********/
387/* VIFs */
388/********/
329 389
330struct ath9k_tx_queue_info { 390/*
331 u32 tqi_ver; 391 * Define the scheme that we select MAC address for multiple
332 enum ath9k_tx_queue tqi_type; 392 * BSS on the same radio. The very first VIF will just use the MAC
333 enum ath9k_tx_queue_subtype tqi_subtype; 393 * address from the EEPROM. For the next 3 VIFs, we set the
334 enum ath9k_tx_queue_flags tqi_qflags; 394 * U/L bit (bit 1) in MAC address, and use the next two bits as the
335 u32 tqi_priority; 395 * index of the VIF.
336 u32 tqi_aifs; 396 */
337 u32 tqi_cwmin;
338 u32 tqi_cwmax;
339 u16 tqi_shretry;
340 u16 tqi_lgretry;
341 u32 tqi_cbrPeriod;
342 u32 tqi_cbrOverflowLimit;
343 u32 tqi_burstTime;
344 u32 tqi_readyTime;
345 u32 tqi_physCompBuf;
346 u32 tqi_intFlags;
347};
348 397
349enum ath9k_rx_filter { 398#define ATH_SET_VIF_BSSID_MASK(bssid_mask) \
350 ATH9K_RX_FILTER_UCAST = 0x00000001, 399 ((bssid_mask)[0] &= ~(((ATH_BCBUF-1)<<2)|0x02))
351 ATH9K_RX_FILTER_MCAST = 0x00000002,
352 ATH9K_RX_FILTER_BCAST = 0x00000004,
353 ATH9K_RX_FILTER_CONTROL = 0x00000008,
354 ATH9K_RX_FILTER_BEACON = 0x00000010,
355 ATH9K_RX_FILTER_PROM = 0x00000020,
356 ATH9K_RX_FILTER_PROBEREQ = 0x00000080,
357 ATH9K_RX_FILTER_PSPOLL = 0x00004000,
358 ATH9K_RX_FILTER_PHYERR = 0x00000100,
359 ATH9K_RX_FILTER_PHYRADAR = 0x00002000,
360};
361 400
362enum ath9k_int { 401struct ath_vif {
363 ATH9K_INT_RX = 0x00000001, 402 int av_bslot;
364 ATH9K_INT_RXDESC = 0x00000002, 403 enum nl80211_iftype av_opmode;
365 ATH9K_INT_RXNOFRM = 0x00000008, 404 struct ath_buf *av_bcbuf;
366 ATH9K_INT_RXEOL = 0x00000010, 405 struct ath_tx_control av_btxctl;
367 ATH9K_INT_RXORN = 0x00000020,
368 ATH9K_INT_TX = 0x00000040,
369 ATH9K_INT_TXDESC = 0x00000080,
370 ATH9K_INT_TIM_TIMER = 0x00000100,
371 ATH9K_INT_TXURN = 0x00000800,
372 ATH9K_INT_MIB = 0x00001000,
373 ATH9K_INT_RXPHY = 0x00004000,
374 ATH9K_INT_RXKCM = 0x00008000,
375 ATH9K_INT_SWBA = 0x00010000,
376 ATH9K_INT_BMISS = 0x00040000,
377 ATH9K_INT_BNR = 0x00100000,
378 ATH9K_INT_TIM = 0x00200000,
379 ATH9K_INT_DTIM = 0x00400000,
380 ATH9K_INT_DTIMSYNC = 0x00800000,
381 ATH9K_INT_GPIO = 0x01000000,
382 ATH9K_INT_CABEND = 0x02000000,
383 ATH9K_INT_CST = 0x10000000,
384 ATH9K_INT_GTT = 0x20000000,
385 ATH9K_INT_FATAL = 0x40000000,
386 ATH9K_INT_GLOBAL = 0x80000000,
387 ATH9K_INT_BMISC = ATH9K_INT_TIM |
388 ATH9K_INT_DTIM |
389 ATH9K_INT_DTIMSYNC |
390 ATH9K_INT_CABEND,
391 ATH9K_INT_COMMON = ATH9K_INT_RXNOFRM |
392 ATH9K_INT_RXDESC |
393 ATH9K_INT_RXEOL |
394 ATH9K_INT_RXORN |
395 ATH9K_INT_TXURN |
396 ATH9K_INT_TXDESC |
397 ATH9K_INT_MIB |
398 ATH9K_INT_RXPHY |
399 ATH9K_INT_RXKCM |
400 ATH9K_INT_SWBA |
401 ATH9K_INT_BMISS |
402 ATH9K_INT_GPIO,
403 ATH9K_INT_NOCARD = 0xffffffff
404}; 406};
405 407
406#define ATH9K_RATESERIES_RTS_CTS 0x0001 408/*******************/
407#define ATH9K_RATESERIES_2040 0x0002 409/* Beacon Handling */
408#define ATH9K_RATESERIES_HALFGI 0x0004 410/*******************/
409 411
410struct ath9k_11n_rate_series { 412/*
411 u32 Tries; 413 * Regardless of the number of beacons we stagger, (i.e. regardless of the
412 u32 Rate; 414 * number of BSSIDs) if a given beacon does not go out even after waiting this
413 u32 PktDuration; 415 * number of beacon intervals, the game's up.
414 u32 ChSel; 416 */
415 u32 RateFlags; 417#define BSTUCK_THRESH (9 * ATH_BCBUF)
416}; 418#define ATH_BCBUF 1
419#define ATH_DEFAULT_BINTVAL 100 /* TU */
420#define ATH_DEFAULT_BMISS_LIMIT 10
421#define IEEE80211_MS_TO_TU(x) (((x) * 1000) / 1024)
422
423struct ath_beacon_config {
424 u16 beacon_interval;
425 u16 listen_interval;
426 u16 dtim_period;
427 u16 bmiss_timeout;
428 u8 dtim_count;
429 u8 tim_offset;
430 union {
431 u64 last_tsf;
432 u8 last_tstamp[8];
433 } u; /* last received beacon/probe response timestamp of this BSS. */
434};
435
436struct ath_beacon {
437 enum {
438 OK, /* no change needed */
439 UPDATE, /* update pending */
440 COMMIT /* beacon sent, commit change */
441 } updateslot; /* slot time update fsm */
442
443 u32 beaconq;
444 u32 bmisscnt;
445 u32 ast_be_xmit;
446 u64 bc_tstamp;
447 int bslot[ATH_BCBUF];
448 int slottime;
449 int slotupdate;
450 struct ath9k_tx_queue_info beacon_qi;
451 struct ath_descdma bdma;
452 struct ath_txq *cabq;
453 struct list_head bbuf;
454};
455
456void ath9k_beacon_tasklet(unsigned long data);
457void ath_beacon_config(struct ath_softc *sc, int if_id);
458int ath_beaconq_setup(struct ath_hw *ah);
459int ath_beacon_alloc(struct ath_softc *sc, int if_id);
460void ath_beacon_return(struct ath_softc *sc, struct ath_vif *avp);
461void ath_beacon_sync(struct ath_softc *sc, int if_id);
462
463/*******/
464/* ANI */
465/*******/
417 466
418#define CHANNEL_CW_INT 0x00002 467/* ANI values for STA only.
419#define CHANNEL_CCK 0x00020 468 FIXME: Add appropriate values for AP later */
420#define CHANNEL_OFDM 0x00040
421#define CHANNEL_2GHZ 0x00080
422#define CHANNEL_5GHZ 0x00100
423#define CHANNEL_PASSIVE 0x00200
424#define CHANNEL_DYN 0x00400
425#define CHANNEL_HALF 0x04000
426#define CHANNEL_QUARTER 0x08000
427#define CHANNEL_HT20 0x10000
428#define CHANNEL_HT40PLUS 0x20000
429#define CHANNEL_HT40MINUS 0x40000
430
431#define CHANNEL_INTERFERENCE 0x01
432#define CHANNEL_DFS 0x02
433#define CHANNEL_4MS_LIMIT 0x04
434#define CHANNEL_DFS_CLEAR 0x08
435#define CHANNEL_DISALLOW_ADHOC 0x10
436#define CHANNEL_PER_11D_ADHOC 0x20
437
438#define CHANNEL_A (CHANNEL_5GHZ|CHANNEL_OFDM)
439#define CHANNEL_B (CHANNEL_2GHZ|CHANNEL_CCK)
440#define CHANNEL_G (CHANNEL_2GHZ|CHANNEL_OFDM)
441#define CHANNEL_G_HT20 (CHANNEL_2GHZ|CHANNEL_HT20)
442#define CHANNEL_A_HT20 (CHANNEL_5GHZ|CHANNEL_HT20)
443#define CHANNEL_G_HT40PLUS (CHANNEL_2GHZ|CHANNEL_HT40PLUS)
444#define CHANNEL_G_HT40MINUS (CHANNEL_2GHZ|CHANNEL_HT40MINUS)
445#define CHANNEL_A_HT40PLUS (CHANNEL_5GHZ|CHANNEL_HT40PLUS)
446#define CHANNEL_A_HT40MINUS (CHANNEL_5GHZ|CHANNEL_HT40MINUS)
447#define CHANNEL_ALL \
448 (CHANNEL_OFDM| \
449 CHANNEL_CCK| \
450 CHANNEL_2GHZ | \
451 CHANNEL_5GHZ | \
452 CHANNEL_HT20 | \
453 CHANNEL_HT40PLUS | \
454 CHANNEL_HT40MINUS)
455
456struct ath9k_channel {
457 struct ieee80211_channel *chan;
458 u16 channel;
459 u32 channelFlags;
460 u32 chanmode;
461 int32_t CalValid;
462 bool oneTimeCalsDone;
463 int8_t iCoff;
464 int8_t qCoff;
465 int16_t rawNoiseFloor;
466};
467 469
468#define IS_CHAN_A(_c) ((((_c)->channelFlags & CHANNEL_A) == CHANNEL_A) || \ 470#define ATH_ANI_POLLINTERVAL 100 /* 100 milliseconds between ANI poll */
469 (((_c)->channelFlags & CHANNEL_A_HT20) == CHANNEL_A_HT20) || \ 471#define ATH_SHORT_CALINTERVAL 1000 /* 1 second between calibrations */
470 (((_c)->channelFlags & CHANNEL_A_HT40PLUS) == CHANNEL_A_HT40PLUS) || \ 472#define ATH_LONG_CALINTERVAL 30000 /* 30 seconds between calibrations */
471 (((_c)->channelFlags & CHANNEL_A_HT40MINUS) == CHANNEL_A_HT40MINUS)) 473#define ATH_RESTART_CALINTERVAL 1200000 /* 20 minutes between calibrations */
472#define IS_CHAN_G(_c) ((((_c)->channelFlags & (CHANNEL_G)) == CHANNEL_G) || \
473 (((_c)->channelFlags & CHANNEL_G_HT20) == CHANNEL_G_HT20) || \
474 (((_c)->channelFlags & CHANNEL_G_HT40PLUS) == CHANNEL_G_HT40PLUS) || \
475 (((_c)->channelFlags & CHANNEL_G_HT40MINUS) == CHANNEL_G_HT40MINUS))
476#define IS_CHAN_OFDM(_c) (((_c)->channelFlags & CHANNEL_OFDM) != 0)
477#define IS_CHAN_5GHZ(_c) (((_c)->channelFlags & CHANNEL_5GHZ) != 0)
478#define IS_CHAN_2GHZ(_c) (((_c)->channelFlags & CHANNEL_2GHZ) != 0)
479#define IS_CHAN_PASSIVE(_c) (((_c)->channelFlags & CHANNEL_PASSIVE) != 0)
480#define IS_CHAN_HALF_RATE(_c) (((_c)->channelFlags & CHANNEL_HALF) != 0)
481#define IS_CHAN_QUARTER_RATE(_c) (((_c)->channelFlags & CHANNEL_QUARTER) != 0)
482
483/* These macros check chanmode and not channelFlags */
484#define IS_CHAN_B(_c) ((_c)->chanmode == CHANNEL_B)
485#define IS_CHAN_HT20(_c) (((_c)->chanmode == CHANNEL_A_HT20) || \
486 ((_c)->chanmode == CHANNEL_G_HT20))
487#define IS_CHAN_HT40(_c) (((_c)->chanmode == CHANNEL_A_HT40PLUS) || \
488 ((_c)->chanmode == CHANNEL_A_HT40MINUS) || \
489 ((_c)->chanmode == CHANNEL_G_HT40PLUS) || \
490 ((_c)->chanmode == CHANNEL_G_HT40MINUS))
491#define IS_CHAN_HT(_c) (IS_CHAN_HT20((_c)) || IS_CHAN_HT40((_c)))
492
493#define IS_CHAN_A_5MHZ_SPACED(_c) \
494 ((((_c)->channelFlags & CHANNEL_5GHZ) != 0) && \
495 (((_c)->channel % 20) != 0) && \
496 (((_c)->channel % 10) != 0))
497
498struct ath9k_keyval {
499 u8 kv_type;
500 u8 kv_pad;
501 u16 kv_len;
502 u8 kv_val[16];
503 u8 kv_mic[8];
504 u8 kv_txmic[8];
505};
506 474
507enum ath9k_key_type { 475struct ath_ani {
508 ATH9K_KEY_TYPE_CLEAR, 476 bool caldone;
509 ATH9K_KEY_TYPE_WEP, 477 int16_t noise_floor;
510 ATH9K_KEY_TYPE_AES, 478 unsigned int longcal_timer;
511 ATH9K_KEY_TYPE_TKIP, 479 unsigned int shortcal_timer;
480 unsigned int resetcal_timer;
481 unsigned int checkani_timer;
482 struct timer_list timer;
512}; 483};
513 484
514enum ath9k_cipher { 485/********************/
515 ATH9K_CIPHER_WEP = 0, 486/* LED Control */
516 ATH9K_CIPHER_AES_OCB = 1, 487/********************/
517 ATH9K_CIPHER_AES_CCM = 2,
518 ATH9K_CIPHER_CKIP = 3,
519 ATH9K_CIPHER_TKIP = 4,
520 ATH9K_CIPHER_CLR = 5,
521 ATH9K_CIPHER_MIC = 127
522};
523 488
524#define AR_EEPROM_EEPCAP_COMPRESS_DIS 0x0001 489#define ATH_LED_PIN 1
525#define AR_EEPROM_EEPCAP_AES_DIS 0x0002 490#define ATH_LED_ON_DURATION_IDLE 350 /* in msecs */
526#define AR_EEPROM_EEPCAP_FASTFRAME_DIS 0x0004 491#define ATH_LED_OFF_DURATION_IDLE 250 /* in msecs */
527#define AR_EEPROM_EEPCAP_BURST_DIS 0x0008
528#define AR_EEPROM_EEPCAP_MAXQCU 0x01F0
529#define AR_EEPROM_EEPCAP_MAXQCU_S 4
530#define AR_EEPROM_EEPCAP_HEAVY_CLIP_EN 0x0200
531#define AR_EEPROM_EEPCAP_KC_ENTRIES 0xF000
532#define AR_EEPROM_EEPCAP_KC_ENTRIES_S 12
533
534#define AR_EEPROM_EEREGCAP_EN_FCC_MIDBAND 0x0040
535#define AR_EEPROM_EEREGCAP_EN_KK_U1_EVEN 0x0080
536#define AR_EEPROM_EEREGCAP_EN_KK_U2 0x0100
537#define AR_EEPROM_EEREGCAP_EN_KK_MIDBAND 0x0200
538#define AR_EEPROM_EEREGCAP_EN_KK_U1_ODD 0x0400
539#define AR_EEPROM_EEREGCAP_EN_KK_NEW_11A 0x0800
540
541#define AR_EEPROM_EEREGCAP_EN_KK_U1_ODD_PRE4_0 0x4000
542#define AR_EEPROM_EEREGCAP_EN_KK_NEW_11A_PRE4_0 0x8000
543
544#define SD_NO_CTL 0xE0
545#define NO_CTL 0xff
546#define CTL_MODE_M 7
547#define CTL_11A 0
548#define CTL_11B 1
549#define CTL_11G 2
550#define CTL_2GHT20 5
551#define CTL_5GHT20 6
552#define CTL_2GHT40 7
553#define CTL_5GHT40 8
554
555#define AR_EEPROM_MAC(i) (0x1d+(i))
556
557#define AR_EEPROM_RFSILENT_GPIO_SEL 0x001c
558#define AR_EEPROM_RFSILENT_GPIO_SEL_S 2
559#define AR_EEPROM_RFSILENT_POLARITY 0x0002
560#define AR_EEPROM_RFSILENT_POLARITY_S 1
561
562#define CTRY_DEBUG 0x1ff
563#define CTRY_DEFAULT 0
564
565enum reg_ext_bitmap {
566 REG_EXT_JAPAN_MIDBAND = 1,
567 REG_EXT_FCC_DFS_HT40 = 2,
568 REG_EXT_JAPAN_NONDFS_HT40 = 3,
569 REG_EXT_JAPAN_DFS_HT40 = 4
570};
571 492
572struct ath9k_country_entry { 493enum ath_led_type {
573 u16 countryCode; 494 ATH_LED_RADIO,
574 u16 regDmnEnum; 495 ATH_LED_ASSOC,
575 u16 regDmn5G; 496 ATH_LED_TX,
576 u16 regDmn2G; 497 ATH_LED_RX
577 u8 isMultidomain;
578 u8 iso[3];
579}; 498};
580 499
581#define REG_WRITE(_ah, _reg, _val) iowrite32(_val, _ah->ah_sh + _reg) 500struct ath_led {
582#define REG_READ(_ah, _reg) ioread32(_ah->ah_sh + _reg) 501 struct ath_softc *sc;
583 502 struct led_classdev led_cdev;
584#define SM(_v, _f) (((_v) << _f##_S) & _f) 503 enum ath_led_type led_type;
585#define MS(_v, _f) (((_v) & _f) >> _f##_S) 504 char name[32];
586#define REG_RMW(_a, _r, _set, _clr) \ 505 bool registered;
587 REG_WRITE(_a, _r, (REG_READ(_a, _r) & ~(_clr)) | (_set))
588#define REG_RMW_FIELD(_a, _r, _f, _v) \
589 REG_WRITE(_a, _r, \
590 (REG_READ(_a, _r) & ~_f) | (((_v) << _f##_S) & _f))
591#define REG_SET_BIT(_a, _r, _f) \
592 REG_WRITE(_a, _r, REG_READ(_a, _r) | _f)
593#define REG_CLR_BIT(_a, _r, _f) \
594 REG_WRITE(_a, _r, REG_READ(_a, _r) & ~_f)
595
596#define ATH9K_TXQ_USE_LOCKOUT_BKOFF_DIS 0x00000001
597
598#define INIT_AIFS 2
599#define INIT_CWMIN 15
600#define INIT_CWMIN_11B 31
601#define INIT_CWMAX 1023
602#define INIT_SH_RETRY 10
603#define INIT_LG_RETRY 10
604#define INIT_SSH_RETRY 32
605#define INIT_SLG_RETRY 32
606
607#define WLAN_CTRL_FRAME_SIZE (2+2+6+4)
608
609#define ATH_AMPDU_LIMIT_MAX (64 * 1024 - 1)
610#define ATH_AMPDU_LIMIT_DEFAULT ATH_AMPDU_LIMIT_MAX
611
612#define IEEE80211_WEP_IVLEN 3
613#define IEEE80211_WEP_KIDLEN 1
614#define IEEE80211_WEP_CRCLEN 4
615#define IEEE80211_MAX_MPDU_LEN (3840 + FCS_LEN + \
616 (IEEE80211_WEP_IVLEN + \
617 IEEE80211_WEP_KIDLEN + \
618 IEEE80211_WEP_CRCLEN))
619#define MAX_RATE_POWER 63
620
621enum ath9k_power_mode {
622 ATH9K_PM_AWAKE = 0,
623 ATH9K_PM_FULL_SLEEP,
624 ATH9K_PM_NETWORK_SLEEP,
625 ATH9K_PM_UNDEFINED
626}; 506};
627 507
628struct ath9k_mib_stats { 508/* Rfkill */
629 u32 ackrcv_bad; 509#define ATH_RFKILL_POLL_INTERVAL 2000 /* msecs */
630 u32 rts_bad;
631 u32 rts_good;
632 u32 fcs_bad;
633 u32 beacons;
634};
635 510
636enum ath9k_ant_setting { 511struct ath_rfkill {
637 ATH9K_ANT_VARIABLE = 0, 512 struct rfkill *rfkill;
638 ATH9K_ANT_FIXED_A, 513 struct delayed_work rfkill_poll;
639 ATH9K_ANT_FIXED_B 514 char rfkill_name[32];
640}; 515};
641 516
642#define ATH9K_SLOT_TIME_6 6 517/********************/
643#define ATH9K_SLOT_TIME_9 9 518/* Main driver core */
644#define ATH9K_SLOT_TIME_20 20 519/********************/
645 520
646enum ath9k_ht_macmode { 521/*
647 ATH9K_HT_MACMODE_20 = 0, 522 * Default cache line size, in bytes.
648 ATH9K_HT_MACMODE_2040 = 1, 523 * Used when PCI device not fully initialized by bootrom/BIOS
649}; 524*/
650 525#define DEFAULT_CACHELINE 32
651enum ath9k_ht_extprotspacing { 526#define ATH_DEFAULT_NOISE_FLOOR -95
652 ATH9K_HT_EXTPROTSPACING_20 = 0, 527#define ATH_REGCLASSIDS_MAX 10
653 ATH9K_HT_EXTPROTSPACING_25 = 1, 528#define ATH_CABQ_READY_TIME 80 /* % of beacon interval */
654}; 529#define ATH_MAX_SW_RETRIES 10
530#define ATH_CHAN_MAX 255
531#define IEEE80211_WEP_NKID 4 /* number of key ids */
655 532
656struct ath9k_ht_cwm { 533/*
657 enum ath9k_ht_macmode ht_macmode; 534 * The key cache is used for h/w cipher state and also for
535 * tracking station state such as the current tx antenna.
536 * We also setup a mapping table between key cache slot indices
537 * and station state to short-circuit node lookups on rx.
538 * Different parts have different size key caches. We handle
539 * up to ATH_KEYMAX entries (could dynamically allocate state).
540 */
541#define ATH_KEYMAX 128 /* max key cache size we handle */
542
543#define ATH_IF_ID_ANY 0xff
544#define ATH_TXPOWER_MAX 100 /* .5 dBm units */
545#define ATH_RSSI_DUMMY_MARKER 0x127
546#define ATH_RATE_DUMMY_MARKER 0
547
548#define SC_OP_INVALID BIT(0)
549#define SC_OP_BEACONS BIT(1)
550#define SC_OP_RXAGGR BIT(2)
551#define SC_OP_TXAGGR BIT(3)
552#define SC_OP_CHAINMASK_UPDATE BIT(4)
553#define SC_OP_FULL_RESET BIT(5)
554#define SC_OP_NO_RESET BIT(6)
555#define SC_OP_PREAMBLE_SHORT BIT(7)
556#define SC_OP_PROTECT_ENABLE BIT(8)
557#define SC_OP_RXFLUSH BIT(9)
558#define SC_OP_LED_ASSOCIATED BIT(10)
559#define SC_OP_RFKILL_REGISTERED BIT(11)
560#define SC_OP_RFKILL_SW_BLOCKED BIT(12)
561#define SC_OP_RFKILL_HW_BLOCKED BIT(13)
562#define SC_OP_WAIT_FOR_BEACON BIT(14)
563#define SC_OP_LED_ON BIT(15)
564
565struct ath_bus_ops {
566 void (*read_cachesize)(struct ath_softc *sc, int *csz);
567 void (*cleanup)(struct ath_softc *sc);
568 bool (*eeprom_read)(struct ath_hw *ah, u32 off, u16 *data);
569};
570
571struct ath_softc {
572 struct ieee80211_hw *hw;
573 struct device *dev;
574 struct tasklet_struct intr_tq;
575 struct tasklet_struct bcon_tasklet;
576 struct ath_hw *sc_ah;
577 void __iomem *mem;
578 int irq;
579 spinlock_t sc_resetlock;
580 struct mutex mutex;
581
582 u8 curbssid[ETH_ALEN];
583 u8 bssidmask[ETH_ALEN];
584 u32 intrstatus;
585 u32 sc_flags; /* SC_OP_* */
586 u16 curtxpow;
587 u16 curaid;
588 u16 cachelsz;
589 u8 nbcnvifs;
590 u16 nvifs;
591 u8 tx_chainmask;
592 u8 rx_chainmask;
593 u32 keymax;
594 DECLARE_BITMAP(keymap, ATH_KEYMAX);
595 u8 splitmic;
596 atomic_t ps_usecount;
597 enum ath9k_int imask;
658 enum ath9k_ht_extprotspacing ht_extprotspacing; 598 enum ath9k_ht_extprotspacing ht_extprotspacing;
659}; 599 enum ath9k_ht_macmode tx_chan_width;
660 600
661enum ath9k_ani_cmd { 601 struct ath_config config;
662 ATH9K_ANI_PRESENT = 0x1, 602 struct ath_rx rx;
663 ATH9K_ANI_NOISE_IMMUNITY_LEVEL = 0x2, 603 struct ath_tx tx;
664 ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION = 0x4, 604 struct ath_beacon beacon;
665 ATH9K_ANI_CCK_WEAK_SIGNAL_THR = 0x8, 605 struct ieee80211_vif *vifs[ATH_BCBUF];
666 ATH9K_ANI_FIRSTEP_LEVEL = 0x10, 606 struct ieee80211_rate rates[IEEE80211_NUM_BANDS][ATH_RATE_MAX];
667 ATH9K_ANI_SPUR_IMMUNITY_LEVEL = 0x20, 607 struct ath_rate_table *hw_rate_table[ATH9K_MODE_MAX];
668 ATH9K_ANI_MODE = 0x40, 608 struct ath_rate_table *cur_rate_table;
669 ATH9K_ANI_PHYERR_RESET = 0x80, 609 struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS];
670 ATH9K_ANI_ALL = 0xff 610
671}; 611 struct ath_led radio_led;
672 612 struct ath_led assoc_led;
673enum { 613 struct ath_led tx_led;
674 WLAN_RC_PHY_OFDM, 614 struct ath_led rx_led;
675 WLAN_RC_PHY_CCK, 615 struct delayed_work ath_led_blink_work;
676 WLAN_RC_PHY_HT_20_SS, 616 int led_on_duration;
677 WLAN_RC_PHY_HT_20_DS, 617 int led_off_duration;
678 WLAN_RC_PHY_HT_40_SS, 618 int led_on_cnt;
679 WLAN_RC_PHY_HT_40_DS, 619 int led_off_cnt;
680 WLAN_RC_PHY_HT_20_SS_HGI, 620
681 WLAN_RC_PHY_HT_20_DS_HGI, 621 struct ath_rfkill rf_kill;
682 WLAN_RC_PHY_HT_40_SS_HGI, 622 struct ath_ani ani;
683 WLAN_RC_PHY_HT_40_DS_HGI, 623 struct ath9k_node_stats nodestats;
684 WLAN_RC_PHY_MAX 624#ifdef CONFIG_ATH9K_DEBUG
685}; 625 struct ath9k_debug debug;
686 626#endif
687enum ath9k_tp_scale { 627 struct ath_bus_ops *bus_ops;
688 ATH9K_TP_SCALE_MAX = 0, 628};
689 ATH9K_TP_SCALE_50, 629
690 ATH9K_TP_SCALE_25, 630int ath_reset(struct ath_softc *sc, bool retry_tx);
691 ATH9K_TP_SCALE_12, 631int ath_get_hal_qnum(u16 queue, struct ath_softc *sc);
692 ATH9K_TP_SCALE_MIN 632int ath_get_mac80211_qnum(u32 queue, struct ath_softc *sc);
693}; 633int ath_cabq_update(struct ath_softc *);
694 634
695enum ser_reg_mode { 635static inline void ath_read_cachesize(struct ath_softc *sc, int *csz)
696 SER_REG_MODE_OFF = 0, 636{
697 SER_REG_MODE_ON = 1, 637 sc->bus_ops->read_cachesize(sc, csz);
698 SER_REG_MODE_AUTO = 2, 638}
699}; 639
700 640static inline void ath_bus_cleanup(struct ath_softc *sc)
701#define AR_PHY_CCA_MAX_GOOD_VALUE -85 641{
702#define AR_PHY_CCA_MAX_HIGH_VALUE -62 642 sc->bus_ops->cleanup(sc);
703#define AR_PHY_CCA_MIN_BAD_VALUE -121 643}
704#define AR_PHY_CCA_FILTERWINDOW_LENGTH_INIT 3 644
705#define AR_PHY_CCA_FILTERWINDOW_LENGTH 5 645extern struct ieee80211_ops ath9k_ops;
706 646
707#define ATH9K_NF_CAL_HIST_MAX 5 647irqreturn_t ath_isr(int irq, void *dev);
708#define NUM_NF_READINGS 6 648void ath_cleanup(struct ath_softc *sc);
709 649int ath_attach(u16 devid, struct ath_softc *sc);
710struct ath9k_nfcal_hist { 650void ath_detach(struct ath_softc *sc);
711 int16_t nfCalBuffer[ATH9K_NF_CAL_HIST_MAX]; 651const char *ath_mac_bb_name(u32 mac_bb_version);
712 u8 currIndex; 652const char *ath_rf_name(u16 rf_version);
713 int16_t privNF; 653
714 u8 invalidNFcount; 654#ifdef CONFIG_PCI
715}; 655int ath_pci_init(void);
716 656void ath_pci_exit(void);
717struct ath9k_beacon_state { 657#else
718 u32 bs_nexttbtt; 658static inline int ath_pci_init(void) { return 0; };
719 u32 bs_nextdtim; 659static inline void ath_pci_exit(void) {};
720 u32 bs_intval;
721#define ATH9K_BEACON_PERIOD 0x0000ffff
722#define ATH9K_BEACON_ENA 0x00800000
723#define ATH9K_BEACON_RESET_TSF 0x01000000
724 u32 bs_dtimperiod;
725 u16 bs_cfpperiod;
726 u16 bs_cfpmaxduration;
727 u32 bs_cfpnext;
728 u16 bs_timoffset;
729 u16 bs_bmissthreshold;
730 u32 bs_sleepduration;
731};
732
733struct ath9k_node_stats {
734 u32 ns_avgbrssi;
735 u32 ns_avgrssi;
736 u32 ns_avgtxrssi;
737 u32 ns_avgtxrate;
738};
739
740#define ATH9K_RSSI_EP_MULTIPLIER (1<<7)
741
742#define AR_GPIO_OUTPUT_MUX_AS_OUTPUT 0
743#define AR_GPIO_OUTPUT_MUX_AS_PCIE_ATTENTION_LED 1
744#define AR_GPIO_OUTPUT_MUX_AS_PCIE_POWER_LED 2
745#define AR_GPIO_OUTPUT_MUX_AS_TX_FRAME 3
746#define AR_GPIO_OUTPUT_MUX_AS_MAC_NETWORK_LED 5
747#define AR_GPIO_OUTPUT_MUX_AS_MAC_POWER_LED 6
748
749enum {
750 ATH9K_RESET_POWER_ON,
751 ATH9K_RESET_WARM,
752 ATH9K_RESET_COLD,
753};
754
755#define AH_USE_EEPROM 0x1
756
757struct ath_hal {
758 u32 ah_magic;
759 u16 ah_devid;
760 u16 ah_subvendorid;
761 u32 ah_macVersion;
762 u16 ah_macRev;
763 u16 ah_phyRev;
764 u16 ah_analog5GhzRev;
765 u16 ah_analog2GhzRev;
766
767 void __iomem *ah_sh;
768 struct ath_softc *ah_sc;
769
770 enum nl80211_iftype ah_opmode;
771 struct ath9k_ops_config ah_config;
772 struct ath9k_hw_capabilities ah_caps;
773
774 u16 ah_countryCode;
775 u32 ah_flags;
776 int16_t ah_powerLimit;
777 u16 ah_maxPowerLevel;
778 u32 ah_tpScale;
779 u16 ah_currentRD;
780 u16 ah_currentRDExt;
781 u16 ah_currentRDInUse;
782 char alpha2[2];
783 struct reg_dmn_pair_mapping *regpair;
784 enum ath9k_power_mode ah_power_mode;
785 enum ath9k_power_mode ah_restore_mode;
786
787 struct ath9k_channel ah_channels[38];
788 struct ath9k_channel *ah_curchan;
789
790 bool ah_isPciExpress;
791 u16 ah_txTrigLevel;
792 u16 ah_rfsilent;
793 u32 ah_rfkill_gpio;
794 u32 ah_rfkill_polarity;
795 u32 ah_btactive_gpio;
796 u32 ah_wlanactive_gpio;
797 struct ath9k_nfcal_hist nfCalHist[NUM_NF_READINGS];
798
799 bool sw_mgmt_crypto;
800};
801
802struct chan_centers {
803 u16 synth_center;
804 u16 ctl_center;
805 u16 ext_center;
806};
807
808struct ath_rate_table;
809
810/* Helpers */
811
812bool ath9k_hw_wait(struct ath_hal *ah, u32 reg, u32 mask, u32 val);
813u32 ath9k_hw_reverse_bits(u32 val, u32 n);
814bool ath9k_get_channel_edges(struct ath_hal *ah,
815 u16 flags, u16 *low,
816 u16 *high);
817u16 ath9k_hw_computetxtime(struct ath_hal *ah,
818 struct ath_rate_table *rates,
819 u32 frameLen, u16 rateix,
820 bool shortPreamble);
821void ath9k_hw_get_channel_centers(struct ath_hal *ah,
822 struct ath9k_channel *chan,
823 struct chan_centers *centers);
824
825/* Attach, Detach */
826
827const char *ath9k_hw_probe(u16 vendorid, u16 devid);
828void ath9k_hw_detach(struct ath_hal *ah);
829struct ath_hal *ath9k_hw_attach(u16 devid, struct ath_softc *sc,
830 void __iomem *mem, int *error);
831void ath9k_hw_rfdetach(struct ath_hal *ah);
832
833
834/* HW Reset */
835
836int ath9k_hw_reset(struct ath_hal *ah, struct ath9k_channel *chan,
837 bool bChannelChange);
838
839/* Key Cache Management */
840
841bool ath9k_hw_keyreset(struct ath_hal *ah, u16 entry);
842bool ath9k_hw_keysetmac(struct ath_hal *ah, u16 entry, const u8 *mac);
843bool ath9k_hw_set_keycache_entry(struct ath_hal *ah, u16 entry,
844 const struct ath9k_keyval *k,
845 const u8 *mac, int xorKey);
846bool ath9k_hw_keyisvalid(struct ath_hal *ah, u16 entry);
847
848/* Power Management */
849
850bool ath9k_hw_setpower(struct ath_hal *ah,
851 enum ath9k_power_mode mode);
852void ath9k_hw_configpcipowersave(struct ath_hal *ah, int restore);
853
854/* Beacon timers */
855
856void ath9k_hw_beaconinit(struct ath_hal *ah, u32 next_beacon, u32 beacon_period);
857void ath9k_hw_set_sta_beacon_timers(struct ath_hal *ah,
858 const struct ath9k_beacon_state *bs);
859/* HW Capabilities */
860
861bool ath9k_hw_fill_cap_info(struct ath_hal *ah);
862bool ath9k_hw_getcapability(struct ath_hal *ah, enum ath9k_capability_type type,
863 u32 capability, u32 *result);
864bool ath9k_hw_setcapability(struct ath_hal *ah, enum ath9k_capability_type type,
865 u32 capability, u32 setting, int *status);
866
867/* GPIO / RFKILL / Antennae */
868
869void ath9k_hw_cfg_gpio_input(struct ath_hal *ah, u32 gpio);
870u32 ath9k_hw_gpio_get(struct ath_hal *ah, u32 gpio);
871void ath9k_hw_cfg_output(struct ath_hal *ah, u32 gpio,
872 u32 ah_signal_type);
873void ath9k_hw_set_gpio(struct ath_hal *ah, u32 gpio, u32 val);
874#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
875void ath9k_enable_rfkill(struct ath_hal *ah);
876#endif 660#endif
877u32 ath9k_hw_getdefantenna(struct ath_hal *ah);
878void ath9k_hw_setantenna(struct ath_hal *ah, u32 antenna);
879bool ath9k_hw_setantennaswitch(struct ath_hal *ah,
880 enum ath9k_ant_setting settings,
881 struct ath9k_channel *chan,
882 u8 *tx_chainmask,
883 u8 *rx_chainmask,
884 u8 *antenna_cfgd);
885
886/* General Operation */
887
888u32 ath9k_hw_getrxfilter(struct ath_hal *ah);
889void ath9k_hw_setrxfilter(struct ath_hal *ah, u32 bits);
890bool ath9k_hw_phy_disable(struct ath_hal *ah);
891bool ath9k_hw_disable(struct ath_hal *ah);
892bool ath9k_hw_set_txpowerlimit(struct ath_hal *ah, u32 limit);
893void ath9k_hw_getmac(struct ath_hal *ah, u8 *mac);
894bool ath9k_hw_setmac(struct ath_hal *ah, const u8 *mac);
895void ath9k_hw_setopmode(struct ath_hal *ah);
896void ath9k_hw_setmcastfilter(struct ath_hal *ah, u32 filter0, u32 filter1);
897void ath9k_hw_getbssidmask(struct ath_hal *ah, u8 *mask);
898bool ath9k_hw_setbssidmask(struct ath_hal *ah, const u8 *mask);
899void ath9k_hw_write_associd(struct ath_hal *ah, const u8 *bssid, u16 assocId);
900u64 ath9k_hw_gettsf64(struct ath_hal *ah);
901void ath9k_hw_settsf64(struct ath_hal *ah, u64 tsf64);
902void ath9k_hw_reset_tsf(struct ath_hal *ah);
903bool ath9k_hw_set_tsfadjust(struct ath_hal *ah, u32 setting);
904bool ath9k_hw_setslottime(struct ath_hal *ah, u32 us);
905void ath9k_hw_set11nmac2040(struct ath_hal *ah, enum ath9k_ht_macmode mode);
906
907/* Regulatory */
908u16 ath9k_regd_get_rd(struct ath_hal *ah);
909bool ath9k_is_world_regd(struct ath_hal *ah);
910const struct ieee80211_regdomain *ath9k_world_regdomain(struct ath_hal *ah);
911const struct ieee80211_regdomain *ath9k_default_world_regdomain(void);
912
913void ath9k_reg_apply_world_flags(struct wiphy *wiphy, enum reg_set_by setby);
914void ath9k_reg_apply_radar_flags(struct wiphy *wiphy);
915
916int ath9k_regd_init(struct ath_hal *ah);
917bool ath9k_regd_is_eeprom_valid(struct ath_hal *ah);
918u32 ath9k_regd_get_ctl(struct ath_hal *ah, struct ath9k_channel *chan);
919int ath9k_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request);
920
921/* ANI */
922
923void ath9k_ani_reset(struct ath_hal *ah);
924void ath9k_hw_ani_monitor(struct ath_hal *ah,
925 const struct ath9k_node_stats *stats,
926 struct ath9k_channel *chan);
927bool ath9k_hw_phycounters(struct ath_hal *ah);
928void ath9k_enable_mib_counters(struct ath_hal *ah);
929void ath9k_hw_disable_mib_counters(struct ath_hal *ah);
930u32 ath9k_hw_GetMibCycleCountsPct(struct ath_hal *ah,
931 u32 *rxc_pcnt,
932 u32 *rxf_pcnt,
933 u32 *txf_pcnt);
934void ath9k_hw_procmibevent(struct ath_hal *ah,
935 const struct ath9k_node_stats *stats);
936void ath9k_hw_ani_setup(struct ath_hal *ah);
937void ath9k_hw_ani_attach(struct ath_hal *ah);
938void ath9k_hw_ani_detach(struct ath_hal *ah);
939
940/* Calibration */
941
942bool ath9k_hw_reset_calvalid(struct ath_hal *ah);
943void ath9k_hw_start_nfcal(struct ath_hal *ah);
944void ath9k_hw_loadnf(struct ath_hal *ah, struct ath9k_channel *chan);
945int16_t ath9k_hw_getnf(struct ath_hal *ah,
946 struct ath9k_channel *chan);
947void ath9k_init_nfcal_hist_buffer(struct ath_hal *ah);
948s16 ath9k_hw_getchan_noise(struct ath_hal *ah, struct ath9k_channel *chan);
949bool ath9k_hw_calibrate(struct ath_hal *ah, struct ath9k_channel *chan,
950 u8 rxchainmask, bool longcal,
951 bool *isCalDone);
952bool ath9k_hw_init_cal(struct ath_hal *ah,
953 struct ath9k_channel *chan);
954
955
956/* EEPROM */
957
958int ath9k_hw_set_txpower(struct ath_hal *ah,
959 struct ath9k_channel *chan,
960 u16 cfgCtl,
961 u8 twiceAntennaReduction,
962 u8 twiceMaxRegulatoryPower,
963 u8 powerLimit);
964void ath9k_hw_set_addac(struct ath_hal *ah, struct ath9k_channel *chan);
965bool ath9k_hw_set_power_per_rate_table(struct ath_hal *ah,
966 struct ath9k_channel *chan,
967 int16_t *ratesArray,
968 u16 cfgCtl,
969 u8 AntennaReduction,
970 u8 twiceMaxRegulatoryPower,
971 u8 powerLimit);
972bool ath9k_hw_set_power_cal_table(struct ath_hal *ah,
973 struct ath9k_channel *chan,
974 int16_t *pTxPowerIndexOffset);
975bool ath9k_hw_eeprom_set_board_values(struct ath_hal *ah,
976 struct ath9k_channel *chan);
977u16 ath9k_hw_get_eeprom_antenna_cfg(struct ath_hal *ah,
978 struct ath9k_channel *chan);
979u8 ath9k_hw_get_num_ant_config(struct ath_hal *ah,
980 enum ieee80211_band freq_band);
981u16 ath9k_hw_eeprom_get_spur_chan(struct ath_hal *ah, u16 i, bool is2GHz);
982int ath9k_hw_eeprom_attach(struct ath_hal *ah);
983
984/* Interrupt Handling */
985
986bool ath9k_hw_intrpend(struct ath_hal *ah);
987bool ath9k_hw_getisr(struct ath_hal *ah, enum ath9k_int *masked);
988enum ath9k_int ath9k_hw_intrget(struct ath_hal *ah);
989enum ath9k_int ath9k_hw_set_interrupts(struct ath_hal *ah, enum ath9k_int ints);
990
991/* MAC (PCU/QCU) */
992
993u32 ath9k_hw_gettxbuf(struct ath_hal *ah, u32 q);
994bool ath9k_hw_puttxbuf(struct ath_hal *ah, u32 q, u32 txdp);
995bool ath9k_hw_txstart(struct ath_hal *ah, u32 q);
996u32 ath9k_hw_numtxpending(struct ath_hal *ah, u32 q);
997bool ath9k_hw_updatetxtriglevel(struct ath_hal *ah, bool bIncTrigLevel);
998bool ath9k_hw_stoptxdma(struct ath_hal *ah, u32 q);
999bool ath9k_hw_filltxdesc(struct ath_hal *ah, struct ath_desc *ds,
1000 u32 segLen, bool firstSeg,
1001 bool lastSeg, const struct ath_desc *ds0);
1002void ath9k_hw_cleartxdesc(struct ath_hal *ah, struct ath_desc *ds);
1003int ath9k_hw_txprocdesc(struct ath_hal *ah, struct ath_desc *ds);
1004void ath9k_hw_set11n_txdesc(struct ath_hal *ah, struct ath_desc *ds,
1005 u32 pktLen, enum ath9k_pkt_type type, u32 txPower,
1006 u32 keyIx, enum ath9k_key_type keyType, u32 flags);
1007void ath9k_hw_set11n_ratescenario(struct ath_hal *ah, struct ath_desc *ds,
1008 struct ath_desc *lastds,
1009 u32 durUpdateEn, u32 rtsctsRate,
1010 u32 rtsctsDuration,
1011 struct ath9k_11n_rate_series series[],
1012 u32 nseries, u32 flags);
1013void ath9k_hw_set11n_aggr_first(struct ath_hal *ah, struct ath_desc *ds,
1014 u32 aggrLen);
1015void ath9k_hw_set11n_aggr_middle(struct ath_hal *ah, struct ath_desc *ds,
1016 u32 numDelims);
1017void ath9k_hw_set11n_aggr_last(struct ath_hal *ah, struct ath_desc *ds);
1018void ath9k_hw_clr11n_aggr(struct ath_hal *ah, struct ath_desc *ds);
1019void ath9k_hw_set11n_burstduration(struct ath_hal *ah, struct ath_desc *ds,
1020 u32 burstDuration);
1021void ath9k_hw_set11n_virtualmorefrag(struct ath_hal *ah, struct ath_desc *ds,
1022 u32 vmf);
1023void ath9k_hw_gettxintrtxqs(struct ath_hal *ah, u32 *txqs);
1024bool ath9k_hw_set_txq_props(struct ath_hal *ah, int q,
1025 const struct ath9k_tx_queue_info *qinfo);
1026bool ath9k_hw_get_txq_props(struct ath_hal *ah, int q,
1027 struct ath9k_tx_queue_info *qinfo);
1028int ath9k_hw_setuptxqueue(struct ath_hal *ah, enum ath9k_tx_queue type,
1029 const struct ath9k_tx_queue_info *qinfo);
1030bool ath9k_hw_releasetxqueue(struct ath_hal *ah, u32 q);
1031bool ath9k_hw_resettxqueue(struct ath_hal *ah, u32 q);
1032int ath9k_hw_rxprocdesc(struct ath_hal *ah, struct ath_desc *ds,
1033 u32 pa, struct ath_desc *nds, u64 tsf);
1034bool ath9k_hw_setuprxdesc(struct ath_hal *ah, struct ath_desc *ds,
1035 u32 size, u32 flags);
1036bool ath9k_hw_setrxabort(struct ath_hal *ah, bool set);
1037void ath9k_hw_putrxbuf(struct ath_hal *ah, u32 rxdp);
1038void ath9k_hw_rxena(struct ath_hal *ah);
1039void ath9k_hw_startpcureceive(struct ath_hal *ah);
1040void ath9k_hw_stoppcurecv(struct ath_hal *ah);
1041bool ath9k_hw_stopdmarecv(struct ath_hal *ah);
1042void ath9k_hw_btcoex_enable(struct ath_hal *ah);
1043 661
662#ifdef CONFIG_ATHEROS_AR71XX
663int ath_ahb_init(void);
664void ath_ahb_exit(void);
665#else
666static inline int ath_ahb_init(void) { return 0; };
667static inline void ath_ahb_exit(void) {};
1044#endif 668#endif
669
670static inline void ath9k_ps_wakeup(struct ath_softc *sc)
671{
672 if (atomic_inc_return(&sc->ps_usecount) == 1)
673 if (sc->sc_ah->power_mode != ATH9K_PM_AWAKE) {
674 sc->sc_ah->restore_mode = sc->sc_ah->power_mode;
675 ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_AWAKE);
676 }
677}
678
679static inline void ath9k_ps_restore(struct ath_softc *sc)
680{
681 if (atomic_dec_and_test(&sc->ps_usecount))
682 if (sc->hw->conf.flags & IEEE80211_CONF_PS)
683 ath9k_hw_setpower(sc->sc_ah,
684 sc->sc_ah->restore_mode);
685}
686#endif /* ATH9K_H */
diff --git a/drivers/net/wireless/ath9k/beacon.c b/drivers/net/wireless/ath9k/beacon.c
index 61d37be9717e..2e2ef3529135 100644
--- a/drivers/net/wireless/ath9k/beacon.c
+++ b/drivers/net/wireless/ath9k/beacon.c
@@ -14,7 +14,7 @@
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */ 15 */
16 16
17#include "core.h" 17#include "ath9k.h"
18 18
19/* 19/*
20 * This function will modify certain transmit queue properties depending on 20 * This function will modify certain transmit queue properties depending on
@@ -23,11 +23,11 @@
23*/ 23*/
24static int ath_beaconq_config(struct ath_softc *sc) 24static int ath_beaconq_config(struct ath_softc *sc)
25{ 25{
26 struct ath_hal *ah = sc->sc_ah; 26 struct ath_hw *ah = sc->sc_ah;
27 struct ath9k_tx_queue_info qi; 27 struct ath9k_tx_queue_info qi;
28 28
29 ath9k_hw_get_txq_props(ah, sc->beacon.beaconq, &qi); 29 ath9k_hw_get_txq_props(ah, sc->beacon.beaconq, &qi);
30 if (sc->sc_ah->ah_opmode == NL80211_IFTYPE_AP) { 30 if (sc->sc_ah->opmode == NL80211_IFTYPE_AP) {
31 /* Always burst out beacon and CAB traffic. */ 31 /* Always burst out beacon and CAB traffic. */
32 qi.tqi_aifs = 1; 32 qi.tqi_aifs = 1;
33 qi.tqi_cwmin = 0; 33 qi.tqi_cwmin = 0;
@@ -63,10 +63,10 @@ static void ath_bstuck_process(struct ath_softc *sc)
63 * Beacons are always sent out at the lowest rate, and are not retried. 63 * Beacons are always sent out at the lowest rate, and are not retried.
64*/ 64*/
65static void ath_beacon_setup(struct ath_softc *sc, 65static void ath_beacon_setup(struct ath_softc *sc,
66 struct ath_vap *avp, struct ath_buf *bf) 66 struct ath_vif *avp, struct ath_buf *bf)
67{ 67{
68 struct sk_buff *skb = (struct sk_buff *)bf->bf_mpdu; 68 struct sk_buff *skb = (struct sk_buff *)bf->bf_mpdu;
69 struct ath_hal *ah = sc->sc_ah; 69 struct ath_hw *ah = sc->sc_ah;
70 struct ath_desc *ds; 70 struct ath_desc *ds;
71 struct ath9k_11n_rate_series series[4]; 71 struct ath9k_11n_rate_series series[4];
72 struct ath_rate_table *rt; 72 struct ath_rate_table *rt;
@@ -82,8 +82,8 @@ static void ath_beacon_setup(struct ath_softc *sc,
82 82
83 flags = ATH9K_TXDESC_NOACK; 83 flags = ATH9K_TXDESC_NOACK;
84 84
85 if (sc->sc_ah->ah_opmode == NL80211_IFTYPE_ADHOC && 85 if (sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC &&
86 (ah->ah_caps.hw_caps & ATH9K_HW_CAP_VEOL)) { 86 (ah->caps.hw_caps & ATH9K_HW_CAP_VEOL)) {
87 ds->ds_link = bf->bf_daddr; /* self-linked */ 87 ds->ds_link = bf->bf_daddr; /* self-linked */
88 flags |= ATH9K_TXDESC_VEOL; 88 flags |= ATH9K_TXDESC_VEOL;
89 /* Let hardware handle antenna switching. */ 89 /* Let hardware handle antenna switching. */
@@ -96,7 +96,7 @@ static void ath_beacon_setup(struct ath_softc *sc,
96 * SWBA's 96 * SWBA's
97 * XXX assumes two antenna 97 * XXX assumes two antenna
98 */ 98 */
99 antenna = ((sc->beacon.ast_be_xmit / sc->sc_nbcnvaps) & 1 ? 2 : 1); 99 antenna = ((sc->beacon.ast_be_xmit / sc->nbcnvifs) & 1 ? 2 : 1);
100 } 100 }
101 101
102 ds->ds_data = bf->bf_buf_addr; 102 ds->ds_data = bf->bf_buf_addr;
@@ -132,24 +132,24 @@ static void ath_beacon_setup(struct ath_softc *sc,
132 memset(series, 0, sizeof(struct ath9k_11n_rate_series) * 4); 132 memset(series, 0, sizeof(struct ath9k_11n_rate_series) * 4);
133 series[0].Tries = 1; 133 series[0].Tries = 1;
134 series[0].Rate = rate; 134 series[0].Rate = rate;
135 series[0].ChSel = sc->sc_tx_chainmask; 135 series[0].ChSel = sc->tx_chainmask;
136 series[0].RateFlags = (ctsrate) ? ATH9K_RATESERIES_RTS_CTS : 0; 136 series[0].RateFlags = (ctsrate) ? ATH9K_RATESERIES_RTS_CTS : 0;
137 ath9k_hw_set11n_ratescenario(ah, ds, ds, 0, 137 ath9k_hw_set11n_ratescenario(ah, ds, ds, 0,
138 ctsrate, ctsduration, series, 4, 0); 138 ctsrate, ctsduration, series, 4, 0);
139} 139}
140 140
141/* Generate beacon frame and queue cab data for a vap */ 141/* Generate beacon frame and queue cab data for a VIF */
142static struct ath_buf *ath_beacon_generate(struct ath_softc *sc, int if_id) 142static struct ath_buf *ath_beacon_generate(struct ath_softc *sc, int if_id)
143{ 143{
144 struct ath_buf *bf; 144 struct ath_buf *bf;
145 struct ath_vap *avp; 145 struct ath_vif *avp;
146 struct sk_buff *skb; 146 struct sk_buff *skb;
147 struct ath_txq *cabq; 147 struct ath_txq *cabq;
148 struct ieee80211_vif *vif; 148 struct ieee80211_vif *vif;
149 struct ieee80211_tx_info *info; 149 struct ieee80211_tx_info *info;
150 int cabq_depth; 150 int cabq_depth;
151 151
152 vif = sc->sc_vaps[if_id]; 152 vif = sc->vifs[if_id];
153 ASSERT(vif); 153 ASSERT(vif);
154 154
155 avp = (void *)vif->drv_priv; 155 avp = (void *)vif->drv_priv;
@@ -204,10 +204,10 @@ static struct ath_buf *ath_beacon_generate(struct ath_softc *sc, int if_id)
204 /* 204 /*
205 * if the CABQ traffic from previous DTIM is pending and the current 205 * if the CABQ traffic from previous DTIM is pending and the current
206 * beacon is also a DTIM. 206 * beacon is also a DTIM.
207 * 1) if there is only one vap let the cab traffic continue. 207 * 1) if there is only one vif let the cab traffic continue.
208 * 2) if there are more than one vap and we are using staggered 208 * 2) if there are more than one vif and we are using staggered
209 * beacons, then drain the cabq by dropping all the frames in 209 * beacons, then drain the cabq by dropping all the frames in
210 * the cabq so that the current vaps cab traffic can be scheduled. 210 * the cabq so that the current vifs cab traffic can be scheduled.
211 */ 211 */
212 spin_lock_bh(&cabq->axq_lock); 212 spin_lock_bh(&cabq->axq_lock);
213 cabq_depth = cabq->axq_depth; 213 cabq_depth = cabq->axq_depth;
@@ -219,7 +219,7 @@ static struct ath_buf *ath_beacon_generate(struct ath_softc *sc, int if_id)
219 * the lock again which is a common function and that 219 * the lock again which is a common function and that
220 * acquires txq lock inside. 220 * acquires txq lock inside.
221 */ 221 */
222 if (sc->sc_nvaps > 1) { 222 if (sc->nvifs > 1) {
223 ath_draintxq(sc, cabq, false); 223 ath_draintxq(sc, cabq, false);
224 DPRINTF(sc, ATH_DBG_BEACON, 224 DPRINTF(sc, ATH_DBG_BEACON,
225 "flush previous cabq traffic\n"); 225 "flush previous cabq traffic\n");
@@ -248,12 +248,12 @@ static struct ath_buf *ath_beacon_generate(struct ath_softc *sc, int if_id)
248static void ath_beacon_start_adhoc(struct ath_softc *sc, int if_id) 248static void ath_beacon_start_adhoc(struct ath_softc *sc, int if_id)
249{ 249{
250 struct ieee80211_vif *vif; 250 struct ieee80211_vif *vif;
251 struct ath_hal *ah = sc->sc_ah; 251 struct ath_hw *ah = sc->sc_ah;
252 struct ath_buf *bf; 252 struct ath_buf *bf;
253 struct ath_vap *avp; 253 struct ath_vif *avp;
254 struct sk_buff *skb; 254 struct sk_buff *skb;
255 255
256 vif = sc->sc_vaps[if_id]; 256 vif = sc->vifs[if_id];
257 ASSERT(vif); 257 ASSERT(vif);
258 258
259 avp = (void *)vif->drv_priv; 259 avp = (void *)vif->drv_priv;
@@ -276,7 +276,7 @@ static void ath_beacon_start_adhoc(struct ath_softc *sc, int if_id)
276 sc->beacon.beaconq, ito64(bf->bf_daddr), bf->bf_desc); 276 sc->beacon.beaconq, ito64(bf->bf_daddr), bf->bf_desc);
277} 277}
278 278
279int ath_beaconq_setup(struct ath_hal *ah) 279int ath_beaconq_setup(struct ath_hw *ah)
280{ 280{
281 struct ath9k_tx_queue_info qi; 281 struct ath9k_tx_queue_info qi;
282 282
@@ -291,13 +291,13 @@ int ath_beaconq_setup(struct ath_hal *ah)
291int ath_beacon_alloc(struct ath_softc *sc, int if_id) 291int ath_beacon_alloc(struct ath_softc *sc, int if_id)
292{ 292{
293 struct ieee80211_vif *vif; 293 struct ieee80211_vif *vif;
294 struct ath_vap *avp; 294 struct ath_vif *avp;
295 struct ieee80211_hdr *hdr; 295 struct ieee80211_hdr *hdr;
296 struct ath_buf *bf; 296 struct ath_buf *bf;
297 struct sk_buff *skb; 297 struct sk_buff *skb;
298 __le64 tstamp; 298 __le64 tstamp;
299 299
300 vif = sc->sc_vaps[if_id]; 300 vif = sc->vifs[if_id];
301 ASSERT(vif); 301 ASSERT(vif);
302 302
303 avp = (void *)vif->drv_priv; 303 avp = (void *)vif->drv_priv;
@@ -310,11 +310,11 @@ int ath_beacon_alloc(struct ath_softc *sc, int if_id)
310 struct ath_buf, list); 310 struct ath_buf, list);
311 list_del(&avp->av_bcbuf->list); 311 list_del(&avp->av_bcbuf->list);
312 312
313 if (sc->sc_ah->ah_opmode == NL80211_IFTYPE_AP || 313 if (sc->sc_ah->opmode == NL80211_IFTYPE_AP ||
314 !(sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_VEOL)) { 314 !(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_VEOL)) {
315 int slot; 315 int slot;
316 /* 316 /*
317 * Assign the vap to a beacon xmit slot. As 317 * Assign the vif to a beacon xmit slot. As
318 * above, this cannot fail to find one. 318 * above, this cannot fail to find one.
319 */ 319 */
320 avp->av_bslot = 0; 320 avp->av_bslot = 0;
@@ -335,7 +335,7 @@ int ath_beacon_alloc(struct ath_softc *sc, int if_id)
335 } 335 }
336 BUG_ON(sc->beacon.bslot[avp->av_bslot] != ATH_IF_ID_ANY); 336 BUG_ON(sc->beacon.bslot[avp->av_bslot] != ATH_IF_ID_ANY);
337 sc->beacon.bslot[avp->av_bslot] = if_id; 337 sc->beacon.bslot[avp->av_bslot] = if_id;
338 sc->sc_nbcnvaps++; 338 sc->nbcnvifs++;
339 } 339 }
340 } 340 }
341 341
@@ -384,8 +384,8 @@ int ath_beacon_alloc(struct ath_softc *sc, int if_id)
384 * timestamp then convert to TSF units and handle 384 * timestamp then convert to TSF units and handle
385 * byte swapping before writing it in the frame. 385 * byte swapping before writing it in the frame.
386 * The hardware will then add this each time a beacon 386 * The hardware will then add this each time a beacon
387 * frame is sent. Note that we align vap's 1..N 387 * frame is sent. Note that we align vif's 1..N
388 * and leave vap 0 untouched. This means vap 0 388 * and leave vif 0 untouched. This means vap 0
389 * has a timestamp in one beacon interval while the 389 * has a timestamp in one beacon interval while the
390 * others get a timestamp aligned to the next interval. 390 * others get a timestamp aligned to the next interval.
391 */ 391 */
@@ -416,14 +416,14 @@ int ath_beacon_alloc(struct ath_softc *sc, int if_id)
416 return 0; 416 return 0;
417} 417}
418 418
419void ath_beacon_return(struct ath_softc *sc, struct ath_vap *avp) 419void ath_beacon_return(struct ath_softc *sc, struct ath_vif *avp)
420{ 420{
421 if (avp->av_bcbuf != NULL) { 421 if (avp->av_bcbuf != NULL) {
422 struct ath_buf *bf; 422 struct ath_buf *bf;
423 423
424 if (avp->av_bslot != -1) { 424 if (avp->av_bslot != -1) {
425 sc->beacon.bslot[avp->av_bslot] = ATH_IF_ID_ANY; 425 sc->beacon.bslot[avp->av_bslot] = ATH_IF_ID_ANY;
426 sc->sc_nbcnvaps--; 426 sc->nbcnvifs--;
427 } 427 }
428 428
429 bf = avp->av_bcbuf; 429 bf = avp->av_bcbuf;
@@ -444,7 +444,7 @@ void ath_beacon_return(struct ath_softc *sc, struct ath_vap *avp)
444void ath9k_beacon_tasklet(unsigned long data) 444void ath9k_beacon_tasklet(unsigned long data)
445{ 445{
446 struct ath_softc *sc = (struct ath_softc *)data; 446 struct ath_softc *sc = (struct ath_softc *)data;
447 struct ath_hal *ah = sc->sc_ah; 447 struct ath_hw *ah = sc->sc_ah;
448 struct ath_buf *bf = NULL; 448 struct ath_buf *bf = NULL;
449 int slot, if_id; 449 int slot, if_id;
450 u32 bfaddr; 450 u32 bfaddr;
@@ -597,7 +597,7 @@ void ath9k_beacon_tasklet(unsigned long data)
597 ath9k_hw_puttxbuf(ah, sc->beacon.beaconq, bfaddr); 597 ath9k_hw_puttxbuf(ah, sc->beacon.beaconq, bfaddr);
598 ath9k_hw_txstart(ah, sc->beacon.beaconq); 598 ath9k_hw_txstart(ah, sc->beacon.beaconq);
599 599
600 sc->beacon.ast_be_xmit += bc; /* XXX per-vap? */ 600 sc->beacon.ast_be_xmit += bc; /* XXX per-vif? */
601 } 601 }
602} 602}
603 603
@@ -619,19 +619,19 @@ void ath9k_beacon_tasklet(unsigned long data)
619void ath_beacon_config(struct ath_softc *sc, int if_id) 619void ath_beacon_config(struct ath_softc *sc, int if_id)
620{ 620{
621 struct ieee80211_vif *vif; 621 struct ieee80211_vif *vif;
622 struct ath_hal *ah = sc->sc_ah; 622 struct ath_hw *ah = sc->sc_ah;
623 struct ath_beacon_config conf; 623 struct ath_beacon_config conf;
624 struct ath_vap *avp; 624 struct ath_vif *avp;
625 enum nl80211_iftype opmode; 625 enum nl80211_iftype opmode;
626 u32 nexttbtt, intval; 626 u32 nexttbtt, intval;
627 627
628 if (if_id != ATH_IF_ID_ANY) { 628 if (if_id != ATH_IF_ID_ANY) {
629 vif = sc->sc_vaps[if_id]; 629 vif = sc->vifs[if_id];
630 ASSERT(vif); 630 ASSERT(vif);
631 avp = (void *)vif->drv_priv; 631 avp = (void *)vif->drv_priv;
632 opmode = avp->av_opmode; 632 opmode = avp->av_opmode;
633 } else { 633 } else {
634 opmode = sc->sc_ah->ah_opmode; 634 opmode = sc->sc_ah->opmode;
635 } 635 }
636 636
637 memset(&conf, 0, sizeof(struct ath_beacon_config)); 637 memset(&conf, 0, sizeof(struct ath_beacon_config));
@@ -647,7 +647,7 @@ void ath_beacon_config(struct ath_softc *sc, int if_id)
647 nexttbtt = TSF_TO_TU(sc->beacon.bc_tstamp >> 32, sc->beacon.bc_tstamp); 647 nexttbtt = TSF_TO_TU(sc->beacon.bc_tstamp >> 32, sc->beacon.bc_tstamp);
648 648
649 /* XXX conditionalize multi-bss support? */ 649 /* XXX conditionalize multi-bss support? */
650 if (sc->sc_ah->ah_opmode == NL80211_IFTYPE_AP) { 650 if (sc->sc_ah->opmode == NL80211_IFTYPE_AP) {
651 /* 651 /*
652 * For multi-bss ap support beacons are either staggered 652 * For multi-bss ap support beacons are either staggered
653 * evenly over N slots or burst together. For the former 653 * evenly over N slots or burst together. For the former
@@ -670,7 +670,7 @@ void ath_beacon_config(struct ath_softc *sc, int if_id)
670 nexttbtt, intval, conf.beacon_interval); 670 nexttbtt, intval, conf.beacon_interval);
671 671
672 /* Check for NL80211_IFTYPE_AP and sc_nostabeacons for WDS client */ 672 /* Check for NL80211_IFTYPE_AP and sc_nostabeacons for WDS client */
673 if (sc->sc_ah->ah_opmode == NL80211_IFTYPE_STATION) { 673 if (sc->sc_ah->opmode == NL80211_IFTYPE_STATION) {
674 struct ath9k_beacon_state bs; 674 struct ath9k_beacon_state bs;
675 u64 tsf; 675 u64 tsf;
676 u32 tsftu; 676 u32 tsftu;
@@ -781,15 +781,15 @@ void ath_beacon_config(struct ath_softc *sc, int if_id)
781 781
782 ath9k_hw_set_interrupts(ah, 0); 782 ath9k_hw_set_interrupts(ah, 0);
783 ath9k_hw_set_sta_beacon_timers(ah, &bs); 783 ath9k_hw_set_sta_beacon_timers(ah, &bs);
784 sc->sc_imask |= ATH9K_INT_BMISS; 784 sc->imask |= ATH9K_INT_BMISS;
785 ath9k_hw_set_interrupts(ah, sc->sc_imask); 785 ath9k_hw_set_interrupts(ah, sc->imask);
786 } else { 786 } else {
787 u64 tsf; 787 u64 tsf;
788 u32 tsftu; 788 u32 tsftu;
789 ath9k_hw_set_interrupts(ah, 0); 789 ath9k_hw_set_interrupts(ah, 0);
790 if (nexttbtt == intval) 790 if (nexttbtt == intval)
791 intval |= ATH9K_BEACON_RESET_TSF; 791 intval |= ATH9K_BEACON_RESET_TSF;
792 if (sc->sc_ah->ah_opmode == NL80211_IFTYPE_ADHOC) { 792 if (sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC) {
793 /* 793 /*
794 * Pull nexttbtt forward to reflect the current 794 * Pull nexttbtt forward to reflect the current
795 * TSF 795 * TSF
@@ -818,27 +818,27 @@ void ath_beacon_config(struct ath_softc *sc, int if_id)
818 * deal with things. 818 * deal with things.
819 */ 819 */
820 intval |= ATH9K_BEACON_ENA; 820 intval |= ATH9K_BEACON_ENA;
821 if (!(ah->ah_caps.hw_caps & ATH9K_HW_CAP_VEOL)) 821 if (!(ah->caps.hw_caps & ATH9K_HW_CAP_VEOL))
822 sc->sc_imask |= ATH9K_INT_SWBA; 822 sc->imask |= ATH9K_INT_SWBA;
823 ath_beaconq_config(sc); 823 ath_beaconq_config(sc);
824 } else if (sc->sc_ah->ah_opmode == NL80211_IFTYPE_AP) { 824 } else if (sc->sc_ah->opmode == NL80211_IFTYPE_AP) {
825 /* 825 /*
826 * In AP mode we enable the beacon timers and 826 * In AP mode we enable the beacon timers and
827 * SWBA interrupts to prepare beacon frames. 827 * SWBA interrupts to prepare beacon frames.
828 */ 828 */
829 intval |= ATH9K_BEACON_ENA; 829 intval |= ATH9K_BEACON_ENA;
830 sc->sc_imask |= ATH9K_INT_SWBA; /* beacon prepare */ 830 sc->imask |= ATH9K_INT_SWBA; /* beacon prepare */
831 ath_beaconq_config(sc); 831 ath_beaconq_config(sc);
832 } 832 }
833 ath9k_hw_beaconinit(ah, nexttbtt, intval); 833 ath9k_hw_beaconinit(ah, nexttbtt, intval);
834 sc->beacon.bmisscnt = 0; 834 sc->beacon.bmisscnt = 0;
835 ath9k_hw_set_interrupts(ah, sc->sc_imask); 835 ath9k_hw_set_interrupts(ah, sc->imask);
836 /* 836 /*
837 * When using a self-linked beacon descriptor in 837 * When using a self-linked beacon descriptor in
838 * ibss mode load it once here. 838 * ibss mode load it once here.
839 */ 839 */
840 if (sc->sc_ah->ah_opmode == NL80211_IFTYPE_ADHOC && 840 if (sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC &&
841 (ah->ah_caps.hw_caps & ATH9K_HW_CAP_VEOL)) 841 (ah->caps.hw_caps & ATH9K_HW_CAP_VEOL))
842 ath_beacon_start_adhoc(sc, 0); 842 ath_beacon_start_adhoc(sc, 0);
843 } 843 }
844} 844}
diff --git a/drivers/net/wireless/ath9k/calib.c b/drivers/net/wireless/ath9k/calib.c
index 69ff01ce968b..1fc3a08e85c6 100644
--- a/drivers/net/wireless/ath9k/calib.c
+++ b/drivers/net/wireless/ath9k/calib.c
@@ -14,10 +14,7 @@
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */ 15 */
16 16
17#include "core.h" 17#include "ath9k.h"
18#include "hw.h"
19#include "reg.h"
20#include "phy.h"
21 18
22/* We can tune this as we go by monitoring really low values */ 19/* We can tune this as we go by monitoring really low values */
23#define ATH9K_NF_TOO_LOW -60 20#define ATH9K_NF_TOO_LOW -60
@@ -26,7 +23,7 @@
26 * is incorrect and we should use the static NF value. Later we can try to 23 * is incorrect and we should use the static NF value. Later we can try to
27 * find out why they are reporting these values */ 24 * find out why they are reporting these values */
28 25
29static bool ath9k_hw_nf_in_range(struct ath_hal *ah, s16 nf) 26static bool ath9k_hw_nf_in_range(struct ath_hw *ah, s16 nf)
30{ 27{
31 if (nf > ATH9K_NF_TOO_LOW) { 28 if (nf > ATH9K_NF_TOO_LOW) {
32 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, 29 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
@@ -89,7 +86,7 @@ static void ath9k_hw_update_nfcal_hist_buffer(struct ath9k_nfcal_hist *h,
89 return; 86 return;
90} 87}
91 88
92static void ath9k_hw_do_getnf(struct ath_hal *ah, 89static void ath9k_hw_do_getnf(struct ath_hw *ah,
93 int16_t nfarray[NUM_NF_READINGS]) 90 int16_t nfarray[NUM_NF_READINGS])
94{ 91{
95 int16_t nf; 92 int16_t nf;
@@ -169,16 +166,16 @@ static void ath9k_hw_do_getnf(struct ath_hal *ah,
169 } 166 }
170} 167}
171 168
172static bool getNoiseFloorThresh(struct ath_hal *ah, 169static bool getNoiseFloorThresh(struct ath_hw *ah,
173 enum ieee80211_band band, 170 enum ieee80211_band band,
174 int16_t *nft) 171 int16_t *nft)
175{ 172{
176 switch (band) { 173 switch (band) {
177 case IEEE80211_BAND_5GHZ: 174 case IEEE80211_BAND_5GHZ:
178 *nft = (int8_t)ath9k_hw_get_eeprom(ah, EEP_NFTHRESH_5); 175 *nft = (int8_t)ah->eep_ops->get_eeprom(ah, EEP_NFTHRESH_5);
179 break; 176 break;
180 case IEEE80211_BAND_2GHZ: 177 case IEEE80211_BAND_2GHZ:
181 *nft = (int8_t)ath9k_hw_get_eeprom(ah, EEP_NFTHRESH_2); 178 *nft = (int8_t)ah->eep_ops->get_eeprom(ah, EEP_NFTHRESH_2);
182 break; 179 break;
183 default: 180 default:
184 BUG_ON(1); 181 BUG_ON(1);
@@ -188,7 +185,7 @@ static bool getNoiseFloorThresh(struct ath_hal *ah,
188 return true; 185 return true;
189} 186}
190 187
191static void ath9k_hw_setup_calibration(struct ath_hal *ah, 188static void ath9k_hw_setup_calibration(struct ath_hw *ah,
192 struct hal_cal_list *currCal) 189 struct hal_cal_list *currCal)
193{ 190{
194 REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4(0), 191 REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4(0),
@@ -222,10 +219,9 @@ static void ath9k_hw_setup_calibration(struct ath_hal *ah,
222 AR_PHY_TIMING_CTRL4_DO_CAL); 219 AR_PHY_TIMING_CTRL4_DO_CAL);
223} 220}
224 221
225static void ath9k_hw_reset_calibration(struct ath_hal *ah, 222static void ath9k_hw_reset_calibration(struct ath_hw *ah,
226 struct hal_cal_list *currCal) 223 struct hal_cal_list *currCal)
227{ 224{
228 struct ath_hal_5416 *ahp = AH5416(ah);
229 int i; 225 int i;
230 226
231 ath9k_hw_setup_calibration(ah, currCal); 227 ath9k_hw_setup_calibration(ah, currCal);
@@ -233,23 +229,21 @@ static void ath9k_hw_reset_calibration(struct ath_hal *ah,
233 currCal->calState = CAL_RUNNING; 229 currCal->calState = CAL_RUNNING;
234 230
235 for (i = 0; i < AR5416_MAX_CHAINS; i++) { 231 for (i = 0; i < AR5416_MAX_CHAINS; i++) {
236 ahp->ah_Meas0.sign[i] = 0; 232 ah->meas0.sign[i] = 0;
237 ahp->ah_Meas1.sign[i] = 0; 233 ah->meas1.sign[i] = 0;
238 ahp->ah_Meas2.sign[i] = 0; 234 ah->meas2.sign[i] = 0;
239 ahp->ah_Meas3.sign[i] = 0; 235 ah->meas3.sign[i] = 0;
240 } 236 }
241 237
242 ahp->ah_CalSamples = 0; 238 ah->cal_samples = 0;
243} 239}
244 240
245static void ath9k_hw_per_calibration(struct ath_hal *ah, 241static void ath9k_hw_per_calibration(struct ath_hw *ah,
246 struct ath9k_channel *ichan, 242 struct ath9k_channel *ichan,
247 u8 rxchainmask, 243 u8 rxchainmask,
248 struct hal_cal_list *currCal, 244 struct hal_cal_list *currCal,
249 bool *isCalDone) 245 bool *isCalDone)
250{ 246{
251 struct ath_hal_5416 *ahp = AH5416(ah);
252
253 *isCalDone = false; 247 *isCalDone = false;
254 248
255 if (currCal->calState == CAL_RUNNING) { 249 if (currCal->calState == CAL_RUNNING) {
@@ -257,9 +251,9 @@ static void ath9k_hw_per_calibration(struct ath_hal *ah,
257 AR_PHY_TIMING_CTRL4_DO_CAL)) { 251 AR_PHY_TIMING_CTRL4_DO_CAL)) {
258 252
259 currCal->calData->calCollect(ah); 253 currCal->calData->calCollect(ah);
260 ahp->ah_CalSamples++; 254 ah->cal_samples++;
261 255
262 if (ahp->ah_CalSamples >= currCal->calData->calNumSamples) { 256 if (ah->cal_samples >= currCal->calData->calNumSamples) {
263 int i, numChains = 0; 257 int i, numChains = 0;
264 for (i = 0; i < AR5416_MAX_CHAINS; i++) { 258 for (i = 0; i < AR5416_MAX_CHAINS; i++) {
265 if (rxchainmask & (1 << i)) 259 if (rxchainmask & (1 << i))
@@ -280,13 +274,12 @@ static void ath9k_hw_per_calibration(struct ath_hal *ah,
280} 274}
281 275
282/* Assumes you are talking about the currently configured channel */ 276/* Assumes you are talking about the currently configured channel */
283static bool ath9k_hw_iscal_supported(struct ath_hal *ah, 277static bool ath9k_hw_iscal_supported(struct ath_hw *ah,
284 enum hal_cal_types calType) 278 enum hal_cal_types calType)
285{ 279{
286 struct ath_hal_5416 *ahp = AH5416(ah);
287 struct ieee80211_conf *conf = &ah->ah_sc->hw->conf; 280 struct ieee80211_conf *conf = &ah->ah_sc->hw->conf;
288 281
289 switch (calType & ahp->ah_suppCals) { 282 switch (calType & ah->supp_cals) {
290 case IQ_MISMATCH_CAL: /* Both 2 GHz and 5 GHz support OFDM */ 283 case IQ_MISMATCH_CAL: /* Both 2 GHz and 5 GHz support OFDM */
291 return true; 284 return true;
292 case ADC_GAIN_CAL: 285 case ADC_GAIN_CAL:
@@ -299,90 +292,86 @@ static bool ath9k_hw_iscal_supported(struct ath_hal *ah,
299 return false; 292 return false;
300} 293}
301 294
302static void ath9k_hw_iqcal_collect(struct ath_hal *ah) 295static void ath9k_hw_iqcal_collect(struct ath_hw *ah)
303{ 296{
304 struct ath_hal_5416 *ahp = AH5416(ah);
305 int i; 297 int i;
306 298
307 for (i = 0; i < AR5416_MAX_CHAINS; i++) { 299 for (i = 0; i < AR5416_MAX_CHAINS; i++) {
308 ahp->ah_totalPowerMeasI[i] += 300 ah->totalPowerMeasI[i] +=
309 REG_READ(ah, AR_PHY_CAL_MEAS_0(i)); 301 REG_READ(ah, AR_PHY_CAL_MEAS_0(i));
310 ahp->ah_totalPowerMeasQ[i] += 302 ah->totalPowerMeasQ[i] +=
311 REG_READ(ah, AR_PHY_CAL_MEAS_1(i)); 303 REG_READ(ah, AR_PHY_CAL_MEAS_1(i));
312 ahp->ah_totalIqCorrMeas[i] += 304 ah->totalIqCorrMeas[i] +=
313 (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_2(i)); 305 (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_2(i));
314 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, 306 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
315 "%d: Chn %d pmi=0x%08x;pmq=0x%08x;iqcm=0x%08x;\n", 307 "%d: Chn %d pmi=0x%08x;pmq=0x%08x;iqcm=0x%08x;\n",
316 ahp->ah_CalSamples, i, ahp->ah_totalPowerMeasI[i], 308 ah->cal_samples, i, ah->totalPowerMeasI[i],
317 ahp->ah_totalPowerMeasQ[i], 309 ah->totalPowerMeasQ[i],
318 ahp->ah_totalIqCorrMeas[i]); 310 ah->totalIqCorrMeas[i]);
319 } 311 }
320} 312}
321 313
322static void ath9k_hw_adc_gaincal_collect(struct ath_hal *ah) 314static void ath9k_hw_adc_gaincal_collect(struct ath_hw *ah)
323{ 315{
324 struct ath_hal_5416 *ahp = AH5416(ah);
325 int i; 316 int i;
326 317
327 for (i = 0; i < AR5416_MAX_CHAINS; i++) { 318 for (i = 0; i < AR5416_MAX_CHAINS; i++) {
328 ahp->ah_totalAdcIOddPhase[i] += 319 ah->totalAdcIOddPhase[i] +=
329 REG_READ(ah, AR_PHY_CAL_MEAS_0(i)); 320 REG_READ(ah, AR_PHY_CAL_MEAS_0(i));
330 ahp->ah_totalAdcIEvenPhase[i] += 321 ah->totalAdcIEvenPhase[i] +=
331 REG_READ(ah, AR_PHY_CAL_MEAS_1(i)); 322 REG_READ(ah, AR_PHY_CAL_MEAS_1(i));
332 ahp->ah_totalAdcQOddPhase[i] += 323 ah->totalAdcQOddPhase[i] +=
333 REG_READ(ah, AR_PHY_CAL_MEAS_2(i)); 324 REG_READ(ah, AR_PHY_CAL_MEAS_2(i));
334 ahp->ah_totalAdcQEvenPhase[i] += 325 ah->totalAdcQEvenPhase[i] +=
335 REG_READ(ah, AR_PHY_CAL_MEAS_3(i)); 326 REG_READ(ah, AR_PHY_CAL_MEAS_3(i));
336 327
337 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, 328 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
338 "%d: Chn %d oddi=0x%08x; eveni=0x%08x; " 329 "%d: Chn %d oddi=0x%08x; eveni=0x%08x; "
339 "oddq=0x%08x; evenq=0x%08x;\n", 330 "oddq=0x%08x; evenq=0x%08x;\n",
340 ahp->ah_CalSamples, i, 331 ah->cal_samples, i,
341 ahp->ah_totalAdcIOddPhase[i], 332 ah->totalAdcIOddPhase[i],
342 ahp->ah_totalAdcIEvenPhase[i], 333 ah->totalAdcIEvenPhase[i],
343 ahp->ah_totalAdcQOddPhase[i], 334 ah->totalAdcQOddPhase[i],
344 ahp->ah_totalAdcQEvenPhase[i]); 335 ah->totalAdcQEvenPhase[i]);
345 } 336 }
346} 337}
347 338
348static void ath9k_hw_adc_dccal_collect(struct ath_hal *ah) 339static void ath9k_hw_adc_dccal_collect(struct ath_hw *ah)
349{ 340{
350 struct ath_hal_5416 *ahp = AH5416(ah);
351 int i; 341 int i;
352 342
353 for (i = 0; i < AR5416_MAX_CHAINS; i++) { 343 for (i = 0; i < AR5416_MAX_CHAINS; i++) {
354 ahp->ah_totalAdcDcOffsetIOddPhase[i] += 344 ah->totalAdcDcOffsetIOddPhase[i] +=
355 (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_0(i)); 345 (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_0(i));
356 ahp->ah_totalAdcDcOffsetIEvenPhase[i] += 346 ah->totalAdcDcOffsetIEvenPhase[i] +=
357 (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_1(i)); 347 (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_1(i));
358 ahp->ah_totalAdcDcOffsetQOddPhase[i] += 348 ah->totalAdcDcOffsetQOddPhase[i] +=
359 (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_2(i)); 349 (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_2(i));
360 ahp->ah_totalAdcDcOffsetQEvenPhase[i] += 350 ah->totalAdcDcOffsetQEvenPhase[i] +=
361 (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_3(i)); 351 (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_3(i));
362 352
363 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, 353 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
364 "%d: Chn %d oddi=0x%08x; eveni=0x%08x; " 354 "%d: Chn %d oddi=0x%08x; eveni=0x%08x; "
365 "oddq=0x%08x; evenq=0x%08x;\n", 355 "oddq=0x%08x; evenq=0x%08x;\n",
366 ahp->ah_CalSamples, i, 356 ah->cal_samples, i,
367 ahp->ah_totalAdcDcOffsetIOddPhase[i], 357 ah->totalAdcDcOffsetIOddPhase[i],
368 ahp->ah_totalAdcDcOffsetIEvenPhase[i], 358 ah->totalAdcDcOffsetIEvenPhase[i],
369 ahp->ah_totalAdcDcOffsetQOddPhase[i], 359 ah->totalAdcDcOffsetQOddPhase[i],
370 ahp->ah_totalAdcDcOffsetQEvenPhase[i]); 360 ah->totalAdcDcOffsetQEvenPhase[i]);
371 } 361 }
372} 362}
373 363
374static void ath9k_hw_iqcalibrate(struct ath_hal *ah, u8 numChains) 364static void ath9k_hw_iqcalibrate(struct ath_hw *ah, u8 numChains)
375{ 365{
376 struct ath_hal_5416 *ahp = AH5416(ah);
377 u32 powerMeasQ, powerMeasI, iqCorrMeas; 366 u32 powerMeasQ, powerMeasI, iqCorrMeas;
378 u32 qCoffDenom, iCoffDenom; 367 u32 qCoffDenom, iCoffDenom;
379 int32_t qCoff, iCoff; 368 int32_t qCoff, iCoff;
380 int iqCorrNeg, i; 369 int iqCorrNeg, i;
381 370
382 for (i = 0; i < numChains; i++) { 371 for (i = 0; i < numChains; i++) {
383 powerMeasI = ahp->ah_totalPowerMeasI[i]; 372 powerMeasI = ah->totalPowerMeasI[i];
384 powerMeasQ = ahp->ah_totalPowerMeasQ[i]; 373 powerMeasQ = ah->totalPowerMeasQ[i];
385 iqCorrMeas = ahp->ah_totalIqCorrMeas[i]; 374 iqCorrMeas = ah->totalIqCorrMeas[i];
386 375
387 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, 376 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
388 "Starting IQ Cal and Correction for Chain %d\n", 377 "Starting IQ Cal and Correction for Chain %d\n",
@@ -390,7 +379,7 @@ static void ath9k_hw_iqcalibrate(struct ath_hal *ah, u8 numChains)
390 379
391 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, 380 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
392 "Orignal: Chn %diq_corr_meas = 0x%08x\n", 381 "Orignal: Chn %diq_corr_meas = 0x%08x\n",
393 i, ahp->ah_totalIqCorrMeas[i]); 382 i, ah->totalIqCorrMeas[i]);
394 383
395 iqCorrNeg = 0; 384 iqCorrNeg = 0;
396 385
@@ -448,17 +437,16 @@ static void ath9k_hw_iqcalibrate(struct ath_hal *ah, u8 numChains)
448 AR_PHY_TIMING_CTRL4_IQCORR_ENABLE); 437 AR_PHY_TIMING_CTRL4_IQCORR_ENABLE);
449} 438}
450 439
451static void ath9k_hw_adc_gaincal_calibrate(struct ath_hal *ah, u8 numChains) 440static void ath9k_hw_adc_gaincal_calibrate(struct ath_hw *ah, u8 numChains)
452{ 441{
453 struct ath_hal_5416 *ahp = AH5416(ah);
454 u32 iOddMeasOffset, iEvenMeasOffset, qOddMeasOffset, qEvenMeasOffset; 442 u32 iOddMeasOffset, iEvenMeasOffset, qOddMeasOffset, qEvenMeasOffset;
455 u32 qGainMismatch, iGainMismatch, val, i; 443 u32 qGainMismatch, iGainMismatch, val, i;
456 444
457 for (i = 0; i < numChains; i++) { 445 for (i = 0; i < numChains; i++) {
458 iOddMeasOffset = ahp->ah_totalAdcIOddPhase[i]; 446 iOddMeasOffset = ah->totalAdcIOddPhase[i];
459 iEvenMeasOffset = ahp->ah_totalAdcIEvenPhase[i]; 447 iEvenMeasOffset = ah->totalAdcIEvenPhase[i];
460 qOddMeasOffset = ahp->ah_totalAdcQOddPhase[i]; 448 qOddMeasOffset = ah->totalAdcQOddPhase[i];
461 qEvenMeasOffset = ahp->ah_totalAdcQEvenPhase[i]; 449 qEvenMeasOffset = ah->totalAdcQEvenPhase[i];
462 450
463 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, 451 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
464 "Starting ADC Gain Cal for Chain %d\n", i); 452 "Starting ADC Gain Cal for Chain %d\n", i);
@@ -506,21 +494,20 @@ static void ath9k_hw_adc_gaincal_calibrate(struct ath_hal *ah, u8 numChains)
506 AR_PHY_NEW_ADC_GAIN_CORR_ENABLE); 494 AR_PHY_NEW_ADC_GAIN_CORR_ENABLE);
507} 495}
508 496
509static void ath9k_hw_adc_dccal_calibrate(struct ath_hal *ah, u8 numChains) 497static void ath9k_hw_adc_dccal_calibrate(struct ath_hw *ah, u8 numChains)
510{ 498{
511 struct ath_hal_5416 *ahp = AH5416(ah);
512 u32 iOddMeasOffset, iEvenMeasOffset, val, i; 499 u32 iOddMeasOffset, iEvenMeasOffset, val, i;
513 int32_t qOddMeasOffset, qEvenMeasOffset, qDcMismatch, iDcMismatch; 500 int32_t qOddMeasOffset, qEvenMeasOffset, qDcMismatch, iDcMismatch;
514 const struct hal_percal_data *calData = 501 const struct hal_percal_data *calData =
515 ahp->ah_cal_list_curr->calData; 502 ah->cal_list_curr->calData;
516 u32 numSamples = 503 u32 numSamples =
517 (1 << (calData->calCountMax + 5)) * calData->calNumSamples; 504 (1 << (calData->calCountMax + 5)) * calData->calNumSamples;
518 505
519 for (i = 0; i < numChains; i++) { 506 for (i = 0; i < numChains; i++) {
520 iOddMeasOffset = ahp->ah_totalAdcDcOffsetIOddPhase[i]; 507 iOddMeasOffset = ah->totalAdcDcOffsetIOddPhase[i];
521 iEvenMeasOffset = ahp->ah_totalAdcDcOffsetIEvenPhase[i]; 508 iEvenMeasOffset = ah->totalAdcDcOffsetIEvenPhase[i];
522 qOddMeasOffset = ahp->ah_totalAdcDcOffsetQOddPhase[i]; 509 qOddMeasOffset = ah->totalAdcDcOffsetQOddPhase[i];
523 qEvenMeasOffset = ahp->ah_totalAdcDcOffsetQEvenPhase[i]; 510 qEvenMeasOffset = ah->totalAdcDcOffsetQEvenPhase[i];
524 511
525 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, 512 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
526 "Starting ADC DC Offset Cal for Chain %d\n", i); 513 "Starting ADC DC Offset Cal for Chain %d\n", i);
@@ -565,13 +552,12 @@ static void ath9k_hw_adc_dccal_calibrate(struct ath_hal *ah, u8 numChains)
565} 552}
566 553
567/* This is done for the currently configured channel */ 554/* This is done for the currently configured channel */
568bool ath9k_hw_reset_calvalid(struct ath_hal *ah) 555bool ath9k_hw_reset_calvalid(struct ath_hw *ah)
569{ 556{
570 struct ath_hal_5416 *ahp = AH5416(ah);
571 struct ieee80211_conf *conf = &ah->ah_sc->hw->conf; 557 struct ieee80211_conf *conf = &ah->ah_sc->hw->conf;
572 struct hal_cal_list *currCal = ahp->ah_cal_list_curr; 558 struct hal_cal_list *currCal = ah->cal_list_curr;
573 559
574 if (!ah->ah_curchan) 560 if (!ah->curchan)
575 return true; 561 return true;
576 562
577 if (!AR_SREV_9100(ah) && !AR_SREV_9160_10_OR_LATER(ah)) 563 if (!AR_SREV_9100(ah) && !AR_SREV_9160_10_OR_LATER(ah))
@@ -594,13 +580,13 @@ bool ath9k_hw_reset_calvalid(struct ath_hal *ah)
594 "Resetting Cal %d state for channel %u\n", 580 "Resetting Cal %d state for channel %u\n",
595 currCal->calData->calType, conf->channel->center_freq); 581 currCal->calData->calType, conf->channel->center_freq);
596 582
597 ah->ah_curchan->CalValid &= ~currCal->calData->calType; 583 ah->curchan->CalValid &= ~currCal->calData->calType;
598 currCal->calState = CAL_WAITING; 584 currCal->calState = CAL_WAITING;
599 585
600 return false; 586 return false;
601} 587}
602 588
603void ath9k_hw_start_nfcal(struct ath_hal *ah) 589void ath9k_hw_start_nfcal(struct ath_hw *ah)
604{ 590{
605 REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, 591 REG_SET_BIT(ah, AR_PHY_AGC_CONTROL,
606 AR_PHY_AGC_CONTROL_ENABLE_NF); 592 AR_PHY_AGC_CONTROL_ENABLE_NF);
@@ -609,7 +595,7 @@ void ath9k_hw_start_nfcal(struct ath_hal *ah)
609 REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF); 595 REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF);
610} 596}
611 597
612void ath9k_hw_loadnf(struct ath_hal *ah, struct ath9k_channel *chan) 598void ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan)
613{ 599{
614 struct ath9k_nfcal_hist *h; 600 struct ath9k_nfcal_hist *h;
615 int i, j; 601 int i, j;
@@ -665,7 +651,7 @@ void ath9k_hw_loadnf(struct ath_hal *ah, struct ath9k_channel *chan)
665 } 651 }
666} 652}
667 653
668int16_t ath9k_hw_getnf(struct ath_hal *ah, 654int16_t ath9k_hw_getnf(struct ath_hw *ah,
669 struct ath9k_channel *chan) 655 struct ath9k_channel *chan)
670{ 656{
671 int16_t nf, nfThresh; 657 int16_t nf, nfThresh;
@@ -701,7 +687,7 @@ int16_t ath9k_hw_getnf(struct ath_hal *ah,
701 return chan->rawNoiseFloor; 687 return chan->rawNoiseFloor;
702} 688}
703 689
704void ath9k_init_nfcal_hist_buffer(struct ath_hal *ah) 690void ath9k_init_nfcal_hist_buffer(struct ath_hw *ah)
705{ 691{
706 int i, j; 692 int i, j;
707 693
@@ -715,10 +701,9 @@ void ath9k_init_nfcal_hist_buffer(struct ath_hal *ah)
715 AR_PHY_CCA_MAX_GOOD_VALUE; 701 AR_PHY_CCA_MAX_GOOD_VALUE;
716 } 702 }
717 } 703 }
718 return;
719} 704}
720 705
721s16 ath9k_hw_getchan_noise(struct ath_hal *ah, struct ath9k_channel *chan) 706s16 ath9k_hw_getchan_noise(struct ath_hw *ah, struct ath9k_channel *chan)
722{ 707{
723 s16 nf; 708 s16 nf;
724 709
@@ -733,12 +718,11 @@ s16 ath9k_hw_getchan_noise(struct ath_hal *ah, struct ath9k_channel *chan)
733 return nf; 718 return nf;
734} 719}
735 720
736bool ath9k_hw_calibrate(struct ath_hal *ah, struct ath9k_channel *chan, 721bool ath9k_hw_calibrate(struct ath_hw *ah, struct ath9k_channel *chan,
737 u8 rxchainmask, bool longcal, 722 u8 rxchainmask, bool longcal,
738 bool *isCalDone) 723 bool *isCalDone)
739{ 724{
740 struct ath_hal_5416 *ahp = AH5416(ah); 725 struct hal_cal_list *currCal = ah->cal_list_curr;
741 struct hal_cal_list *currCal = ahp->ah_cal_list_curr;
742 726
743 *isCalDone = true; 727 *isCalDone = true;
744 728
@@ -748,7 +732,7 @@ bool ath9k_hw_calibrate(struct ath_hal *ah, struct ath9k_channel *chan,
748 ath9k_hw_per_calibration(ah, chan, rxchainmask, currCal, 732 ath9k_hw_per_calibration(ah, chan, rxchainmask, currCal,
749 isCalDone); 733 isCalDone);
750 if (*isCalDone) { 734 if (*isCalDone) {
751 ahp->ah_cal_list_curr = currCal = currCal->calNext; 735 ah->cal_list_curr = currCal = currCal->calNext;
752 736
753 if (currCal->calState == CAL_WAITING) { 737 if (currCal->calState == CAL_WAITING) {
754 *isCalDone = false; 738 *isCalDone = false;
@@ -759,7 +743,7 @@ bool ath9k_hw_calibrate(struct ath_hal *ah, struct ath9k_channel *chan,
759 743
760 if (longcal) { 744 if (longcal) {
761 ath9k_hw_getnf(ah, chan); 745 ath9k_hw_getnf(ah, chan);
762 ath9k_hw_loadnf(ah, ah->ah_curchan); 746 ath9k_hw_loadnf(ah, ah->curchan);
763 ath9k_hw_start_nfcal(ah); 747 ath9k_hw_start_nfcal(ah);
764 748
765 if (chan->channelFlags & CHANNEL_CW_INT) 749 if (chan->channelFlags & CHANNEL_CW_INT)
@@ -769,7 +753,7 @@ bool ath9k_hw_calibrate(struct ath_hal *ah, struct ath9k_channel *chan,
769 return true; 753 return true;
770} 754}
771 755
772static inline void ath9k_hw_9285_pa_cal(struct ath_hal *ah) 756static inline void ath9k_hw_9285_pa_cal(struct ath_hw *ah)
773{ 757{
774 758
775 u32 regVal; 759 u32 regVal;
@@ -864,11 +848,9 @@ static inline void ath9k_hw_9285_pa_cal(struct ath_hal *ah)
864 848
865} 849}
866 850
867bool ath9k_hw_init_cal(struct ath_hal *ah, 851bool ath9k_hw_init_cal(struct ath_hw *ah,
868 struct ath9k_channel *chan) 852 struct ath9k_channel *chan)
869{ 853{
870 struct ath_hal_5416 *ahp = AH5416(ah);
871
872 REG_WRITE(ah, AR_PHY_AGC_CONTROL, 854 REG_WRITE(ah, AR_PHY_AGC_CONTROL,
873 REG_READ(ah, AR_PHY_AGC_CONTROL) | 855 REG_READ(ah, AR_PHY_AGC_CONTROL) |
874 AR_PHY_AGC_CONTROL_CAL); 856 AR_PHY_AGC_CONTROL_CAL);
@@ -887,32 +869,32 @@ bool ath9k_hw_init_cal(struct ath_hal *ah,
887 REG_READ(ah, AR_PHY_AGC_CONTROL) | 869 REG_READ(ah, AR_PHY_AGC_CONTROL) |
888 AR_PHY_AGC_CONTROL_NF); 870 AR_PHY_AGC_CONTROL_NF);
889 871
890 ahp->ah_cal_list = ahp->ah_cal_list_last = ahp->ah_cal_list_curr = NULL; 872 ah->cal_list = ah->cal_list_last = ah->cal_list_curr = NULL;
891 873
892 if (AR_SREV_9100(ah) || AR_SREV_9160_10_OR_LATER(ah)) { 874 if (AR_SREV_9100(ah) || AR_SREV_9160_10_OR_LATER(ah)) {
893 if (ath9k_hw_iscal_supported(ah, ADC_GAIN_CAL)) { 875 if (ath9k_hw_iscal_supported(ah, ADC_GAIN_CAL)) {
894 INIT_CAL(&ahp->ah_adcGainCalData); 876 INIT_CAL(&ah->adcgain_caldata);
895 INSERT_CAL(ahp, &ahp->ah_adcGainCalData); 877 INSERT_CAL(ah, &ah->adcgain_caldata);
896 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, 878 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
897 "enabling ADC Gain Calibration.\n"); 879 "enabling ADC Gain Calibration.\n");
898 } 880 }
899 if (ath9k_hw_iscal_supported(ah, ADC_DC_CAL)) { 881 if (ath9k_hw_iscal_supported(ah, ADC_DC_CAL)) {
900 INIT_CAL(&ahp->ah_adcDcCalData); 882 INIT_CAL(&ah->adcdc_caldata);
901 INSERT_CAL(ahp, &ahp->ah_adcDcCalData); 883 INSERT_CAL(ah, &ah->adcdc_caldata);
902 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, 884 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
903 "enabling ADC DC Calibration.\n"); 885 "enabling ADC DC Calibration.\n");
904 } 886 }
905 if (ath9k_hw_iscal_supported(ah, IQ_MISMATCH_CAL)) { 887 if (ath9k_hw_iscal_supported(ah, IQ_MISMATCH_CAL)) {
906 INIT_CAL(&ahp->ah_iqCalData); 888 INIT_CAL(&ah->iq_caldata);
907 INSERT_CAL(ahp, &ahp->ah_iqCalData); 889 INSERT_CAL(ah, &ah->iq_caldata);
908 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, 890 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
909 "enabling IQ Calibration.\n"); 891 "enabling IQ Calibration.\n");
910 } 892 }
911 893
912 ahp->ah_cal_list_curr = ahp->ah_cal_list; 894 ah->cal_list_curr = ah->cal_list;
913 895
914 if (ahp->ah_cal_list_curr) 896 if (ah->cal_list_curr)
915 ath9k_hw_reset_calibration(ah, ahp->ah_cal_list_curr); 897 ath9k_hw_reset_calibration(ah, ah->cal_list_curr);
916 } 898 }
917 899
918 chan->CalValid = 0; 900 chan->CalValid = 0;
diff --git a/drivers/net/wireless/ath9k/calib.h b/drivers/net/wireless/ath9k/calib.h
new file mode 100644
index 000000000000..d2448f049c1d
--- /dev/null
+++ b/drivers/net/wireless/ath9k/calib.h
@@ -0,0 +1,124 @@
1/*
2 * Copyright (c) 2008 Atheros Communications Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#ifndef CALIB_H
18#define CALIB_H
19
20extern const struct hal_percal_data iq_cal_multi_sample;
21extern const struct hal_percal_data iq_cal_single_sample;
22extern const struct hal_percal_data adc_gain_cal_multi_sample;
23extern const struct hal_percal_data adc_gain_cal_single_sample;
24extern const struct hal_percal_data adc_dc_cal_multi_sample;
25extern const struct hal_percal_data adc_dc_cal_single_sample;
26extern const struct hal_percal_data adc_init_dc_cal;
27
28#define AR_PHY_CCA_MAX_GOOD_VALUE -85
29#define AR_PHY_CCA_MAX_HIGH_VALUE -62
30#define AR_PHY_CCA_MIN_BAD_VALUE -121
31#define AR_PHY_CCA_FILTERWINDOW_LENGTH_INIT 3
32#define AR_PHY_CCA_FILTERWINDOW_LENGTH 5
33
34#define NUM_NF_READINGS 6
35#define ATH9K_NF_CAL_HIST_MAX 5
36
37struct ar5416IniArray {
38 u32 *ia_array;
39 u32 ia_rows;
40 u32 ia_columns;
41};
42
43#define INIT_INI_ARRAY(iniarray, array, rows, columns) do { \
44 (iniarray)->ia_array = (u32 *)(array); \
45 (iniarray)->ia_rows = (rows); \
46 (iniarray)->ia_columns = (columns); \
47 } while (0)
48
49#define INI_RA(iniarray, row, column) \
50 (((iniarray)->ia_array)[(row) * ((iniarray)->ia_columns) + (column)])
51
52#define INIT_CAL(_perCal) do { \
53 (_perCal)->calState = CAL_WAITING; \
54 (_perCal)->calNext = NULL; \
55 } while (0)
56
57#define INSERT_CAL(_ahp, _perCal) \
58 do { \
59 if ((_ahp)->cal_list_last == NULL) { \
60 (_ahp)->cal_list = \
61 (_ahp)->cal_list_last = (_perCal); \
62 ((_ahp)->cal_list_last)->calNext = (_perCal); \
63 } else { \
64 ((_ahp)->cal_list_last)->calNext = (_perCal); \
65 (_ahp)->cal_list_last = (_perCal); \
66 (_perCal)->calNext = (_ahp)->cal_list; \
67 } \
68 } while (0)
69
70enum hal_cal_types {
71 ADC_DC_INIT_CAL = 0x1,
72 ADC_GAIN_CAL = 0x2,
73 ADC_DC_CAL = 0x4,
74 IQ_MISMATCH_CAL = 0x8
75};
76
77enum hal_cal_state {
78 CAL_INACTIVE,
79 CAL_WAITING,
80 CAL_RUNNING,
81 CAL_DONE
82};
83
84#define MIN_CAL_SAMPLES 1
85#define MAX_CAL_SAMPLES 64
86#define INIT_LOG_COUNT 5
87#define PER_MIN_LOG_COUNT 2
88#define PER_MAX_LOG_COUNT 10
89
90struct hal_percal_data {
91 enum hal_cal_types calType;
92 u32 calNumSamples;
93 u32 calCountMax;
94 void (*calCollect) (struct ath_hw *);
95 void (*calPostProc) (struct ath_hw *, u8);
96};
97
98struct hal_cal_list {
99 const struct hal_percal_data *calData;
100 enum hal_cal_state calState;
101 struct hal_cal_list *calNext;
102};
103
104struct ath9k_nfcal_hist {
105 int16_t nfCalBuffer[ATH9K_NF_CAL_HIST_MAX];
106 u8 currIndex;
107 int16_t privNF;
108 u8 invalidNFcount;
109};
110
111bool ath9k_hw_reset_calvalid(struct ath_hw *ah);
112void ath9k_hw_start_nfcal(struct ath_hw *ah);
113void ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan);
114int16_t ath9k_hw_getnf(struct ath_hw *ah,
115 struct ath9k_channel *chan);
116void ath9k_init_nfcal_hist_buffer(struct ath_hw *ah);
117s16 ath9k_hw_getchan_noise(struct ath_hw *ah, struct ath9k_channel *chan);
118bool ath9k_hw_calibrate(struct ath_hw *ah, struct ath9k_channel *chan,
119 u8 rxchainmask, bool longcal,
120 bool *isCalDone);
121bool ath9k_hw_init_cal(struct ath_hw *ah,
122 struct ath9k_channel *chan);
123
124#endif /* CALIB_H */
diff --git a/drivers/net/wireless/ath9k/core.h b/drivers/net/wireless/ath9k/core.h
deleted file mode 100644
index 791f1acc0bb3..000000000000
--- a/drivers/net/wireless/ath9k/core.h
+++ /dev/null
@@ -1,816 +0,0 @@
1/*
2 * Copyright (c) 2008 Atheros Communications Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#ifndef CORE_H
18#define CORE_H
19
20#include <linux/etherdevice.h>
21#include <linux/device.h>
22#include <net/mac80211.h>
23#include <linux/leds.h>
24#include <linux/rfkill.h>
25
26#include "ath9k.h"
27#include "rc.h"
28
29struct ath_node;
30
31/* Macro to expand scalars to 64-bit objects */
32
33#define ito64(x) (sizeof(x) == 8) ? \
34 (((unsigned long long int)(x)) & (0xff)) : \
35 (sizeof(x) == 16) ? \
36 (((unsigned long long int)(x)) & 0xffff) : \
37 ((sizeof(x) == 32) ? \
38 (((unsigned long long int)(x)) & 0xffffffff) : \
39 (unsigned long long int)(x))
40
41/* increment with wrap-around */
42#define INCR(_l, _sz) do { \
43 (_l)++; \
44 (_l) &= ((_sz) - 1); \
45 } while (0)
46
47/* decrement with wrap-around */
48#define DECR(_l, _sz) do { \
49 (_l)--; \
50 (_l) &= ((_sz) - 1); \
51 } while (0)
52
53#define A_MAX(a, b) ((a) > (b) ? (a) : (b))
54
55#define ASSERT(exp) do { \
56 if (unlikely(!(exp))) { \
57 BUG(); \
58 } \
59 } while (0)
60
61#define TSF_TO_TU(_h,_l) \
62 ((((u32)(_h)) << 22) | (((u32)(_l)) >> 10))
63
64#define ATH_TXQ_SETUP(sc, i) ((sc)->tx.txqsetup & (1<<i))
65
66static const u8 ath_bcast_mac[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
67
68enum ATH_DEBUG {
69 ATH_DBG_RESET = 0x00000001,
70 ATH_DBG_REG_IO = 0x00000002,
71 ATH_DBG_QUEUE = 0x00000004,
72 ATH_DBG_EEPROM = 0x00000008,
73 ATH_DBG_CALIBRATE = 0x00000010,
74 ATH_DBG_CHANNEL = 0x00000020,
75 ATH_DBG_INTERRUPT = 0x00000040,
76 ATH_DBG_REGULATORY = 0x00000080,
77 ATH_DBG_ANI = 0x00000100,
78 ATH_DBG_POWER_MGMT = 0x00000200,
79 ATH_DBG_XMIT = 0x00000400,
80 ATH_DBG_BEACON = 0x00001000,
81 ATH_DBG_CONFIG = 0x00002000,
82 ATH_DBG_KEYCACHE = 0x00004000,
83 ATH_DBG_FATAL = 0x00008000,
84 ATH_DBG_ANY = 0xffffffff
85};
86
87#define DBG_DEFAULT (ATH_DBG_FATAL)
88
89#ifdef CONFIG_ATH9K_DEBUG
90
91/**
92 * struct ath_interrupt_stats - Contains statistics about interrupts
93 * @total: Total no. of interrupts generated so far
94 * @rxok: RX with no errors
95 * @rxeol: RX with no more RXDESC available
96 * @rxorn: RX FIFO overrun
97 * @txok: TX completed at the requested rate
98 * @txurn: TX FIFO underrun
99 * @mib: MIB regs reaching its threshold
100 * @rxphyerr: RX with phy errors
101 * @rx_keycache_miss: RX with key cache misses
102 * @swba: Software Beacon Alert
103 * @bmiss: Beacon Miss
104 * @bnr: Beacon Not Ready
105 * @cst: Carrier Sense TImeout
106 * @gtt: Global TX Timeout
107 * @tim: RX beacon TIM occurrence
108 * @cabend: RX End of CAB traffic
109 * @dtimsync: DTIM sync lossage
110 * @dtim: RX Beacon with DTIM
111 */
112struct ath_interrupt_stats {
113 u32 total;
114 u32 rxok;
115 u32 rxeol;
116 u32 rxorn;
117 u32 txok;
118 u32 txeol;
119 u32 txurn;
120 u32 mib;
121 u32 rxphyerr;
122 u32 rx_keycache_miss;
123 u32 swba;
124 u32 bmiss;
125 u32 bnr;
126 u32 cst;
127 u32 gtt;
128 u32 tim;
129 u32 cabend;
130 u32 dtimsync;
131 u32 dtim;
132};
133
134struct ath_legacy_rc_stats {
135 u32 success;
136};
137
138struct ath_11n_rc_stats {
139 u32 success;
140};
141
142struct ath_stats {
143 struct ath_interrupt_stats istats;
144 struct ath_legacy_rc_stats legacy_rcstats[12]; /* max(11a,11b,11g) */
145 struct ath_11n_rc_stats n_rcstats[16]; /* 0..15 MCS rates */
146};
147
148struct ath9k_debug {
149 int debug_mask;
150 struct dentry *debugfs_root;
151 struct dentry *debugfs_phy;
152 struct dentry *debugfs_dma;
153 struct dentry *debugfs_interrupt;
154 struct dentry *debugfs_rcstat;
155 struct ath_stats stats;
156};
157
158void DPRINTF(struct ath_softc *sc, int dbg_mask, const char *fmt, ...);
159int ath9k_init_debug(struct ath_softc *sc);
160void ath9k_exit_debug(struct ath_softc *sc);
161void ath_debug_stat_interrupt(struct ath_softc *sc, enum ath9k_int status);
162void ath_debug_stat_rc(struct ath_softc *sc, struct sk_buff *skb);
163
164#else
165
166static inline void DPRINTF(struct ath_softc *sc, int dbg_mask,
167 const char *fmt, ...)
168{
169}
170
171static inline int ath9k_init_debug(struct ath_softc *sc)
172{
173 return 0;
174}
175
176static inline void ath9k_exit_debug(struct ath_softc *sc)
177{
178}
179
180static inline void ath_debug_stat_interrupt(struct ath_softc *sc,
181 enum ath9k_int status)
182{
183}
184
185static inline void ath_debug_stat_rc(struct ath_softc *sc,
186 struct sk_buff *skb)
187{
188}
189
190#endif /* CONFIG_ATH9K_DEBUG */
191
192struct ath_config {
193 u32 ath_aggr_prot;
194 u16 txpowlimit;
195 u16 txpowlimit_override;
196 u8 cabqReadytime;
197 u8 swBeaconProcess;
198};
199
200/*************************/
201/* Descriptor Management */
202/*************************/
203
204#define ATH_TXBUF_RESET(_bf) do { \
205 (_bf)->bf_status = 0; \
206 (_bf)->bf_lastbf = NULL; \
207 (_bf)->bf_next = NULL; \
208 memset(&((_bf)->bf_state), 0, \
209 sizeof(struct ath_buf_state)); \
210 } while (0)
211
212enum buffer_type {
213 BUF_DATA = BIT(0),
214 BUF_AGGR = BIT(1),
215 BUF_AMPDU = BIT(2),
216 BUF_HT = BIT(3),
217 BUF_RETRY = BIT(4),
218 BUF_XRETRY = BIT(5),
219 BUF_SHORT_PREAMBLE = BIT(6),
220 BUF_BAR = BIT(7),
221 BUF_PSPOLL = BIT(8),
222 BUF_AGGR_BURST = BIT(9),
223 BUF_CALC_AIRTIME = BIT(10),
224};
225
226struct ath_buf_state {
227 int bfs_nframes; /* # frames in aggregate */
228 u16 bfs_al; /* length of aggregate */
229 u16 bfs_frmlen; /* length of frame */
230 int bfs_seqno; /* sequence number */
231 int bfs_tidno; /* tid of this frame */
232 int bfs_retries; /* current retries */
233 u32 bf_type; /* BUF_* (enum buffer_type) */
234 u32 bfs_keyix;
235 enum ath9k_key_type bfs_keytype;
236};
237
238#define bf_nframes bf_state.bfs_nframes
239#define bf_al bf_state.bfs_al
240#define bf_frmlen bf_state.bfs_frmlen
241#define bf_retries bf_state.bfs_retries
242#define bf_seqno bf_state.bfs_seqno
243#define bf_tidno bf_state.bfs_tidno
244#define bf_rcs bf_state.bfs_rcs
245#define bf_keyix bf_state.bfs_keyix
246#define bf_keytype bf_state.bfs_keytype
247#define bf_isdata(bf) (bf->bf_state.bf_type & BUF_DATA)
248#define bf_isaggr(bf) (bf->bf_state.bf_type & BUF_AGGR)
249#define bf_isampdu(bf) (bf->bf_state.bf_type & BUF_AMPDU)
250#define bf_isht(bf) (bf->bf_state.bf_type & BUF_HT)
251#define bf_isretried(bf) (bf->bf_state.bf_type & BUF_RETRY)
252#define bf_isxretried(bf) (bf->bf_state.bf_type & BUF_XRETRY)
253#define bf_isbar(bf) (bf->bf_state.bf_type & BUF_BAR)
254#define bf_ispspoll(bf) (bf->bf_state.bf_type & BUF_PSPOLL)
255#define bf_isaggrburst(bf) (bf->bf_state.bf_type & BUF_AGGR_BURST)
256
257/*
258 * Abstraction of a contiguous buffer to transmit/receive. There is only
259 * a single hw descriptor encapsulated here.
260 */
261struct ath_buf {
262 struct list_head list;
263 struct ath_buf *bf_lastbf; /* last buf of this unit (a frame or
264 an aggregate) */
265 struct ath_buf *bf_next; /* next subframe in the aggregate */
266 void *bf_mpdu; /* enclosing frame structure */
267 struct ath_desc *bf_desc; /* virtual addr of desc */
268 dma_addr_t bf_daddr; /* physical addr of desc */
269 dma_addr_t bf_buf_addr; /* physical addr of data buffer */
270 u32 bf_status;
271 u16 bf_flags; /* tx descriptor flags */
272 struct ath_buf_state bf_state; /* buffer state */
273 dma_addr_t bf_dmacontext;
274};
275
276#define ATH_RXBUF_RESET(_bf) ((_bf)->bf_status = 0)
277#define ATH_BUFSTATUS_STALE 0x00000002
278
279/* DMA state for tx/rx descriptors */
280
281struct ath_descdma {
282 const char *dd_name;
283 struct ath_desc *dd_desc; /* descriptors */
284 dma_addr_t dd_desc_paddr; /* physical addr of dd_desc */
285 u32 dd_desc_len; /* size of dd_desc */
286 struct ath_buf *dd_bufptr; /* associated buffers */
287 dma_addr_t dd_dmacontext;
288};
289
290int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd,
291 struct list_head *head, const char *name,
292 int nbuf, int ndesc);
293void ath_descdma_cleanup(struct ath_softc *sc, struct ath_descdma *dd,
294 struct list_head *head);
295
296/***********/
297/* RX / TX */
298/***********/
299
300#define ATH_MAX_ANTENNA 3
301#define ATH_RXBUF 512
302#define WME_NUM_TID 16
303#define ATH_TXBUF 512
304#define ATH_TXMAXTRY 13
305#define ATH_11N_TXMAXTRY 10
306#define ATH_MGT_TXMAXTRY 4
307#define WME_BA_BMP_SIZE 64
308#define WME_MAX_BA WME_BA_BMP_SIZE
309#define ATH_TID_MAX_BUFS (2 * WME_MAX_BA)
310
311#define TID_TO_WME_AC(_tid) \
312 ((((_tid) == 0) || ((_tid) == 3)) ? WME_AC_BE : \
313 (((_tid) == 1) || ((_tid) == 2)) ? WME_AC_BK : \
314 (((_tid) == 4) || ((_tid) == 5)) ? WME_AC_VI : \
315 WME_AC_VO)
316
317#define WME_AC_BE 0
318#define WME_AC_BK 1
319#define WME_AC_VI 2
320#define WME_AC_VO 3
321#define WME_NUM_AC 4
322
323#define ADDBA_EXCHANGE_ATTEMPTS 10
324#define ATH_AGGR_DELIM_SZ 4
325#define ATH_AGGR_MINPLEN 256 /* in bytes, minimum packet length */
326/* number of delimiters for encryption padding */
327#define ATH_AGGR_ENCRYPTDELIM 10
328/* minimum h/w qdepth to be sustained to maximize aggregation */
329#define ATH_AGGR_MIN_QDEPTH 2
330#define ATH_AMPDU_SUBFRAME_DEFAULT 32
331#define IEEE80211_SEQ_SEQ_SHIFT 4
332#define IEEE80211_SEQ_MAX 4096
333#define IEEE80211_MIN_AMPDU_BUF 0x8
334#define IEEE80211_HTCAP_MAXRXAMPDU_FACTOR 13
335
336/* return whether a bit at index _n in bitmap _bm is set
337 * _sz is the size of the bitmap */
338#define ATH_BA_ISSET(_bm, _n) (((_n) < (WME_BA_BMP_SIZE)) && \
339 ((_bm)[(_n) >> 5] & (1 << ((_n) & 31))))
340
341/* return block-ack bitmap index given sequence and starting sequence */
342#define ATH_BA_INDEX(_st, _seq) (((_seq) - (_st)) & (IEEE80211_SEQ_MAX - 1))
343
344/* returns delimiter padding required given the packet length */
345#define ATH_AGGR_GET_NDELIM(_len) \
346 (((((_len) + ATH_AGGR_DELIM_SZ) < ATH_AGGR_MINPLEN) ? \
347 (ATH_AGGR_MINPLEN - (_len) - ATH_AGGR_DELIM_SZ) : 0) >> 2)
348
349#define BAW_WITHIN(_start, _bawsz, _seqno) \
350 ((((_seqno) - (_start)) & 4095) < (_bawsz))
351
352#define ATH_DS_BA_SEQ(_ds) ((_ds)->ds_us.tx.ts_seqnum)
353#define ATH_DS_BA_BITMAP(_ds) (&(_ds)->ds_us.tx.ba_low)
354#define ATH_DS_TX_BA(_ds) ((_ds)->ds_us.tx.ts_flags & ATH9K_TX_BA)
355#define ATH_AN_2_TID(_an, _tidno) (&(_an)->tid[(_tidno)])
356
357enum ATH_AGGR_STATUS {
358 ATH_AGGR_DONE,
359 ATH_AGGR_BAW_CLOSED,
360 ATH_AGGR_LIMITED,
361 ATH_AGGR_SHORTPKT,
362 ATH_AGGR_8K_LIMITED,
363};
364
365struct ath_txq {
366 u32 axq_qnum; /* hardware q number */
367 u32 *axq_link; /* link ptr in last TX desc */
368 struct list_head axq_q; /* transmit queue */
369 spinlock_t axq_lock;
370 u32 axq_depth; /* queue depth */
371 u8 axq_aggr_depth; /* aggregates queued */
372 u32 axq_totalqueued; /* total ever queued */
373 bool stopped; /* Is mac80211 queue stopped ? */
374 struct ath_buf *axq_linkbuf; /* virtual addr of last buffer*/
375
376 /* first desc of the last descriptor that contains CTS */
377 struct ath_desc *axq_lastdsWithCTS;
378
379 /* final desc of the gating desc that determines whether
380 lastdsWithCTS has been DMA'ed or not */
381 struct ath_desc *axq_gatingds;
382
383 struct list_head axq_acq;
384};
385
386#define AGGR_CLEANUP BIT(1)
387#define AGGR_ADDBA_COMPLETE BIT(2)
388#define AGGR_ADDBA_PROGRESS BIT(3)
389
390/* per TID aggregate tx state for a destination */
391struct ath_atx_tid {
392 struct list_head list; /* round-robin tid entry */
393 struct list_head buf_q; /* pending buffers */
394 struct ath_node *an;
395 struct ath_atx_ac *ac;
396 struct ath_buf *tx_buf[ATH_TID_MAX_BUFS]; /* active tx frames */
397 u16 seq_start;
398 u16 seq_next;
399 u16 baw_size;
400 int tidno;
401 int baw_head; /* first un-acked tx buffer */
402 int baw_tail; /* next unused tx buffer slot */
403 int sched;
404 int paused;
405 u8 state;
406 int addba_exchangeattempts;
407};
408
409/* per access-category aggregate tx state for a destination */
410struct ath_atx_ac {
411 int sched; /* dest-ac is scheduled */
412 int qnum; /* H/W queue number associated
413 with this AC */
414 struct list_head list; /* round-robin txq entry */
415 struct list_head tid_q; /* queue of TIDs with buffers */
416};
417
418/* per-frame tx control block */
419struct ath_tx_control {
420 struct ath_txq *txq;
421 int if_id;
422};
423
424/* per frame tx status block */
425struct ath_xmit_status {
426 int retries; /* number of retries to successufully
427 transmit this frame */
428 int flags; /* status of transmit */
429#define ATH_TX_ERROR 0x01
430#define ATH_TX_XRETRY 0x02
431#define ATH_TX_BAR 0x04
432};
433
434/* All RSSI values are noise floor adjusted */
435struct ath_tx_stat {
436 int rssi;
437 int rssictl[ATH_MAX_ANTENNA];
438 int rssiextn[ATH_MAX_ANTENNA];
439 int rateieee;
440 int rateKbps;
441 int ratecode;
442 int flags;
443 u32 airtime; /* time on air per final tx rate */
444};
445
446struct aggr_rifs_param {
447 int param_max_frames;
448 int param_max_len;
449 int param_rl;
450 int param_al;
451 struct ath_rc_series *param_rcs;
452};
453
454struct ath_node {
455 struct ath_softc *an_sc;
456 struct ath_atx_tid tid[WME_NUM_TID];
457 struct ath_atx_ac ac[WME_NUM_AC];
458 u16 maxampdu;
459 u8 mpdudensity;
460};
461
462struct ath_tx {
463 u16 seq_no;
464 u32 txqsetup;
465 int hwq_map[ATH9K_WME_AC_VO+1];
466 spinlock_t txbuflock;
467 struct list_head txbuf;
468 struct ath_txq txq[ATH9K_NUM_TX_QUEUES];
469 struct ath_descdma txdma;
470};
471
472struct ath_rx {
473 u8 defant;
474 u8 rxotherant;
475 u32 *rxlink;
476 int bufsize;
477 unsigned int rxfilter;
478 spinlock_t rxflushlock;
479 spinlock_t rxbuflock;
480 struct list_head rxbuf;
481 struct ath_descdma rxdma;
482};
483
484int ath_startrecv(struct ath_softc *sc);
485bool ath_stoprecv(struct ath_softc *sc);
486void ath_flushrecv(struct ath_softc *sc);
487u32 ath_calcrxfilter(struct ath_softc *sc);
488int ath_rx_init(struct ath_softc *sc, int nbufs);
489void ath_rx_cleanup(struct ath_softc *sc);
490int ath_rx_tasklet(struct ath_softc *sc, int flush);
491struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype);
492void ath_tx_cleanupq(struct ath_softc *sc, struct ath_txq *txq);
493int ath_tx_setup(struct ath_softc *sc, int haltype);
494void ath_drain_all_txq(struct ath_softc *sc, bool retry_tx);
495void ath_draintxq(struct ath_softc *sc,
496 struct ath_txq *txq, bool retry_tx);
497void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an);
498void ath_tx_node_cleanup(struct ath_softc *sc, struct ath_node *an);
499void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq);
500int ath_tx_init(struct ath_softc *sc, int nbufs);
501int ath_tx_cleanup(struct ath_softc *sc);
502struct ath_txq *ath_test_get_txq(struct ath_softc *sc, struct sk_buff *skb);
503int ath_txq_update(struct ath_softc *sc, int qnum,
504 struct ath9k_tx_queue_info *q);
505int ath_tx_start(struct ath_softc *sc, struct sk_buff *skb,
506 struct ath_tx_control *txctl);
507void ath_tx_tasklet(struct ath_softc *sc);
508void ath_tx_cabq(struct ath_softc *sc, struct sk_buff *skb);
509bool ath_tx_aggr_check(struct ath_softc *sc, struct ath_node *an, u8 tidno);
510int ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta,
511 u16 tid, u16 *ssn);
512int ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid);
513void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid);
514
515/********/
516/* VAPs */
517/********/
518
519/*
520 * Define the scheme that we select MAC address for multiple
521 * BSS on the same radio. The very first VAP will just use the MAC
522 * address from the EEPROM. For the next 3 VAPs, we set the
523 * U/L bit (bit 1) in MAC address, and use the next two bits as the
524 * index of the VAP.
525 */
526
527#define ATH_SET_VAP_BSSID_MASK(bssid_mask) \
528 ((bssid_mask)[0] &= ~(((ATH_BCBUF-1)<<2)|0x02))
529
530struct ath_vap {
531 int av_bslot;
532 enum nl80211_iftype av_opmode;
533 struct ath_buf *av_bcbuf;
534 struct ath_tx_control av_btxctl;
535};
536
537/*******************/
538/* Beacon Handling */
539/*******************/
540
541/*
542 * Regardless of the number of beacons we stagger, (i.e. regardless of the
543 * number of BSSIDs) if a given beacon does not go out even after waiting this
544 * number of beacon intervals, the game's up.
545 */
546#define BSTUCK_THRESH (9 * ATH_BCBUF)
547#define ATH_BCBUF 1
548#define ATH_DEFAULT_BINTVAL 100 /* TU */
549#define ATH_DEFAULT_BMISS_LIMIT 10
550#define IEEE80211_MS_TO_TU(x) (((x) * 1000) / 1024)
551
552struct ath_beacon_config {
553 u16 beacon_interval;
554 u16 listen_interval;
555 u16 dtim_period;
556 u16 bmiss_timeout;
557 u8 dtim_count;
558 u8 tim_offset;
559 union {
560 u64 last_tsf;
561 u8 last_tstamp[8];
562 } u; /* last received beacon/probe response timestamp of this BSS. */
563};
564
565struct ath_beacon {
566 enum {
567 OK, /* no change needed */
568 UPDATE, /* update pending */
569 COMMIT /* beacon sent, commit change */
570 } updateslot; /* slot time update fsm */
571
572 u32 beaconq;
573 u32 bmisscnt;
574 u32 ast_be_xmit;
575 u64 bc_tstamp;
576 int bslot[ATH_BCBUF];
577 int slottime;
578 int slotupdate;
579 struct ath9k_tx_queue_info beacon_qi;
580 struct ath_descdma bdma;
581 struct ath_txq *cabq;
582 struct list_head bbuf;
583};
584
585void ath9k_beacon_tasklet(unsigned long data);
586void ath_beacon_config(struct ath_softc *sc, int if_id);
587int ath_beaconq_setup(struct ath_hal *ah);
588int ath_beacon_alloc(struct ath_softc *sc, int if_id);
589void ath_beacon_return(struct ath_softc *sc, struct ath_vap *avp);
590void ath_beacon_sync(struct ath_softc *sc, int if_id);
591
592/*******/
593/* ANI */
594/*******/
595
596/* ANI values for STA only.
597 FIXME: Add appropriate values for AP later */
598
599#define ATH_ANI_POLLINTERVAL 100 /* 100 milliseconds between ANI poll */
600#define ATH_SHORT_CALINTERVAL 1000 /* 1 second between calibrations */
601#define ATH_LONG_CALINTERVAL 30000 /* 30 seconds between calibrations */
602#define ATH_RESTART_CALINTERVAL 1200000 /* 20 minutes between calibrations */
603
604struct ath_ani {
605 bool sc_caldone;
606 int16_t sc_noise_floor;
607 unsigned int sc_longcal_timer;
608 unsigned int sc_shortcal_timer;
609 unsigned int sc_resetcal_timer;
610 unsigned int sc_checkani_timer;
611 struct timer_list timer;
612};
613
614/********************/
615/* LED Control */
616/********************/
617
618#define ATH_LED_PIN 1
619#define ATH_LED_ON_DURATION_IDLE 350 /* in msecs */
620#define ATH_LED_OFF_DURATION_IDLE 250 /* in msecs */
621
622enum ath_led_type {
623 ATH_LED_RADIO,
624 ATH_LED_ASSOC,
625 ATH_LED_TX,
626 ATH_LED_RX
627};
628
629struct ath_led {
630 struct ath_softc *sc;
631 struct led_classdev led_cdev;
632 enum ath_led_type led_type;
633 char name[32];
634 bool registered;
635};
636
637/* Rfkill */
638#define ATH_RFKILL_POLL_INTERVAL 2000 /* msecs */
639
640struct ath_rfkill {
641 struct rfkill *rfkill;
642 struct delayed_work rfkill_poll;
643 char rfkill_name[32];
644};
645
646/********************/
647/* Main driver core */
648/********************/
649
650/*
651 * Default cache line size, in bytes.
652 * Used when PCI device not fully initialized by bootrom/BIOS
653*/
654#define DEFAULT_CACHELINE 32
655#define ATH_DEFAULT_NOISE_FLOOR -95
656#define ATH_REGCLASSIDS_MAX 10
657#define ATH_CABQ_READY_TIME 80 /* % of beacon interval */
658#define ATH_MAX_SW_RETRIES 10
659#define ATH_CHAN_MAX 255
660#define IEEE80211_WEP_NKID 4 /* number of key ids */
661#define IEEE80211_RATE_VAL 0x7f
662/*
663 * The key cache is used for h/w cipher state and also for
664 * tracking station state such as the current tx antenna.
665 * We also setup a mapping table between key cache slot indices
666 * and station state to short-circuit node lookups on rx.
667 * Different parts have different size key caches. We handle
668 * up to ATH_KEYMAX entries (could dynamically allocate state).
669 */
670#define ATH_KEYMAX 128 /* max key cache size we handle */
671
672#define ATH_IF_ID_ANY 0xff
673#define ATH_TXPOWER_MAX 100 /* .5 dBm units */
674#define ATH_RSSI_DUMMY_MARKER 0x127
675#define ATH_RATE_DUMMY_MARKER 0
676
677#define SC_OP_INVALID BIT(0)
678#define SC_OP_BEACONS BIT(1)
679#define SC_OP_RXAGGR BIT(2)
680#define SC_OP_TXAGGR BIT(3)
681#define SC_OP_CHAINMASK_UPDATE BIT(4)
682#define SC_OP_FULL_RESET BIT(5)
683#define SC_OP_NO_RESET BIT(6)
684#define SC_OP_PREAMBLE_SHORT BIT(7)
685#define SC_OP_PROTECT_ENABLE BIT(8)
686#define SC_OP_RXFLUSH BIT(9)
687#define SC_OP_LED_ASSOCIATED BIT(10)
688#define SC_OP_RFKILL_REGISTERED BIT(11)
689#define SC_OP_RFKILL_SW_BLOCKED BIT(12)
690#define SC_OP_RFKILL_HW_BLOCKED BIT(13)
691#define SC_OP_WAIT_FOR_BEACON BIT(14)
692#define SC_OP_LED_ON BIT(15)
693
694struct ath_bus_ops {
695 void (*read_cachesize)(struct ath_softc *sc, int *csz);
696 void (*cleanup)(struct ath_softc *sc);
697 bool (*eeprom_read)(struct ath_hal *ah, u32 off, u16 *data);
698};
699
700struct ath_softc {
701 struct ieee80211_hw *hw;
702 struct device *dev;
703 struct tasklet_struct intr_tq;
704 struct tasklet_struct bcon_tasklet;
705 struct ath_hal *sc_ah;
706 void __iomem *mem;
707 int irq;
708 spinlock_t sc_resetlock;
709 struct mutex mutex;
710
711 u8 sc_curbssid[ETH_ALEN];
712 u8 sc_myaddr[ETH_ALEN];
713 u8 sc_bssidmask[ETH_ALEN];
714 u32 sc_intrstatus;
715 u32 sc_flags; /* SC_OP_* */
716 u16 sc_curtxpow;
717 u16 sc_curaid;
718 u16 sc_cachelsz;
719 u8 sc_nbcnvaps;
720 u16 sc_nvaps;
721 u8 sc_tx_chainmask;
722 u8 sc_rx_chainmask;
723 u32 sc_keymax;
724 DECLARE_BITMAP(sc_keymap, ATH_KEYMAX);
725 u8 sc_splitmic;
726 atomic_t ps_usecount;
727 enum ath9k_int sc_imask;
728 enum ath9k_ht_extprotspacing sc_ht_extprotspacing;
729 enum ath9k_ht_macmode tx_chan_width;
730
731 struct ath_config sc_config;
732 struct ath_rx rx;
733 struct ath_tx tx;
734 struct ath_beacon beacon;
735 struct ieee80211_vif *sc_vaps[ATH_BCBUF];
736 struct ieee80211_rate rates[IEEE80211_NUM_BANDS][ATH_RATE_MAX];
737 struct ath_rate_table *hw_rate_table[ATH9K_MODE_MAX];
738 struct ath_rate_table *cur_rate_table;
739 struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS];
740
741 struct ath_led radio_led;
742 struct ath_led assoc_led;
743 struct ath_led tx_led;
744 struct ath_led rx_led;
745 struct delayed_work ath_led_blink_work;
746 int led_on_duration;
747 int led_off_duration;
748 int led_on_cnt;
749 int led_off_cnt;
750
751 struct ath_rfkill rf_kill;
752 struct ath_ani sc_ani;
753 struct ath9k_node_stats sc_halstats;
754#ifdef CONFIG_ATH9K_DEBUG
755 struct ath9k_debug sc_debug;
756#endif
757 struct ath_bus_ops *bus_ops;
758};
759
760int ath_reset(struct ath_softc *sc, bool retry_tx);
761int ath_get_hal_qnum(u16 queue, struct ath_softc *sc);
762int ath_get_mac80211_qnum(u32 queue, struct ath_softc *sc);
763int ath_cabq_update(struct ath_softc *);
764
765static inline void ath_read_cachesize(struct ath_softc *sc, int *csz)
766{
767 sc->bus_ops->read_cachesize(sc, csz);
768}
769
770static inline void ath_bus_cleanup(struct ath_softc *sc)
771{
772 sc->bus_ops->cleanup(sc);
773}
774
775extern struct ieee80211_ops ath9k_ops;
776
777irqreturn_t ath_isr(int irq, void *dev);
778void ath_cleanup(struct ath_softc *sc);
779int ath_attach(u16 devid, struct ath_softc *sc);
780void ath_detach(struct ath_softc *sc);
781const char *ath_mac_bb_name(u32 mac_bb_version);
782const char *ath_rf_name(u16 rf_version);
783
784#ifdef CONFIG_PCI
785int ath_pci_init(void);
786void ath_pci_exit(void);
787#else
788static inline int ath_pci_init(void) { return 0; };
789static inline void ath_pci_exit(void) {};
790#endif
791
792#ifdef CONFIG_ATHEROS_AR71XX
793int ath_ahb_init(void);
794void ath_ahb_exit(void);
795#else
796static inline int ath_ahb_init(void) { return 0; };
797static inline void ath_ahb_exit(void) {};
798#endif
799
800static inline void ath9k_ps_wakeup(struct ath_softc *sc)
801{
802 if (atomic_inc_return(&sc->ps_usecount) == 1)
803 if (sc->sc_ah->ah_power_mode != ATH9K_PM_AWAKE) {
804 sc->sc_ah->ah_restore_mode = sc->sc_ah->ah_power_mode;
805 ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_AWAKE);
806 }
807}
808
809static inline void ath9k_ps_restore(struct ath_softc *sc)
810{
811 if (atomic_dec_and_test(&sc->ps_usecount))
812 if (sc->hw->conf.flags & IEEE80211_CONF_PS)
813 ath9k_hw_setpower(sc->sc_ah,
814 sc->sc_ah->ah_restore_mode);
815}
816#endif /* CORE_H */
diff --git a/drivers/net/wireless/ath9k/debug.c b/drivers/net/wireless/ath9k/debug.c
index 6181e49eecba..800ad5926b6f 100644
--- a/drivers/net/wireless/ath9k/debug.c
+++ b/drivers/net/wireless/ath9k/debug.c
@@ -14,9 +14,7 @@
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */ 15 */
16 16
17#include "core.h" 17#include "ath9k.h"
18#include "reg.h"
19#include "hw.h"
20 18
21static unsigned int ath9k_debug = DBG_DEFAULT; 19static unsigned int ath9k_debug = DBG_DEFAULT;
22module_param_named(debug, ath9k_debug, uint, 0); 20module_param_named(debug, ath9k_debug, uint, 0);
@@ -26,7 +24,7 @@ void DPRINTF(struct ath_softc *sc, int dbg_mask, const char *fmt, ...)
26 if (!sc) 24 if (!sc)
27 return; 25 return;
28 26
29 if (sc->sc_debug.debug_mask & dbg_mask) { 27 if (sc->debug.debug_mask & dbg_mask) {
30 va_list args; 28 va_list args;
31 29
32 va_start(args, fmt); 30 va_start(args, fmt);
@@ -46,7 +44,7 @@ static ssize_t read_file_dma(struct file *file, char __user *user_buf,
46 size_t count, loff_t *ppos) 44 size_t count, loff_t *ppos)
47{ 45{
48 struct ath_softc *sc = file->private_data; 46 struct ath_softc *sc = file->private_data;
49 struct ath_hal *ah = sc->sc_ah; 47 struct ath_hw *ah = sc->sc_ah;
50 char buf[1024]; 48 char buf[1024];
51 unsigned int len = 0; 49 unsigned int len = 0;
52 u32 val[ATH9K_NUM_DMA_DEBUG_REGS]; 50 u32 val[ATH9K_NUM_DMA_DEBUG_REGS];
@@ -132,41 +130,41 @@ static const struct file_operations fops_dma = {
132void ath_debug_stat_interrupt(struct ath_softc *sc, enum ath9k_int status) 130void ath_debug_stat_interrupt(struct ath_softc *sc, enum ath9k_int status)
133{ 131{
134 if (status) 132 if (status)
135 sc->sc_debug.stats.istats.total++; 133 sc->debug.stats.istats.total++;
136 if (status & ATH9K_INT_RX) 134 if (status & ATH9K_INT_RX)
137 sc->sc_debug.stats.istats.rxok++; 135 sc->debug.stats.istats.rxok++;
138 if (status & ATH9K_INT_RXEOL) 136 if (status & ATH9K_INT_RXEOL)
139 sc->sc_debug.stats.istats.rxeol++; 137 sc->debug.stats.istats.rxeol++;
140 if (status & ATH9K_INT_RXORN) 138 if (status & ATH9K_INT_RXORN)
141 sc->sc_debug.stats.istats.rxorn++; 139 sc->debug.stats.istats.rxorn++;
142 if (status & ATH9K_INT_TX) 140 if (status & ATH9K_INT_TX)
143 sc->sc_debug.stats.istats.txok++; 141 sc->debug.stats.istats.txok++;
144 if (status & ATH9K_INT_TXURN) 142 if (status & ATH9K_INT_TXURN)
145 sc->sc_debug.stats.istats.txurn++; 143 sc->debug.stats.istats.txurn++;
146 if (status & ATH9K_INT_MIB) 144 if (status & ATH9K_INT_MIB)
147 sc->sc_debug.stats.istats.mib++; 145 sc->debug.stats.istats.mib++;
148 if (status & ATH9K_INT_RXPHY) 146 if (status & ATH9K_INT_RXPHY)
149 sc->sc_debug.stats.istats.rxphyerr++; 147 sc->debug.stats.istats.rxphyerr++;
150 if (status & ATH9K_INT_RXKCM) 148 if (status & ATH9K_INT_RXKCM)
151 sc->sc_debug.stats.istats.rx_keycache_miss++; 149 sc->debug.stats.istats.rx_keycache_miss++;
152 if (status & ATH9K_INT_SWBA) 150 if (status & ATH9K_INT_SWBA)
153 sc->sc_debug.stats.istats.swba++; 151 sc->debug.stats.istats.swba++;
154 if (status & ATH9K_INT_BMISS) 152 if (status & ATH9K_INT_BMISS)
155 sc->sc_debug.stats.istats.bmiss++; 153 sc->debug.stats.istats.bmiss++;
156 if (status & ATH9K_INT_BNR) 154 if (status & ATH9K_INT_BNR)
157 sc->sc_debug.stats.istats.bnr++; 155 sc->debug.stats.istats.bnr++;
158 if (status & ATH9K_INT_CST) 156 if (status & ATH9K_INT_CST)
159 sc->sc_debug.stats.istats.cst++; 157 sc->debug.stats.istats.cst++;
160 if (status & ATH9K_INT_GTT) 158 if (status & ATH9K_INT_GTT)
161 sc->sc_debug.stats.istats.gtt++; 159 sc->debug.stats.istats.gtt++;
162 if (status & ATH9K_INT_TIM) 160 if (status & ATH9K_INT_TIM)
163 sc->sc_debug.stats.istats.tim++; 161 sc->debug.stats.istats.tim++;
164 if (status & ATH9K_INT_CABEND) 162 if (status & ATH9K_INT_CABEND)
165 sc->sc_debug.stats.istats.cabend++; 163 sc->debug.stats.istats.cabend++;
166 if (status & ATH9K_INT_DTIMSYNC) 164 if (status & ATH9K_INT_DTIMSYNC)
167 sc->sc_debug.stats.istats.dtimsync++; 165 sc->debug.stats.istats.dtimsync++;
168 if (status & ATH9K_INT_DTIM) 166 if (status & ATH9K_INT_DTIM)
169 sc->sc_debug.stats.istats.dtim++; 167 sc->debug.stats.istats.dtim++;
170} 168}
171 169
172static ssize_t read_file_interrupt(struct file *file, char __user *user_buf, 170static ssize_t read_file_interrupt(struct file *file, char __user *user_buf,
@@ -177,41 +175,41 @@ static ssize_t read_file_interrupt(struct file *file, char __user *user_buf,
177 unsigned int len = 0; 175 unsigned int len = 0;
178 176
179 len += snprintf(buf + len, sizeof(buf) - len, 177 len += snprintf(buf + len, sizeof(buf) - len,
180 "%8s: %10u\n", "RX", sc->sc_debug.stats.istats.rxok); 178 "%8s: %10u\n", "RX", sc->debug.stats.istats.rxok);
181 len += snprintf(buf + len, sizeof(buf) - len, 179 len += snprintf(buf + len, sizeof(buf) - len,
182 "%8s: %10u\n", "RXEOL", sc->sc_debug.stats.istats.rxeol); 180 "%8s: %10u\n", "RXEOL", sc->debug.stats.istats.rxeol);
183 len += snprintf(buf + len, sizeof(buf) - len, 181 len += snprintf(buf + len, sizeof(buf) - len,
184 "%8s: %10u\n", "RXORN", sc->sc_debug.stats.istats.rxorn); 182 "%8s: %10u\n", "RXORN", sc->debug.stats.istats.rxorn);
185 len += snprintf(buf + len, sizeof(buf) - len, 183 len += snprintf(buf + len, sizeof(buf) - len,
186 "%8s: %10u\n", "TX", sc->sc_debug.stats.istats.txok); 184 "%8s: %10u\n", "TX", sc->debug.stats.istats.txok);
187 len += snprintf(buf + len, sizeof(buf) - len, 185 len += snprintf(buf + len, sizeof(buf) - len,
188 "%8s: %10u\n", "TXURN", sc->sc_debug.stats.istats.txurn); 186 "%8s: %10u\n", "TXURN", sc->debug.stats.istats.txurn);
189 len += snprintf(buf + len, sizeof(buf) - len, 187 len += snprintf(buf + len, sizeof(buf) - len,
190 "%8s: %10u\n", "MIB", sc->sc_debug.stats.istats.mib); 188 "%8s: %10u\n", "MIB", sc->debug.stats.istats.mib);
191 len += snprintf(buf + len, sizeof(buf) - len, 189 len += snprintf(buf + len, sizeof(buf) - len,
192 "%8s: %10u\n", "RXPHY", sc->sc_debug.stats.istats.rxphyerr); 190 "%8s: %10u\n", "RXPHY", sc->debug.stats.istats.rxphyerr);
193 len += snprintf(buf + len, sizeof(buf) - len, 191 len += snprintf(buf + len, sizeof(buf) - len,
194 "%8s: %10u\n", "RXKCM", sc->sc_debug.stats.istats.rx_keycache_miss); 192 "%8s: %10u\n", "RXKCM", sc->debug.stats.istats.rx_keycache_miss);
195 len += snprintf(buf + len, sizeof(buf) - len, 193 len += snprintf(buf + len, sizeof(buf) - len,
196 "%8s: %10u\n", "SWBA", sc->sc_debug.stats.istats.swba); 194 "%8s: %10u\n", "SWBA", sc->debug.stats.istats.swba);
197 len += snprintf(buf + len, sizeof(buf) - len, 195 len += snprintf(buf + len, sizeof(buf) - len,
198 "%8s: %10u\n", "BMISS", sc->sc_debug.stats.istats.bmiss); 196 "%8s: %10u\n", "BMISS", sc->debug.stats.istats.bmiss);
199 len += snprintf(buf + len, sizeof(buf) - len, 197 len += snprintf(buf + len, sizeof(buf) - len,
200 "%8s: %10u\n", "BNR", sc->sc_debug.stats.istats.bnr); 198 "%8s: %10u\n", "BNR", sc->debug.stats.istats.bnr);
201 len += snprintf(buf + len, sizeof(buf) - len, 199 len += snprintf(buf + len, sizeof(buf) - len,
202 "%8s: %10u\n", "CST", sc->sc_debug.stats.istats.cst); 200 "%8s: %10u\n", "CST", sc->debug.stats.istats.cst);
203 len += snprintf(buf + len, sizeof(buf) - len, 201 len += snprintf(buf + len, sizeof(buf) - len,
204 "%8s: %10u\n", "GTT", sc->sc_debug.stats.istats.gtt); 202 "%8s: %10u\n", "GTT", sc->debug.stats.istats.gtt);
205 len += snprintf(buf + len, sizeof(buf) - len, 203 len += snprintf(buf + len, sizeof(buf) - len,
206 "%8s: %10u\n", "TIM", sc->sc_debug.stats.istats.tim); 204 "%8s: %10u\n", "TIM", sc->debug.stats.istats.tim);
207 len += snprintf(buf + len, sizeof(buf) - len, 205 len += snprintf(buf + len, sizeof(buf) - len,
208 "%8s: %10u\n", "CABEND", sc->sc_debug.stats.istats.cabend); 206 "%8s: %10u\n", "CABEND", sc->debug.stats.istats.cabend);
209 len += snprintf(buf + len, sizeof(buf) - len, 207 len += snprintf(buf + len, sizeof(buf) - len,
210 "%8s: %10u\n", "DTIMSYNC", sc->sc_debug.stats.istats.dtimsync); 208 "%8s: %10u\n", "DTIMSYNC", sc->debug.stats.istats.dtimsync);
211 len += snprintf(buf + len, sizeof(buf) - len, 209 len += snprintf(buf + len, sizeof(buf) - len,
212 "%8s: %10u\n", "DTIM", sc->sc_debug.stats.istats.dtim); 210 "%8s: %10u\n", "DTIM", sc->debug.stats.istats.dtim);
213 len += snprintf(buf + len, sizeof(buf) - len, 211 len += snprintf(buf + len, sizeof(buf) - len,
214 "%8s: %10u\n", "TOTAL", sc->sc_debug.stats.istats.total); 212 "%8s: %10u\n", "TOTAL", sc->debug.stats.istats.total);
215 213
216 return simple_read_from_buffer(user_buf, count, ppos, buf, len); 214 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
217} 215}
@@ -233,7 +231,7 @@ static void ath_debug_stat_11n_rc(struct ath_softc *sc, struct sk_buff *skb)
233 final_ts_idx = tx_info_priv->tx.ts_rateindex; 231 final_ts_idx = tx_info_priv->tx.ts_rateindex;
234 idx = sc->cur_rate_table->info[rates[final_ts_idx].idx].dot11rate; 232 idx = sc->cur_rate_table->info[rates[final_ts_idx].idx].dot11rate;
235 233
236 sc->sc_debug.stats.n_rcstats[idx].success++; 234 sc->debug.stats.n_rcstats[idx].success++;
237} 235}
238 236
239static void ath_debug_stat_legacy_rc(struct ath_softc *sc, struct sk_buff *skb) 237static void ath_debug_stat_legacy_rc(struct ath_softc *sc, struct sk_buff *skb)
@@ -247,7 +245,7 @@ static void ath_debug_stat_legacy_rc(struct ath_softc *sc, struct sk_buff *skb)
247 final_ts_idx = tx_info_priv->tx.ts_rateindex; 245 final_ts_idx = tx_info_priv->tx.ts_rateindex;
248 idx = rates[final_ts_idx].idx; 246 idx = rates[final_ts_idx].idx;
249 247
250 sc->sc_debug.stats.legacy_rcstats[idx].success++; 248 sc->debug.stats.legacy_rcstats[idx].success++;
251} 249}
252 250
253void ath_debug_stat_rc(struct ath_softc *sc, struct sk_buff *skb) 251void ath_debug_stat_rc(struct ath_softc *sc, struct sk_buff *skb)
@@ -258,21 +256,36 @@ void ath_debug_stat_rc(struct ath_softc *sc, struct sk_buff *skb)
258 ath_debug_stat_legacy_rc(sc, skb); 256 ath_debug_stat_legacy_rc(sc, skb);
259} 257}
260 258
259/* FIXME: legacy rates, later on .. */
260void ath_debug_stat_retries(struct ath_softc *sc, int rix,
261 int xretries, int retries)
262{
263 if (conf_is_ht(&sc->hw->conf)) {
264 int idx = sc->cur_rate_table->info[rix].dot11rate;
265
266 sc->debug.stats.n_rcstats[idx].xretries += xretries;
267 sc->debug.stats.n_rcstats[idx].retries += retries;
268 }
269}
270
261static ssize_t ath_read_file_stat_11n_rc(struct file *file, 271static ssize_t ath_read_file_stat_11n_rc(struct file *file,
262 char __user *user_buf, 272 char __user *user_buf,
263 size_t count, loff_t *ppos) 273 size_t count, loff_t *ppos)
264{ 274{
265 struct ath_softc *sc = file->private_data; 275 struct ath_softc *sc = file->private_data;
266 char buf[512]; 276 char buf[1024];
267 unsigned int len = 0; 277 unsigned int len = 0;
268 int i = 0; 278 int i = 0;
269 279
270 len += sprintf(buf, "%7s %13s\n\n", "Rate", "Success"); 280 len += sprintf(buf, "%7s %13s %8s %8s\n\n", "Rate", "Success",
281 "Retries", "XRetries");
271 282
272 for (i = 0; i <= 15; i++) { 283 for (i = 0; i <= 15; i++) {
273 len += snprintf(buf + len, sizeof(buf) - len, 284 len += snprintf(buf + len, sizeof(buf) - len,
274 "%5s%3d: %8u\n", "MCS", i, 285 "%5s%3d: %8u %8u %8u\n", "MCS", i,
275 sc->sc_debug.stats.n_rcstats[i].success); 286 sc->debug.stats.n_rcstats[i].success,
287 sc->debug.stats.n_rcstats[i].retries,
288 sc->debug.stats.n_rcstats[i].xretries);
276 } 289 }
277 290
278 return simple_read_from_buffer(user_buf, count, ppos, buf, len); 291 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
@@ -292,7 +305,7 @@ static ssize_t ath_read_file_stat_legacy_rc(struct file *file,
292 for (i = 0; i < sc->cur_rate_table->rate_cnt; i++) { 305 for (i = 0; i < sc->cur_rate_table->rate_cnt; i++) {
293 len += snprintf(buf + len, sizeof(buf) - len, "%5u: %12u\n", 306 len += snprintf(buf + len, sizeof(buf) - len, "%5u: %12u\n",
294 sc->cur_rate_table->info[i].ratekbps / 1000, 307 sc->cur_rate_table->info[i].ratekbps / 1000,
295 sc->sc_debug.stats.legacy_rcstats[i].success); 308 sc->debug.stats.legacy_rcstats[i].success);
296 } 309 }
297 310
298 return simple_read_from_buffer(user_buf, count, ppos, buf, len); 311 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
@@ -317,34 +330,34 @@ static const struct file_operations fops_rcstat = {
317 330
318int ath9k_init_debug(struct ath_softc *sc) 331int ath9k_init_debug(struct ath_softc *sc)
319{ 332{
320 sc->sc_debug.debug_mask = ath9k_debug; 333 sc->debug.debug_mask = ath9k_debug;
321 334
322 sc->sc_debug.debugfs_root = debugfs_create_dir(KBUILD_MODNAME, NULL); 335 sc->debug.debugfs_root = debugfs_create_dir(KBUILD_MODNAME, NULL);
323 if (!sc->sc_debug.debugfs_root) 336 if (!sc->debug.debugfs_root)
324 goto err; 337 goto err;
325 338
326 sc->sc_debug.debugfs_phy = debugfs_create_dir(wiphy_name(sc->hw->wiphy), 339 sc->debug.debugfs_phy = debugfs_create_dir(wiphy_name(sc->hw->wiphy),
327 sc->sc_debug.debugfs_root); 340 sc->debug.debugfs_root);
328 if (!sc->sc_debug.debugfs_phy) 341 if (!sc->debug.debugfs_phy)
329 goto err; 342 goto err;
330 343
331 sc->sc_debug.debugfs_dma = debugfs_create_file("dma", S_IRUGO, 344 sc->debug.debugfs_dma = debugfs_create_file("dma", S_IRUGO,
332 sc->sc_debug.debugfs_phy, sc, &fops_dma); 345 sc->debug.debugfs_phy, sc, &fops_dma);
333 if (!sc->sc_debug.debugfs_dma) 346 if (!sc->debug.debugfs_dma)
334 goto err; 347 goto err;
335 348
336 sc->sc_debug.debugfs_interrupt = debugfs_create_file("interrupt", 349 sc->debug.debugfs_interrupt = debugfs_create_file("interrupt",
337 S_IRUGO, 350 S_IRUGO,
338 sc->sc_debug.debugfs_phy, 351 sc->debug.debugfs_phy,
339 sc, &fops_interrupt); 352 sc, &fops_interrupt);
340 if (!sc->sc_debug.debugfs_interrupt) 353 if (!sc->debug.debugfs_interrupt)
341 goto err; 354 goto err;
342 355
343 sc->sc_debug.debugfs_rcstat = debugfs_create_file("rcstat", 356 sc->debug.debugfs_rcstat = debugfs_create_file("rcstat",
344 S_IRUGO, 357 S_IRUGO,
345 sc->sc_debug.debugfs_phy, 358 sc->debug.debugfs_phy,
346 sc, &fops_rcstat); 359 sc, &fops_rcstat);
347 if (!sc->sc_debug.debugfs_rcstat) 360 if (!sc->debug.debugfs_rcstat)
348 goto err; 361 goto err;
349 362
350 return 0; 363 return 0;
@@ -355,9 +368,9 @@ err:
355 368
356void ath9k_exit_debug(struct ath_softc *sc) 369void ath9k_exit_debug(struct ath_softc *sc)
357{ 370{
358 debugfs_remove(sc->sc_debug.debugfs_rcstat); 371 debugfs_remove(sc->debug.debugfs_rcstat);
359 debugfs_remove(sc->sc_debug.debugfs_interrupt); 372 debugfs_remove(sc->debug.debugfs_interrupt);
360 debugfs_remove(sc->sc_debug.debugfs_dma); 373 debugfs_remove(sc->debug.debugfs_dma);
361 debugfs_remove(sc->sc_debug.debugfs_phy); 374 debugfs_remove(sc->debug.debugfs_phy);
362 debugfs_remove(sc->sc_debug.debugfs_root); 375 debugfs_remove(sc->debug.debugfs_root);
363} 376}
diff --git a/drivers/net/wireless/ath9k/debug.h b/drivers/net/wireless/ath9k/debug.h
new file mode 100644
index 000000000000..61e969894c0a
--- /dev/null
+++ b/drivers/net/wireless/ath9k/debug.h
@@ -0,0 +1,153 @@
1/*
2 * Copyright (c) 2008 Atheros Communications Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#ifndef DEBUG_H
18#define DEBUG_H
19
20enum ATH_DEBUG {
21 ATH_DBG_RESET = 0x00000001,
22 ATH_DBG_REG_IO = 0x00000002,
23 ATH_DBG_QUEUE = 0x00000004,
24 ATH_DBG_EEPROM = 0x00000008,
25 ATH_DBG_CALIBRATE = 0x00000010,
26 ATH_DBG_CHANNEL = 0x00000020,
27 ATH_DBG_INTERRUPT = 0x00000040,
28 ATH_DBG_REGULATORY = 0x00000080,
29 ATH_DBG_ANI = 0x00000100,
30 ATH_DBG_POWER_MGMT = 0x00000200,
31 ATH_DBG_XMIT = 0x00000400,
32 ATH_DBG_BEACON = 0x00001000,
33 ATH_DBG_CONFIG = 0x00002000,
34 ATH_DBG_KEYCACHE = 0x00004000,
35 ATH_DBG_FATAL = 0x00008000,
36 ATH_DBG_ANY = 0xffffffff
37};
38
39#define DBG_DEFAULT (ATH_DBG_FATAL)
40
41#ifdef CONFIG_ATH9K_DEBUG
42
43/**
44 * struct ath_interrupt_stats - Contains statistics about interrupts
45 * @total: Total no. of interrupts generated so far
46 * @rxok: RX with no errors
47 * @rxeol: RX with no more RXDESC available
48 * @rxorn: RX FIFO overrun
49 * @txok: TX completed at the requested rate
50 * @txurn: TX FIFO underrun
51 * @mib: MIB regs reaching its threshold
52 * @rxphyerr: RX with phy errors
53 * @rx_keycache_miss: RX with key cache misses
54 * @swba: Software Beacon Alert
55 * @bmiss: Beacon Miss
56 * @bnr: Beacon Not Ready
57 * @cst: Carrier Sense TImeout
58 * @gtt: Global TX Timeout
59 * @tim: RX beacon TIM occurrence
60 * @cabend: RX End of CAB traffic
61 * @dtimsync: DTIM sync lossage
62 * @dtim: RX Beacon with DTIM
63 */
64struct ath_interrupt_stats {
65 u32 total;
66 u32 rxok;
67 u32 rxeol;
68 u32 rxorn;
69 u32 txok;
70 u32 txeol;
71 u32 txurn;
72 u32 mib;
73 u32 rxphyerr;
74 u32 rx_keycache_miss;
75 u32 swba;
76 u32 bmiss;
77 u32 bnr;
78 u32 cst;
79 u32 gtt;
80 u32 tim;
81 u32 cabend;
82 u32 dtimsync;
83 u32 dtim;
84};
85
86struct ath_legacy_rc_stats {
87 u32 success;
88};
89
90struct ath_11n_rc_stats {
91 u32 success;
92 u32 retries;
93 u32 xretries;
94};
95
96struct ath_stats {
97 struct ath_interrupt_stats istats;
98 struct ath_legacy_rc_stats legacy_rcstats[12]; /* max(11a,11b,11g) */
99 struct ath_11n_rc_stats n_rcstats[16]; /* 0..15 MCS rates */
100};
101
102struct ath9k_debug {
103 int debug_mask;
104 struct dentry *debugfs_root;
105 struct dentry *debugfs_phy;
106 struct dentry *debugfs_dma;
107 struct dentry *debugfs_interrupt;
108 struct dentry *debugfs_rcstat;
109 struct ath_stats stats;
110};
111
112void DPRINTF(struct ath_softc *sc, int dbg_mask, const char *fmt, ...);
113int ath9k_init_debug(struct ath_softc *sc);
114void ath9k_exit_debug(struct ath_softc *sc);
115void ath_debug_stat_interrupt(struct ath_softc *sc, enum ath9k_int status);
116void ath_debug_stat_rc(struct ath_softc *sc, struct sk_buff *skb);
117void ath_debug_stat_retries(struct ath_softc *sc, int rix,
118 int xretries, int retries);
119
120#else
121
122static inline void DPRINTF(struct ath_softc *sc, int dbg_mask,
123 const char *fmt, ...)
124{
125}
126
127static inline int ath9k_init_debug(struct ath_softc *sc)
128{
129 return 0;
130}
131
132static inline void ath9k_exit_debug(struct ath_softc *sc)
133{
134}
135
136static inline void ath_debug_stat_interrupt(struct ath_softc *sc,
137 enum ath9k_int status)
138{
139}
140
141static inline void ath_debug_stat_rc(struct ath_softc *sc,
142 struct sk_buff *skb)
143{
144}
145
146static inline void ath_debug_stat_retries(struct ath_softc *sc, int rix,
147 int xretries, int retries)
148{
149}
150
151#endif /* CONFIG_ATH9K_DEBUG */
152
153#endif /* DEBUG_H */
diff --git a/drivers/net/wireless/ath9k/eeprom.c b/drivers/net/wireless/ath9k/eeprom.c
index 5038907e7432..c0359ad2bc7b 100644
--- a/drivers/net/wireless/ath9k/eeprom.c
+++ b/drivers/net/wireless/ath9k/eeprom.c
@@ -14,12 +14,9 @@
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */ 15 */
16 16
17#include "core.h" 17#include "ath9k.h"
18#include "hw.h"
19#include "reg.h"
20#include "phy.h"
21 18
22static void ath9k_hw_analog_shift_rmw(struct ath_hal *ah, 19static void ath9k_hw_analog_shift_rmw(struct ath_hw *ah,
23 u32 reg, u32 mask, 20 u32 reg, u32 mask,
24 u32 shift, u32 val) 21 u32 shift, u32 val)
25{ 22{
@@ -30,7 +27,7 @@ static void ath9k_hw_analog_shift_rmw(struct ath_hal *ah,
30 27
31 REG_WRITE(ah, reg, regVal); 28 REG_WRITE(ah, reg, regVal);
32 29
33 if (ah->ah_config.analog_shiftreg) 30 if (ah->config.analog_shiftreg)
34 udelay(100); 31 udelay(100);
35 32
36 return; 33 return;
@@ -91,212 +88,227 @@ static inline bool ath9k_hw_get_lower_upper_index(u8 target, u8 *pList,
91 return false; 88 return false;
92} 89}
93 90
94static inline bool ath9k_hw_nvram_read(struct ath_hal *ah, u32 off, u16 *data) 91static inline bool ath9k_hw_nvram_read(struct ath_hw *ah, u32 off, u16 *data)
95{ 92{
96 struct ath_softc *sc = ah->ah_sc; 93 struct ath_softc *sc = ah->ah_sc;
97 94
98 return sc->bus_ops->eeprom_read(ah, off, data); 95 return sc->bus_ops->eeprom_read(ah, off, data);
99} 96}
100 97
101static bool ath9k_hw_fill_4k_eeprom(struct ath_hal *ah) 98static inline bool ath9k_hw_fill_vpd_table(u8 pwrMin, u8 pwrMax, u8 *pPwrList,
99 u8 *pVpdList, u16 numIntercepts,
100 u8 *pRetVpdList)
102{ 101{
103#define SIZE_EEPROM_4K (sizeof(struct ar5416_eeprom_4k) / sizeof(u16)) 102 u16 i, k;
104 struct ath_hal_5416 *ahp = AH5416(ah); 103 u8 currPwr = pwrMin;
105 struct ar5416_eeprom_4k *eep = &ahp->ah_eeprom.map4k; 104 u16 idxL = 0, idxR = 0;
106 u16 *eep_data;
107 int addr, eep_start_loc = 0;
108
109 eep_start_loc = 64;
110 105
111 if (!ath9k_hw_use_flash(ah)) { 106 for (i = 0; i <= (pwrMax - pwrMin) / 2; i++) {
112 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, 107 ath9k_hw_get_lower_upper_index(currPwr, pPwrList,
113 "Reading from EEPROM, not flash\n"); 108 numIntercepts, &(idxL),
109 &(idxR));
110 if (idxR < 1)
111 idxR = 1;
112 if (idxL == numIntercepts - 1)
113 idxL = (u16) (numIntercepts - 2);
114 if (pPwrList[idxL] == pPwrList[idxR])
115 k = pVpdList[idxL];
116 else
117 k = (u16)(((currPwr - pPwrList[idxL]) * pVpdList[idxR] +
118 (pPwrList[idxR] - currPwr) * pVpdList[idxL]) /
119 (pPwrList[idxR] - pPwrList[idxL]));
120 pRetVpdList[i] = (u8) k;
121 currPwr += 2;
114 } 122 }
115 123
116 eep_data = (u16 *)eep;
117
118 for (addr = 0; addr < SIZE_EEPROM_4K; addr++) {
119 if (!ath9k_hw_nvram_read(ah, addr + eep_start_loc, eep_data)) {
120 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
121 "Unable to read eeprom region \n");
122 return false;
123 }
124 eep_data++;
125 }
126 return true; 124 return true;
127#undef SIZE_EEPROM_4K
128} 125}
129 126
130static bool ath9k_hw_fill_def_eeprom(struct ath_hal *ah) 127static void ath9k_hw_get_legacy_target_powers(struct ath_hw *ah,
128 struct ath9k_channel *chan,
129 struct cal_target_power_leg *powInfo,
130 u16 numChannels,
131 struct cal_target_power_leg *pNewPower,
132 u16 numRates, bool isExtTarget)
131{ 133{
132#define SIZE_EEPROM_DEF (sizeof(struct ar5416_eeprom_def) / sizeof(u16)) 134 struct chan_centers centers;
133 struct ath_hal_5416 *ahp = AH5416(ah); 135 u16 clo, chi;
134 struct ar5416_eeprom_def *eep = &ahp->ah_eeprom.def; 136 int i;
135 u16 *eep_data; 137 int matchIndex = -1, lowIndex = -1;
136 int addr, ar5416_eep_start_loc = 0x100; 138 u16 freq;
137 139
138 eep_data = (u16 *)eep; 140 ath9k_hw_get_channel_centers(ah, chan, &centers);
141 freq = (isExtTarget) ? centers.ext_center : centers.ctl_center;
139 142
140 for (addr = 0; addr < SIZE_EEPROM_DEF; addr++) { 143 if (freq <= ath9k_hw_fbin2freq(powInfo[0].bChannel,
141 if (!ath9k_hw_nvram_read(ah, addr + ar5416_eep_start_loc, 144 IS_CHAN_2GHZ(chan))) {
142 eep_data)) { 145 matchIndex = 0;
143 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, 146 } else {
144 "Unable to read eeprom region\n"); 147 for (i = 0; (i < numChannels) &&
145 return false; 148 (powInfo[i].bChannel != AR5416_BCHAN_UNUSED); i++) {
149 if (freq == ath9k_hw_fbin2freq(powInfo[i].bChannel,
150 IS_CHAN_2GHZ(chan))) {
151 matchIndex = i;
152 break;
153 } else if ((freq < ath9k_hw_fbin2freq(powInfo[i].bChannel,
154 IS_CHAN_2GHZ(chan))) &&
155 (freq > ath9k_hw_fbin2freq(powInfo[i - 1].bChannel,
156 IS_CHAN_2GHZ(chan)))) {
157 lowIndex = i - 1;
158 break;
159 }
146 } 160 }
147 eep_data++; 161 if ((matchIndex == -1) && (lowIndex == -1))
162 matchIndex = i - 1;
148 } 163 }
149 return true;
150#undef SIZE_EEPROM_DEF
151}
152 164
153static bool (*ath9k_fill_eeprom[]) (struct ath_hal *) = { 165 if (matchIndex != -1) {
154 ath9k_hw_fill_def_eeprom, 166 *pNewPower = powInfo[matchIndex];
155 ath9k_hw_fill_4k_eeprom 167 } else {
156}; 168 clo = ath9k_hw_fbin2freq(powInfo[lowIndex].bChannel,
157 169 IS_CHAN_2GHZ(chan));
158static inline bool ath9k_hw_fill_eeprom(struct ath_hal *ah) 170 chi = ath9k_hw_fbin2freq(powInfo[lowIndex + 1].bChannel,
159{ 171 IS_CHAN_2GHZ(chan));
160 struct ath_hal_5416 *ahp = AH5416(ah);
161 172
162 return ath9k_fill_eeprom[ahp->ah_eep_map](ah); 173 for (i = 0; i < numRates; i++) {
174 pNewPower->tPow2x[i] =
175 (u8)ath9k_hw_interpolate(freq, clo, chi,
176 powInfo[lowIndex].tPow2x[i],
177 powInfo[lowIndex + 1].tPow2x[i]);
178 }
179 }
163} 180}
164 181
165static int ath9k_hw_check_def_eeprom(struct ath_hal *ah) 182static void ath9k_hw_get_target_powers(struct ath_hw *ah,
183 struct ath9k_channel *chan,
184 struct cal_target_power_ht *powInfo,
185 u16 numChannels,
186 struct cal_target_power_ht *pNewPower,
187 u16 numRates, bool isHt40Target)
166{ 188{
167 struct ath_hal_5416 *ahp = AH5416(ah); 189 struct chan_centers centers;
168 struct ar5416_eeprom_def *eep = 190 u16 clo, chi;
169 (struct ar5416_eeprom_def *) &ahp->ah_eeprom.def; 191 int i;
170 u16 *eepdata, temp, magic, magic2; 192 int matchIndex = -1, lowIndex = -1;
171 u32 sum = 0, el; 193 u16 freq;
172 bool need_swap = false;
173 int i, addr, size;
174
175 if (!ath9k_hw_nvram_read(ah, AR5416_EEPROM_MAGIC_OFFSET,
176 &magic)) {
177 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
178 "Reading Magic # failed\n");
179 return false;
180 }
181
182 if (!ath9k_hw_use_flash(ah)) {
183 194
184 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, 195 ath9k_hw_get_channel_centers(ah, chan, &centers);
185 "Read Magic = 0x%04X\n", magic); 196 freq = isHt40Target ? centers.synth_center : centers.ctl_center;
186 197
187 if (magic != AR5416_EEPROM_MAGIC) { 198 if (freq <= ath9k_hw_fbin2freq(powInfo[0].bChannel, IS_CHAN_2GHZ(chan))) {
188 magic2 = swab16(magic); 199 matchIndex = 0;
200 } else {
201 for (i = 0; (i < numChannels) &&
202 (powInfo[i].bChannel != AR5416_BCHAN_UNUSED); i++) {
203 if (freq == ath9k_hw_fbin2freq(powInfo[i].bChannel,
204 IS_CHAN_2GHZ(chan))) {
205 matchIndex = i;
206 break;
207 } else
208 if ((freq < ath9k_hw_fbin2freq(powInfo[i].bChannel,
209 IS_CHAN_2GHZ(chan))) &&
210 (freq > ath9k_hw_fbin2freq(powInfo[i - 1].bChannel,
211 IS_CHAN_2GHZ(chan)))) {
212 lowIndex = i - 1;
213 break;
214 }
215 }
216 if ((matchIndex == -1) && (lowIndex == -1))
217 matchIndex = i - 1;
218 }
189 219
190 if (magic2 == AR5416_EEPROM_MAGIC) { 220 if (matchIndex != -1) {
191 size = sizeof(struct ar5416_eeprom_def); 221 *pNewPower = powInfo[matchIndex];
192 need_swap = true; 222 } else {
193 eepdata = (u16 *) (&ahp->ah_eeprom); 223 clo = ath9k_hw_fbin2freq(powInfo[lowIndex].bChannel,
224 IS_CHAN_2GHZ(chan));
225 chi = ath9k_hw_fbin2freq(powInfo[lowIndex + 1].bChannel,
226 IS_CHAN_2GHZ(chan));
194 227
195 for (addr = 0; addr < size / sizeof(u16); addr++) { 228 for (i = 0; i < numRates; i++) {
196 temp = swab16(*eepdata); 229 pNewPower->tPow2x[i] = (u8)ath9k_hw_interpolate(freq,
197 *eepdata = temp; 230 clo, chi,
198 eepdata++; 231 powInfo[lowIndex].tPow2x[i],
232 powInfo[lowIndex + 1].tPow2x[i]);
233 }
234 }
235}
199 236
200 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, 237static u16 ath9k_hw_get_max_edge_power(u16 freq,
201 "0x%04X ", *eepdata); 238 struct cal_ctl_edges *pRdEdgesPower,
239 bool is2GHz, int num_band_edges)
240{
241 u16 twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
242 int i;
202 243
203 if (((addr + 1) % 6) == 0) 244 for (i = 0; (i < num_band_edges) &&
204 DPRINTF(ah->ah_sc, 245 (pRdEdgesPower[i].bChannel != AR5416_BCHAN_UNUSED); i++) {
205 ATH_DBG_EEPROM, "\n"); 246 if (freq == ath9k_hw_fbin2freq(pRdEdgesPower[i].bChannel, is2GHz)) {
206 } 247 twiceMaxEdgePower = pRdEdgesPower[i].tPower;
207 } else { 248 break;
208 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, 249 } else if ((i > 0) &&
209 "Invalid EEPROM Magic. " 250 (freq < ath9k_hw_fbin2freq(pRdEdgesPower[i].bChannel,
210 "endianness mismatch.\n"); 251 is2GHz))) {
211 return -EINVAL; 252 if (ath9k_hw_fbin2freq(pRdEdgesPower[i - 1].bChannel,
253 is2GHz) < freq &&
254 pRdEdgesPower[i - 1].flag) {
255 twiceMaxEdgePower =
256 pRdEdgesPower[i - 1].tPower;
212 } 257 }
258 break;
213 } 259 }
214 } 260 }
215 261
216 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, "need_swap = %s.\n", 262 return twiceMaxEdgePower;
217 need_swap ? "True" : "False"); 263}
218 264
219 if (need_swap) 265/****************************************/
220 el = swab16(ahp->ah_eeprom.def.baseEepHeader.length); 266/* EEPROM Operations for 4K sized cards */
221 else 267/****************************************/
222 el = ahp->ah_eeprom.def.baseEepHeader.length;
223 268
224 if (el > sizeof(struct ar5416_eeprom_def)) 269static int ath9k_hw_4k_get_eeprom_ver(struct ath_hw *ah)
225 el = sizeof(struct ar5416_eeprom_def) / sizeof(u16); 270{
226 else 271 return ((ah->eeprom.map4k.baseEepHeader.version >> 12) & 0xF);
227 el = el / sizeof(u16); 272}
228 273
229 eepdata = (u16 *)(&ahp->ah_eeprom); 274static int ath9k_hw_4k_get_eeprom_rev(struct ath_hw *ah)
275{
276 return ((ah->eeprom.map4k.baseEepHeader.version) & 0xFFF);
277}
230 278
231 for (i = 0; i < el; i++) 279static bool ath9k_hw_4k_fill_eeprom(struct ath_hw *ah)
232 sum ^= *eepdata++; 280{
281#define SIZE_EEPROM_4K (sizeof(struct ar5416_eeprom_4k) / sizeof(u16))
282 struct ar5416_eeprom_4k *eep = &ah->eeprom.map4k;
283 u16 *eep_data;
284 int addr, eep_start_loc = 0;
233 285
234 if (need_swap) { 286 eep_start_loc = 64;
235 u32 integer, j;
236 u16 word;
237 287
288 if (!ath9k_hw_use_flash(ah)) {
238 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, 289 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
239 "EEPROM Endianness is not native.. Changing \n"); 290 "Reading from EEPROM, not flash\n");
240 291 }
241 word = swab16(eep->baseEepHeader.length);
242 eep->baseEepHeader.length = word;
243
244 word = swab16(eep->baseEepHeader.checksum);
245 eep->baseEepHeader.checksum = word;
246
247 word = swab16(eep->baseEepHeader.version);
248 eep->baseEepHeader.version = word;
249
250 word = swab16(eep->baseEepHeader.regDmn[0]);
251 eep->baseEepHeader.regDmn[0] = word;
252
253 word = swab16(eep->baseEepHeader.regDmn[1]);
254 eep->baseEepHeader.regDmn[1] = word;
255
256 word = swab16(eep->baseEepHeader.rfSilent);
257 eep->baseEepHeader.rfSilent = word;
258
259 word = swab16(eep->baseEepHeader.blueToothOptions);
260 eep->baseEepHeader.blueToothOptions = word;
261
262 word = swab16(eep->baseEepHeader.deviceCap);
263 eep->baseEepHeader.deviceCap = word;
264
265 for (j = 0; j < ARRAY_SIZE(eep->modalHeader); j++) {
266 struct modal_eep_header *pModal =
267 &eep->modalHeader[j];
268 integer = swab32(pModal->antCtrlCommon);
269 pModal->antCtrlCommon = integer;
270 292
271 for (i = 0; i < AR5416_MAX_CHAINS; i++) { 293 eep_data = (u16 *)eep;
272 integer = swab32(pModal->antCtrlChain[i]);
273 pModal->antCtrlChain[i] = integer;
274 }
275 294
276 for (i = 0; i < AR5416_EEPROM_MODAL_SPURS; i++) { 295 for (addr = 0; addr < SIZE_EEPROM_4K; addr++) {
277 word = swab16(pModal->spurChans[i].spurChan); 296 if (!ath9k_hw_nvram_read(ah, addr + eep_start_loc, eep_data)) {
278 pModal->spurChans[i].spurChan = word; 297 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
279 } 298 "Unable to read eeprom region \n");
299 return false;
280 } 300 }
301 eep_data++;
281 } 302 }
282 303 return true;
283 if (sum != 0xffff || ar5416_get_eep_ver(ahp) != AR5416_EEP_VER || 304#undef SIZE_EEPROM_4K
284 ar5416_get_eep_rev(ahp) < AR5416_EEP_NO_BACK_VER) {
285 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
286 "Bad EEPROM checksum 0x%x or revision 0x%04x\n",
287 sum, ar5416_get_eep_ver(ahp));
288 return -EINVAL;
289 }
290
291 return 0;
292} 305}
293 306
294static int ath9k_hw_check_4k_eeprom(struct ath_hal *ah) 307static int ath9k_hw_4k_check_eeprom(struct ath_hw *ah)
295{ 308{
296#define EEPROM_4K_SIZE (sizeof(struct ar5416_eeprom_4k) / sizeof(u16)) 309#define EEPROM_4K_SIZE (sizeof(struct ar5416_eeprom_4k) / sizeof(u16))
297 struct ath_hal_5416 *ahp = AH5416(ah);
298 struct ar5416_eeprom_4k *eep = 310 struct ar5416_eeprom_4k *eep =
299 (struct ar5416_eeprom_4k *) &ahp->ah_eeprom.map4k; 311 (struct ar5416_eeprom_4k *) &ah->eeprom.map4k;
300 u16 *eepdata, temp, magic, magic2; 312 u16 *eepdata, temp, magic, magic2;
301 u32 sum = 0, el; 313 u32 sum = 0, el;
302 bool need_swap = false; 314 bool need_swap = false;
@@ -320,7 +332,7 @@ static int ath9k_hw_check_4k_eeprom(struct ath_hal *ah)
320 332
321 if (magic2 == AR5416_EEPROM_MAGIC) { 333 if (magic2 == AR5416_EEPROM_MAGIC) {
322 need_swap = true; 334 need_swap = true;
323 eepdata = (u16 *) (&ahp->ah_eeprom); 335 eepdata = (u16 *) (&ah->eeprom);
324 336
325 for (addr = 0; addr < EEPROM_4K_SIZE; addr++) { 337 for (addr = 0; addr < EEPROM_4K_SIZE; addr++) {
326 temp = swab16(*eepdata); 338 temp = swab16(*eepdata);
@@ -347,16 +359,16 @@ static int ath9k_hw_check_4k_eeprom(struct ath_hal *ah)
347 need_swap ? "True" : "False"); 359 need_swap ? "True" : "False");
348 360
349 if (need_swap) 361 if (need_swap)
350 el = swab16(ahp->ah_eeprom.map4k.baseEepHeader.length); 362 el = swab16(ah->eeprom.map4k.baseEepHeader.length);
351 else 363 else
352 el = ahp->ah_eeprom.map4k.baseEepHeader.length; 364 el = ah->eeprom.map4k.baseEepHeader.length;
353 365
354 if (el > sizeof(struct ar5416_eeprom_def)) 366 if (el > sizeof(struct ar5416_eeprom_def))
355 el = sizeof(struct ar5416_eeprom_4k) / sizeof(u16); 367 el = sizeof(struct ar5416_eeprom_4k) / sizeof(u16);
356 else 368 else
357 el = el / sizeof(u16); 369 el = el / sizeof(u16);
358 370
359 eepdata = (u16 *)(&ahp->ah_eeprom); 371 eepdata = (u16 *)(&ah->eeprom);
360 372
361 for (i = 0; i < el; i++) 373 for (i = 0; i < el; i++)
362 sum ^= *eepdata++; 374 sum ^= *eepdata++;
@@ -406,11 +418,11 @@ static int ath9k_hw_check_4k_eeprom(struct ath_hal *ah)
406 } 418 }
407 } 419 }
408 420
409 if (sum != 0xffff || ar5416_get_eep4k_ver(ahp) != AR5416_EEP_VER || 421 if (sum != 0xffff || ah->eep_ops->get_eeprom_ver(ah) != AR5416_EEP_VER ||
410 ar5416_get_eep4k_rev(ahp) < AR5416_EEP_NO_BACK_VER) { 422 ah->eep_ops->get_eeprom_rev(ah) < AR5416_EEP_NO_BACK_VER) {
411 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, 423 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
412 "Bad EEPROM checksum 0x%x or revision 0x%04x\n", 424 "Bad EEPROM checksum 0x%x or revision 0x%04x\n",
413 sum, ar5416_get_eep4k_ver(ahp)); 425 sum, ah->eep_ops->get_eeprom_ver(ah));
414 return -EINVAL; 426 return -EINVAL;
415 } 427 }
416 428
@@ -418,48 +430,48 @@ static int ath9k_hw_check_4k_eeprom(struct ath_hal *ah)
418#undef EEPROM_4K_SIZE 430#undef EEPROM_4K_SIZE
419} 431}
420 432
421static int (*ath9k_check_eeprom[]) (struct ath_hal *) = { 433static u32 ath9k_hw_4k_get_eeprom(struct ath_hw *ah,
422 ath9k_hw_check_def_eeprom, 434 enum eeprom_param param)
423 ath9k_hw_check_4k_eeprom
424};
425
426static inline int ath9k_hw_check_eeprom(struct ath_hal *ah)
427{
428 struct ath_hal_5416 *ahp = AH5416(ah);
429
430 return ath9k_check_eeprom[ahp->ah_eep_map](ah);
431}
432
433static inline bool ath9k_hw_fill_vpd_table(u8 pwrMin, u8 pwrMax, u8 *pPwrList,
434 u8 *pVpdList, u16 numIntercepts,
435 u8 *pRetVpdList)
436{ 435{
437 u16 i, k; 436 struct ar5416_eeprom_4k *eep = &ah->eeprom.map4k;
438 u8 currPwr = pwrMin; 437 struct modal_eep_4k_header *pModal = &eep->modalHeader;
439 u16 idxL = 0, idxR = 0; 438 struct base_eep_header_4k *pBase = &eep->baseEepHeader;
440 439
441 for (i = 0; i <= (pwrMax - pwrMin) / 2; i++) { 440 switch (param) {
442 ath9k_hw_get_lower_upper_index(currPwr, pPwrList, 441 case EEP_NFTHRESH_2:
443 numIntercepts, &(idxL), 442 return pModal[1].noiseFloorThreshCh[0];
444 &(idxR)); 443 case AR_EEPROM_MAC(0):
445 if (idxR < 1) 444 return pBase->macAddr[0] << 8 | pBase->macAddr[1];
446 idxR = 1; 445 case AR_EEPROM_MAC(1):
447 if (idxL == numIntercepts - 1) 446 return pBase->macAddr[2] << 8 | pBase->macAddr[3];
448 idxL = (u16) (numIntercepts - 2); 447 case AR_EEPROM_MAC(2):
449 if (pPwrList[idxL] == pPwrList[idxR]) 448 return pBase->macAddr[4] << 8 | pBase->macAddr[5];
450 k = pVpdList[idxL]; 449 case EEP_REG_0:
451 else 450 return pBase->regDmn[0];
452 k = (u16)(((currPwr - pPwrList[idxL]) * pVpdList[idxR] + 451 case EEP_REG_1:
453 (pPwrList[idxR] - currPwr) * pVpdList[idxL]) / 452 return pBase->regDmn[1];
454 (pPwrList[idxR] - pPwrList[idxL])); 453 case EEP_OP_CAP:
455 pRetVpdList[i] = (u8) k; 454 return pBase->deviceCap;
456 currPwr += 2; 455 case EEP_OP_MODE:
456 return pBase->opCapFlags;
457 case EEP_RF_SILENT:
458 return pBase->rfSilent;
459 case EEP_OB_2:
460 return pModal->ob_01;
461 case EEP_DB_2:
462 return pModal->db1_01;
463 case EEP_MINOR_REV:
464 return pBase->version & AR5416_EEP_VER_MINOR_MASK;
465 case EEP_TX_MASK:
466 return pBase->txMask;
467 case EEP_RX_MASK:
468 return pBase->rxMask;
469 default:
470 return 0;
457 } 471 }
458
459 return true;
460} 472}
461 473
462static void ath9k_hw_get_4k_gain_boundaries_pdadcs(struct ath_hal *ah, 474static void ath9k_hw_get_4k_gain_boundaries_pdadcs(struct ath_hw *ah,
463 struct ath9k_channel *chan, 475 struct ath9k_channel *chan,
464 struct cal_data_per_freq_4k *pRawDataSet, 476 struct cal_data_per_freq_4k *pRawDataSet,
465 u8 *bChans, u16 availPiers, 477 u8 *bChans, u16 availPiers,
@@ -627,442 +639,11 @@ static void ath9k_hw_get_4k_gain_boundaries_pdadcs(struct ath_hal *ah,
627#undef TMP_VAL_VPD_TABLE 639#undef TMP_VAL_VPD_TABLE
628} 640}
629 641
630static void ath9k_hw_get_def_gain_boundaries_pdadcs(struct ath_hal *ah, 642static bool ath9k_hw_set_4k_power_cal_table(struct ath_hw *ah,
631 struct ath9k_channel *chan,
632 struct cal_data_per_freq *pRawDataSet,
633 u8 *bChans, u16 availPiers,
634 u16 tPdGainOverlap, int16_t *pMinCalPower,
635 u16 *pPdGainBoundaries, u8 *pPDADCValues,
636 u16 numXpdGains)
637{
638 int i, j, k;
639 int16_t ss;
640 u16 idxL = 0, idxR = 0, numPiers;
641 static u8 vpdTableL[AR5416_NUM_PD_GAINS]
642 [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
643 static u8 vpdTableR[AR5416_NUM_PD_GAINS]
644 [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
645 static u8 vpdTableI[AR5416_NUM_PD_GAINS]
646 [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
647
648 u8 *pVpdL, *pVpdR, *pPwrL, *pPwrR;
649 u8 minPwrT4[AR5416_NUM_PD_GAINS];
650 u8 maxPwrT4[AR5416_NUM_PD_GAINS];
651 int16_t vpdStep;
652 int16_t tmpVal;
653 u16 sizeCurrVpdTable, maxIndex, tgtIndex;
654 bool match;
655 int16_t minDelta = 0;
656 struct chan_centers centers;
657
658 ath9k_hw_get_channel_centers(ah, chan, &centers);
659
660 for (numPiers = 0; numPiers < availPiers; numPiers++) {
661 if (bChans[numPiers] == AR5416_BCHAN_UNUSED)
662 break;
663 }
664
665 match = ath9k_hw_get_lower_upper_index((u8)FREQ2FBIN(centers.synth_center,
666 IS_CHAN_2GHZ(chan)),
667 bChans, numPiers, &idxL, &idxR);
668
669 if (match) {
670 for (i = 0; i < numXpdGains; i++) {
671 minPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][0];
672 maxPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][4];
673 ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
674 pRawDataSet[idxL].pwrPdg[i],
675 pRawDataSet[idxL].vpdPdg[i],
676 AR5416_PD_GAIN_ICEPTS,
677 vpdTableI[i]);
678 }
679 } else {
680 for (i = 0; i < numXpdGains; i++) {
681 pVpdL = pRawDataSet[idxL].vpdPdg[i];
682 pPwrL = pRawDataSet[idxL].pwrPdg[i];
683 pVpdR = pRawDataSet[idxR].vpdPdg[i];
684 pPwrR = pRawDataSet[idxR].pwrPdg[i];
685
686 minPwrT4[i] = max(pPwrL[0], pPwrR[0]);
687
688 maxPwrT4[i] =
689 min(pPwrL[AR5416_PD_GAIN_ICEPTS - 1],
690 pPwrR[AR5416_PD_GAIN_ICEPTS - 1]);
691
692
693 ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
694 pPwrL, pVpdL,
695 AR5416_PD_GAIN_ICEPTS,
696 vpdTableL[i]);
697 ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
698 pPwrR, pVpdR,
699 AR5416_PD_GAIN_ICEPTS,
700 vpdTableR[i]);
701
702 for (j = 0; j <= (maxPwrT4[i] - minPwrT4[i]) / 2; j++) {
703 vpdTableI[i][j] =
704 (u8)(ath9k_hw_interpolate((u16)
705 FREQ2FBIN(centers.
706 synth_center,
707 IS_CHAN_2GHZ
708 (chan)),
709 bChans[idxL], bChans[idxR],
710 vpdTableL[i][j], vpdTableR[i][j]));
711 }
712 }
713 }
714
715 *pMinCalPower = (int16_t)(minPwrT4[0] / 2);
716
717 k = 0;
718
719 for (i = 0; i < numXpdGains; i++) {
720 if (i == (numXpdGains - 1))
721 pPdGainBoundaries[i] =
722 (u16)(maxPwrT4[i] / 2);
723 else
724 pPdGainBoundaries[i] =
725 (u16)((maxPwrT4[i] + minPwrT4[i + 1]) / 4);
726
727 pPdGainBoundaries[i] =
728 min((u16)AR5416_MAX_RATE_POWER, pPdGainBoundaries[i]);
729
730 if ((i == 0) && !AR_SREV_5416_V20_OR_LATER(ah)) {
731 minDelta = pPdGainBoundaries[0] - 23;
732 pPdGainBoundaries[0] = 23;
733 } else {
734 minDelta = 0;
735 }
736
737 if (i == 0) {
738 if (AR_SREV_9280_10_OR_LATER(ah))
739 ss = (int16_t)(0 - (minPwrT4[i] / 2));
740 else
741 ss = 0;
742 } else {
743 ss = (int16_t)((pPdGainBoundaries[i - 1] -
744 (minPwrT4[i] / 2)) -
745 tPdGainOverlap + 1 + minDelta);
746 }
747 vpdStep = (int16_t)(vpdTableI[i][1] - vpdTableI[i][0]);
748 vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep);
749
750 while ((ss < 0) && (k < (AR5416_NUM_PDADC_VALUES - 1))) {
751 tmpVal = (int16_t)(vpdTableI[i][0] + ss * vpdStep);
752 pPDADCValues[k++] = (u8)((tmpVal < 0) ? 0 : tmpVal);
753 ss++;
754 }
755
756 sizeCurrVpdTable = (u8) ((maxPwrT4[i] - minPwrT4[i]) / 2 + 1);
757 tgtIndex = (u8)(pPdGainBoundaries[i] + tPdGainOverlap -
758 (minPwrT4[i] / 2));
759 maxIndex = (tgtIndex < sizeCurrVpdTable) ?
760 tgtIndex : sizeCurrVpdTable;
761
762 while ((ss < maxIndex) && (k < (AR5416_NUM_PDADC_VALUES - 1))) {
763 pPDADCValues[k++] = vpdTableI[i][ss++];
764 }
765
766 vpdStep = (int16_t)(vpdTableI[i][sizeCurrVpdTable - 1] -
767 vpdTableI[i][sizeCurrVpdTable - 2]);
768 vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep);
769
770 if (tgtIndex > maxIndex) {
771 while ((ss <= tgtIndex) &&
772 (k < (AR5416_NUM_PDADC_VALUES - 1))) {
773 tmpVal = (int16_t)((vpdTableI[i][sizeCurrVpdTable - 1] +
774 (ss - maxIndex + 1) * vpdStep));
775 pPDADCValues[k++] = (u8)((tmpVal > 255) ?
776 255 : tmpVal);
777 ss++;
778 }
779 }
780 }
781
782 while (i < AR5416_PD_GAINS_IN_MASK) {
783 pPdGainBoundaries[i] = pPdGainBoundaries[i - 1];
784 i++;
785 }
786
787 while (k < AR5416_NUM_PDADC_VALUES) {
788 pPDADCValues[k] = pPDADCValues[k - 1];
789 k++;
790 }
791
792 return;
793}
794
795static void ath9k_hw_get_legacy_target_powers(struct ath_hal *ah,
796 struct ath9k_channel *chan,
797 struct cal_target_power_leg *powInfo,
798 u16 numChannels,
799 struct cal_target_power_leg *pNewPower,
800 u16 numRates, bool isExtTarget)
801{
802 struct chan_centers centers;
803 u16 clo, chi;
804 int i;
805 int matchIndex = -1, lowIndex = -1;
806 u16 freq;
807
808 ath9k_hw_get_channel_centers(ah, chan, &centers);
809 freq = (isExtTarget) ? centers.ext_center : centers.ctl_center;
810
811 if (freq <= ath9k_hw_fbin2freq(powInfo[0].bChannel,
812 IS_CHAN_2GHZ(chan))) {
813 matchIndex = 0;
814 } else {
815 for (i = 0; (i < numChannels) &&
816 (powInfo[i].bChannel != AR5416_BCHAN_UNUSED); i++) {
817 if (freq == ath9k_hw_fbin2freq(powInfo[i].bChannel,
818 IS_CHAN_2GHZ(chan))) {
819 matchIndex = i;
820 break;
821 } else if ((freq < ath9k_hw_fbin2freq(powInfo[i].bChannel,
822 IS_CHAN_2GHZ(chan))) &&
823 (freq > ath9k_hw_fbin2freq(powInfo[i - 1].bChannel,
824 IS_CHAN_2GHZ(chan)))) {
825 lowIndex = i - 1;
826 break;
827 }
828 }
829 if ((matchIndex == -1) && (lowIndex == -1))
830 matchIndex = i - 1;
831 }
832
833 if (matchIndex != -1) {
834 *pNewPower = powInfo[matchIndex];
835 } else {
836 clo = ath9k_hw_fbin2freq(powInfo[lowIndex].bChannel,
837 IS_CHAN_2GHZ(chan));
838 chi = ath9k_hw_fbin2freq(powInfo[lowIndex + 1].bChannel,
839 IS_CHAN_2GHZ(chan));
840
841 for (i = 0; i < numRates; i++) {
842 pNewPower->tPow2x[i] =
843 (u8)ath9k_hw_interpolate(freq, clo, chi,
844 powInfo[lowIndex].tPow2x[i],
845 powInfo[lowIndex + 1].tPow2x[i]);
846 }
847 }
848}
849
850static void ath9k_hw_get_target_powers(struct ath_hal *ah,
851 struct ath9k_channel *chan,
852 struct cal_target_power_ht *powInfo,
853 u16 numChannels,
854 struct cal_target_power_ht *pNewPower,
855 u16 numRates, bool isHt40Target)
856{
857 struct chan_centers centers;
858 u16 clo, chi;
859 int i;
860 int matchIndex = -1, lowIndex = -1;
861 u16 freq;
862
863 ath9k_hw_get_channel_centers(ah, chan, &centers);
864 freq = isHt40Target ? centers.synth_center : centers.ctl_center;
865
866 if (freq <= ath9k_hw_fbin2freq(powInfo[0].bChannel, IS_CHAN_2GHZ(chan))) {
867 matchIndex = 0;
868 } else {
869 for (i = 0; (i < numChannels) &&
870 (powInfo[i].bChannel != AR5416_BCHAN_UNUSED); i++) {
871 if (freq == ath9k_hw_fbin2freq(powInfo[i].bChannel,
872 IS_CHAN_2GHZ(chan))) {
873 matchIndex = i;
874 break;
875 } else
876 if ((freq < ath9k_hw_fbin2freq(powInfo[i].bChannel,
877 IS_CHAN_2GHZ(chan))) &&
878 (freq > ath9k_hw_fbin2freq(powInfo[i - 1].bChannel,
879 IS_CHAN_2GHZ(chan)))) {
880 lowIndex = i - 1;
881 break;
882 }
883 }
884 if ((matchIndex == -1) && (lowIndex == -1))
885 matchIndex = i - 1;
886 }
887
888 if (matchIndex != -1) {
889 *pNewPower = powInfo[matchIndex];
890 } else {
891 clo = ath9k_hw_fbin2freq(powInfo[lowIndex].bChannel,
892 IS_CHAN_2GHZ(chan));
893 chi = ath9k_hw_fbin2freq(powInfo[lowIndex + 1].bChannel,
894 IS_CHAN_2GHZ(chan));
895
896 for (i = 0; i < numRates; i++) {
897 pNewPower->tPow2x[i] = (u8)ath9k_hw_interpolate(freq,
898 clo, chi,
899 powInfo[lowIndex].tPow2x[i],
900 powInfo[lowIndex + 1].tPow2x[i]);
901 }
902 }
903}
904
905static u16 ath9k_hw_get_max_edge_power(u16 freq,
906 struct cal_ctl_edges *pRdEdgesPower,
907 bool is2GHz, int num_band_edges)
908{
909 u16 twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
910 int i;
911
912 for (i = 0; (i < num_band_edges) &&
913 (pRdEdgesPower[i].bChannel != AR5416_BCHAN_UNUSED); i++) {
914 if (freq == ath9k_hw_fbin2freq(pRdEdgesPower[i].bChannel, is2GHz)) {
915 twiceMaxEdgePower = pRdEdgesPower[i].tPower;
916 break;
917 } else if ((i > 0) &&
918 (freq < ath9k_hw_fbin2freq(pRdEdgesPower[i].bChannel,
919 is2GHz))) {
920 if (ath9k_hw_fbin2freq(pRdEdgesPower[i - 1].bChannel,
921 is2GHz) < freq &&
922 pRdEdgesPower[i - 1].flag) {
923 twiceMaxEdgePower =
924 pRdEdgesPower[i - 1].tPower;
925 }
926 break;
927 }
928 }
929
930 return twiceMaxEdgePower;
931}
932
933static bool ath9k_hw_set_def_power_cal_table(struct ath_hal *ah,
934 struct ath9k_channel *chan,
935 int16_t *pTxPowerIndexOffset)
936{
937 struct ath_hal_5416 *ahp = AH5416(ah);
938 struct ar5416_eeprom_def *pEepData = &ahp->ah_eeprom.def;
939 struct cal_data_per_freq *pRawDataset;
940 u8 *pCalBChans = NULL;
941 u16 pdGainOverlap_t2;
942 static u8 pdadcValues[AR5416_NUM_PDADC_VALUES];
943 u16 gainBoundaries[AR5416_PD_GAINS_IN_MASK];
944 u16 numPiers, i, j;
945 int16_t tMinCalPower;
946 u16 numXpdGain, xpdMask;
947 u16 xpdGainValues[AR5416_NUM_PD_GAINS] = { 0, 0, 0, 0 };
948 u32 reg32, regOffset, regChainOffset;
949 int16_t modalIdx;
950
951 modalIdx = IS_CHAN_2GHZ(chan) ? 1 : 0;
952 xpdMask = pEepData->modalHeader[modalIdx].xpdGain;
953
954 if ((pEepData->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
955 AR5416_EEP_MINOR_VER_2) {
956 pdGainOverlap_t2 =
957 pEepData->modalHeader[modalIdx].pdGainOverlap;
958 } else {
959 pdGainOverlap_t2 = (u16)(MS(REG_READ(ah, AR_PHY_TPCRG5),
960 AR_PHY_TPCRG5_PD_GAIN_OVERLAP));
961 }
962
963 if (IS_CHAN_2GHZ(chan)) {
964 pCalBChans = pEepData->calFreqPier2G;
965 numPiers = AR5416_NUM_2G_CAL_PIERS;
966 } else {
967 pCalBChans = pEepData->calFreqPier5G;
968 numPiers = AR5416_NUM_5G_CAL_PIERS;
969 }
970
971 numXpdGain = 0;
972
973 for (i = 1; i <= AR5416_PD_GAINS_IN_MASK; i++) {
974 if ((xpdMask >> (AR5416_PD_GAINS_IN_MASK - i)) & 1) {
975 if (numXpdGain >= AR5416_NUM_PD_GAINS)
976 break;
977 xpdGainValues[numXpdGain] =
978 (u16)(AR5416_PD_GAINS_IN_MASK - i);
979 numXpdGain++;
980 }
981 }
982
983 REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_NUM_PD_GAIN,
984 (numXpdGain - 1) & 0x3);
985 REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_1,
986 xpdGainValues[0]);
987 REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_2,
988 xpdGainValues[1]);
989 REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_3,
990 xpdGainValues[2]);
991
992 for (i = 0; i < AR5416_MAX_CHAINS; i++) {
993 if (AR_SREV_5416_V20_OR_LATER(ah) &&
994 (ahp->ah_rxchainmask == 5 || ahp->ah_txchainmask == 5) &&
995 (i != 0)) {
996 regChainOffset = (i == 1) ? 0x2000 : 0x1000;
997 } else
998 regChainOffset = i * 0x1000;
999
1000 if (pEepData->baseEepHeader.txMask & (1 << i)) {
1001 if (IS_CHAN_2GHZ(chan))
1002 pRawDataset = pEepData->calPierData2G[i];
1003 else
1004 pRawDataset = pEepData->calPierData5G[i];
1005
1006 ath9k_hw_get_def_gain_boundaries_pdadcs(ah, chan,
1007 pRawDataset, pCalBChans,
1008 numPiers, pdGainOverlap_t2,
1009 &tMinCalPower, gainBoundaries,
1010 pdadcValues, numXpdGain);
1011
1012 if ((i == 0) || AR_SREV_5416_V20_OR_LATER(ah)) {
1013 REG_WRITE(ah,
1014 AR_PHY_TPCRG5 + regChainOffset,
1015 SM(pdGainOverlap_t2,
1016 AR_PHY_TPCRG5_PD_GAIN_OVERLAP)
1017 | SM(gainBoundaries[0],
1018 AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1)
1019 | SM(gainBoundaries[1],
1020 AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2)
1021 | SM(gainBoundaries[2],
1022 AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3)
1023 | SM(gainBoundaries[3],
1024 AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4));
1025 }
1026
1027 regOffset = AR_PHY_BASE + (672 << 2) + regChainOffset;
1028 for (j = 0; j < 32; j++) {
1029 reg32 = ((pdadcValues[4 * j + 0] & 0xFF) << 0) |
1030 ((pdadcValues[4 * j + 1] & 0xFF) << 8) |
1031 ((pdadcValues[4 * j + 2] & 0xFF) << 16)|
1032 ((pdadcValues[4 * j + 3] & 0xFF) << 24);
1033 REG_WRITE(ah, regOffset, reg32);
1034
1035 DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
1036 "PDADC (%d,%4x): %4.4x %8.8x\n",
1037 i, regChainOffset, regOffset,
1038 reg32);
1039 DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
1040 "PDADC: Chain %d | PDADC %3d "
1041 "Value %3d | PDADC %3d Value %3d | "
1042 "PDADC %3d Value %3d | PDADC %3d "
1043 "Value %3d |\n",
1044 i, 4 * j, pdadcValues[4 * j],
1045 4 * j + 1, pdadcValues[4 * j + 1],
1046 4 * j + 2, pdadcValues[4 * j + 2],
1047 4 * j + 3,
1048 pdadcValues[4 * j + 3]);
1049
1050 regOffset += 4;
1051 }
1052 }
1053 }
1054
1055 *pTxPowerIndexOffset = 0;
1056
1057 return true;
1058}
1059
1060static bool ath9k_hw_set_4k_power_cal_table(struct ath_hal *ah,
1061 struct ath9k_channel *chan, 643 struct ath9k_channel *chan,
1062 int16_t *pTxPowerIndexOffset) 644 int16_t *pTxPowerIndexOffset)
1063{ 645{
1064 struct ath_hal_5416 *ahp = AH5416(ah); 646 struct ar5416_eeprom_4k *pEepData = &ah->eeprom.map4k;
1065 struct ar5416_eeprom_4k *pEepData = &ahp->ah_eeprom.map4k;
1066 struct cal_data_per_freq_4k *pRawDataset; 647 struct cal_data_per_freq_4k *pRawDataset;
1067 u8 *pCalBChans = NULL; 648 u8 *pCalBChans = NULL;
1068 u16 pdGainOverlap_t2; 649 u16 pdGainOverlap_t2;
@@ -1111,7 +692,7 @@ static bool ath9k_hw_set_4k_power_cal_table(struct ath_hal *ah,
1111 692
1112 for (i = 0; i < AR5416_MAX_CHAINS; i++) { 693 for (i = 0; i < AR5416_MAX_CHAINS; i++) {
1113 if (AR_SREV_5416_V20_OR_LATER(ah) && 694 if (AR_SREV_5416_V20_OR_LATER(ah) &&
1114 (ahp->ah_rxchainmask == 5 || ahp->ah_txchainmask == 5) && 695 (ah->rxchainmask == 5 || ah->txchainmask == 5) &&
1115 (i != 0)) { 696 (i != 0)) {
1116 regChainOffset = (i == 1) ? 0x2000 : 0x1000; 697 regChainOffset = (i == 1) ? 0x2000 : 0x1000;
1117 } else 698 } else
@@ -1174,298 +755,7 @@ static bool ath9k_hw_set_4k_power_cal_table(struct ath_hal *ah,
1174 return true; 755 return true;
1175} 756}
1176 757
1177static bool ath9k_hw_set_def_power_per_rate_table(struct ath_hal *ah, 758static bool ath9k_hw_set_4k_power_per_rate_table(struct ath_hw *ah,
1178 struct ath9k_channel *chan,
1179 int16_t *ratesArray,
1180 u16 cfgCtl,
1181 u16 AntennaReduction,
1182 u16 twiceMaxRegulatoryPower,
1183 u16 powerLimit)
1184{
1185#define REDUCE_SCALED_POWER_BY_TWO_CHAIN 6 /* 10*log10(2)*2 */
1186#define REDUCE_SCALED_POWER_BY_THREE_CHAIN 10 /* 10*log10(3)*2 */
1187
1188 struct ath_hal_5416 *ahp = AH5416(ah);
1189 struct ar5416_eeprom_def *pEepData = &ahp->ah_eeprom.def;
1190 u16 twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
1191 static const u16 tpScaleReductionTable[5] =
1192 { 0, 3, 6, 9, AR5416_MAX_RATE_POWER };
1193
1194 int i;
1195 int16_t twiceLargestAntenna;
1196 struct cal_ctl_data *rep;
1197 struct cal_target_power_leg targetPowerOfdm, targetPowerCck = {
1198 0, { 0, 0, 0, 0}
1199 };
1200 struct cal_target_power_leg targetPowerOfdmExt = {
1201 0, { 0, 0, 0, 0} }, targetPowerCckExt = {
1202 0, { 0, 0, 0, 0 }
1203 };
1204 struct cal_target_power_ht targetPowerHt20, targetPowerHt40 = {
1205 0, {0, 0, 0, 0}
1206 };
1207 u16 scaledPower = 0, minCtlPower, maxRegAllowedPower;
1208 u16 ctlModesFor11a[] =
1209 { CTL_11A, CTL_5GHT20, CTL_11A_EXT, CTL_5GHT40 };
1210 u16 ctlModesFor11g[] =
1211 { CTL_11B, CTL_11G, CTL_2GHT20, CTL_11B_EXT, CTL_11G_EXT,
1212 CTL_2GHT40
1213 };
1214 u16 numCtlModes, *pCtlMode, ctlMode, freq;
1215 struct chan_centers centers;
1216 int tx_chainmask;
1217 u16 twiceMinEdgePower;
1218
1219 tx_chainmask = ahp->ah_txchainmask;
1220
1221 ath9k_hw_get_channel_centers(ah, chan, &centers);
1222
1223 twiceLargestAntenna = max(
1224 pEepData->modalHeader
1225 [IS_CHAN_2GHZ(chan)].antennaGainCh[0],
1226 pEepData->modalHeader
1227 [IS_CHAN_2GHZ(chan)].antennaGainCh[1]);
1228
1229 twiceLargestAntenna = max((u8)twiceLargestAntenna,
1230 pEepData->modalHeader
1231 [IS_CHAN_2GHZ(chan)].antennaGainCh[2]);
1232
1233 twiceLargestAntenna = (int16_t)min(AntennaReduction -
1234 twiceLargestAntenna, 0);
1235
1236 maxRegAllowedPower = twiceMaxRegulatoryPower + twiceLargestAntenna;
1237
1238 if (ah->ah_tpScale != ATH9K_TP_SCALE_MAX) {
1239 maxRegAllowedPower -=
1240 (tpScaleReductionTable[(ah->ah_tpScale)] * 2);
1241 }
1242
1243 scaledPower = min(powerLimit, maxRegAllowedPower);
1244
1245 switch (ar5416_get_ntxchains(tx_chainmask)) {
1246 case 1:
1247 break;
1248 case 2:
1249 scaledPower -= REDUCE_SCALED_POWER_BY_TWO_CHAIN;
1250 break;
1251 case 3:
1252 scaledPower -= REDUCE_SCALED_POWER_BY_THREE_CHAIN;
1253 break;
1254 }
1255
1256 scaledPower = max((u16)0, scaledPower);
1257
1258 if (IS_CHAN_2GHZ(chan)) {
1259 numCtlModes = ARRAY_SIZE(ctlModesFor11g) -
1260 SUB_NUM_CTL_MODES_AT_2G_40;
1261 pCtlMode = ctlModesFor11g;
1262
1263 ath9k_hw_get_legacy_target_powers(ah, chan,
1264 pEepData->calTargetPowerCck,
1265 AR5416_NUM_2G_CCK_TARGET_POWERS,
1266 &targetPowerCck, 4, false);
1267 ath9k_hw_get_legacy_target_powers(ah, chan,
1268 pEepData->calTargetPower2G,
1269 AR5416_NUM_2G_20_TARGET_POWERS,
1270 &targetPowerOfdm, 4, false);
1271 ath9k_hw_get_target_powers(ah, chan,
1272 pEepData->calTargetPower2GHT20,
1273 AR5416_NUM_2G_20_TARGET_POWERS,
1274 &targetPowerHt20, 8, false);
1275
1276 if (IS_CHAN_HT40(chan)) {
1277 numCtlModes = ARRAY_SIZE(ctlModesFor11g);
1278 ath9k_hw_get_target_powers(ah, chan,
1279 pEepData->calTargetPower2GHT40,
1280 AR5416_NUM_2G_40_TARGET_POWERS,
1281 &targetPowerHt40, 8, true);
1282 ath9k_hw_get_legacy_target_powers(ah, chan,
1283 pEepData->calTargetPowerCck,
1284 AR5416_NUM_2G_CCK_TARGET_POWERS,
1285 &targetPowerCckExt, 4, true);
1286 ath9k_hw_get_legacy_target_powers(ah, chan,
1287 pEepData->calTargetPower2G,
1288 AR5416_NUM_2G_20_TARGET_POWERS,
1289 &targetPowerOfdmExt, 4, true);
1290 }
1291 } else {
1292 numCtlModes = ARRAY_SIZE(ctlModesFor11a) -
1293 SUB_NUM_CTL_MODES_AT_5G_40;
1294 pCtlMode = ctlModesFor11a;
1295
1296 ath9k_hw_get_legacy_target_powers(ah, chan,
1297 pEepData->calTargetPower5G,
1298 AR5416_NUM_5G_20_TARGET_POWERS,
1299 &targetPowerOfdm, 4, false);
1300 ath9k_hw_get_target_powers(ah, chan,
1301 pEepData->calTargetPower5GHT20,
1302 AR5416_NUM_5G_20_TARGET_POWERS,
1303 &targetPowerHt20, 8, false);
1304
1305 if (IS_CHAN_HT40(chan)) {
1306 numCtlModes = ARRAY_SIZE(ctlModesFor11a);
1307 ath9k_hw_get_target_powers(ah, chan,
1308 pEepData->calTargetPower5GHT40,
1309 AR5416_NUM_5G_40_TARGET_POWERS,
1310 &targetPowerHt40, 8, true);
1311 ath9k_hw_get_legacy_target_powers(ah, chan,
1312 pEepData->calTargetPower5G,
1313 AR5416_NUM_5G_20_TARGET_POWERS,
1314 &targetPowerOfdmExt, 4, true);
1315 }
1316 }
1317
1318 for (ctlMode = 0; ctlMode < numCtlModes; ctlMode++) {
1319 bool isHt40CtlMode = (pCtlMode[ctlMode] == CTL_5GHT40) ||
1320 (pCtlMode[ctlMode] == CTL_2GHT40);
1321 if (isHt40CtlMode)
1322 freq = centers.synth_center;
1323 else if (pCtlMode[ctlMode] & EXT_ADDITIVE)
1324 freq = centers.ext_center;
1325 else
1326 freq = centers.ctl_center;
1327
1328 if (ar5416_get_eep_ver(ahp) == 14 && ar5416_get_eep_rev(ahp) <= 2)
1329 twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
1330
1331 DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
1332 "LOOP-Mode ctlMode %d < %d, isHt40CtlMode %d, "
1333 "EXT_ADDITIVE %d\n",
1334 ctlMode, numCtlModes, isHt40CtlMode,
1335 (pCtlMode[ctlMode] & EXT_ADDITIVE));
1336
1337 for (i = 0; (i < AR5416_NUM_CTLS) && pEepData->ctlIndex[i]; i++) {
1338 DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
1339 " LOOP-Ctlidx %d: cfgCtl 0x%2.2x "
1340 "pCtlMode 0x%2.2x ctlIndex 0x%2.2x "
1341 "chan %d\n",
1342 i, cfgCtl, pCtlMode[ctlMode],
1343 pEepData->ctlIndex[i], chan->channel);
1344
1345 if ((((cfgCtl & ~CTL_MODE_M) |
1346 (pCtlMode[ctlMode] & CTL_MODE_M)) ==
1347 pEepData->ctlIndex[i]) ||
1348 (((cfgCtl & ~CTL_MODE_M) |
1349 (pCtlMode[ctlMode] & CTL_MODE_M)) ==
1350 ((pEepData->ctlIndex[i] & CTL_MODE_M) | SD_NO_CTL))) {
1351 rep = &(pEepData->ctlData[i]);
1352
1353 twiceMinEdgePower = ath9k_hw_get_max_edge_power(freq,
1354 rep->ctlEdges[ar5416_get_ntxchains(tx_chainmask) - 1],
1355 IS_CHAN_2GHZ(chan), AR5416_NUM_BAND_EDGES);
1356
1357 DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
1358 " MATCH-EE_IDX %d: ch %d is2 %d "
1359 "2xMinEdge %d chainmask %d chains %d\n",
1360 i, freq, IS_CHAN_2GHZ(chan),
1361 twiceMinEdgePower, tx_chainmask,
1362 ar5416_get_ntxchains
1363 (tx_chainmask));
1364 if ((cfgCtl & ~CTL_MODE_M) == SD_NO_CTL) {
1365 twiceMaxEdgePower = min(twiceMaxEdgePower,
1366 twiceMinEdgePower);
1367 } else {
1368 twiceMaxEdgePower = twiceMinEdgePower;
1369 break;
1370 }
1371 }
1372 }
1373
1374 minCtlPower = min(twiceMaxEdgePower, scaledPower);
1375
1376 DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
1377 " SEL-Min ctlMode %d pCtlMode %d "
1378 "2xMaxEdge %d sP %d minCtlPwr %d\n",
1379 ctlMode, pCtlMode[ctlMode], twiceMaxEdgePower,
1380 scaledPower, minCtlPower);
1381
1382 switch (pCtlMode[ctlMode]) {
1383 case CTL_11B:
1384 for (i = 0; i < ARRAY_SIZE(targetPowerCck.tPow2x); i++) {
1385 targetPowerCck.tPow2x[i] =
1386 min((u16)targetPowerCck.tPow2x[i],
1387 minCtlPower);
1388 }
1389 break;
1390 case CTL_11A:
1391 case CTL_11G:
1392 for (i = 0; i < ARRAY_SIZE(targetPowerOfdm.tPow2x); i++) {
1393 targetPowerOfdm.tPow2x[i] =
1394 min((u16)targetPowerOfdm.tPow2x[i],
1395 minCtlPower);
1396 }
1397 break;
1398 case CTL_5GHT20:
1399 case CTL_2GHT20:
1400 for (i = 0; i < ARRAY_SIZE(targetPowerHt20.tPow2x); i++) {
1401 targetPowerHt20.tPow2x[i] =
1402 min((u16)targetPowerHt20.tPow2x[i],
1403 minCtlPower);
1404 }
1405 break;
1406 case CTL_11B_EXT:
1407 targetPowerCckExt.tPow2x[0] = min((u16)
1408 targetPowerCckExt.tPow2x[0],
1409 minCtlPower);
1410 break;
1411 case CTL_11A_EXT:
1412 case CTL_11G_EXT:
1413 targetPowerOfdmExt.tPow2x[0] = min((u16)
1414 targetPowerOfdmExt.tPow2x[0],
1415 minCtlPower);
1416 break;
1417 case CTL_5GHT40:
1418 case CTL_2GHT40:
1419 for (i = 0; i < ARRAY_SIZE(targetPowerHt40.tPow2x); i++) {
1420 targetPowerHt40.tPow2x[i] =
1421 min((u16)targetPowerHt40.tPow2x[i],
1422 minCtlPower);
1423 }
1424 break;
1425 default:
1426 break;
1427 }
1428 }
1429
1430 ratesArray[rate6mb] = ratesArray[rate9mb] = ratesArray[rate12mb] =
1431 ratesArray[rate18mb] = ratesArray[rate24mb] =
1432 targetPowerOfdm.tPow2x[0];
1433 ratesArray[rate36mb] = targetPowerOfdm.tPow2x[1];
1434 ratesArray[rate48mb] = targetPowerOfdm.tPow2x[2];
1435 ratesArray[rate54mb] = targetPowerOfdm.tPow2x[3];
1436 ratesArray[rateXr] = targetPowerOfdm.tPow2x[0];
1437
1438 for (i = 0; i < ARRAY_SIZE(targetPowerHt20.tPow2x); i++)
1439 ratesArray[rateHt20_0 + i] = targetPowerHt20.tPow2x[i];
1440
1441 if (IS_CHAN_2GHZ(chan)) {
1442 ratesArray[rate1l] = targetPowerCck.tPow2x[0];
1443 ratesArray[rate2s] = ratesArray[rate2l] =
1444 targetPowerCck.tPow2x[1];
1445 ratesArray[rate5_5s] = ratesArray[rate5_5l] =
1446 targetPowerCck.tPow2x[2];
1447 ;
1448 ratesArray[rate11s] = ratesArray[rate11l] =
1449 targetPowerCck.tPow2x[3];
1450 ;
1451 }
1452 if (IS_CHAN_HT40(chan)) {
1453 for (i = 0; i < ARRAY_SIZE(targetPowerHt40.tPow2x); i++) {
1454 ratesArray[rateHt40_0 + i] =
1455 targetPowerHt40.tPow2x[i];
1456 }
1457 ratesArray[rateDupOfdm] = targetPowerHt40.tPow2x[0];
1458 ratesArray[rateDupCck] = targetPowerHt40.tPow2x[0];
1459 ratesArray[rateExtOfdm] = targetPowerOfdmExt.tPow2x[0];
1460 if (IS_CHAN_2GHZ(chan)) {
1461 ratesArray[rateExtCck] =
1462 targetPowerCckExt.tPow2x[0];
1463 }
1464 }
1465 return true;
1466}
1467
1468static bool ath9k_hw_set_4k_power_per_rate_table(struct ath_hal *ah,
1469 struct ath9k_channel *chan, 759 struct ath9k_channel *chan,
1470 int16_t *ratesArray, 760 int16_t *ratesArray,
1471 u16 cfgCtl, 761 u16 cfgCtl,
@@ -1473,8 +763,7 @@ static bool ath9k_hw_set_4k_power_per_rate_table(struct ath_hal *ah,
1473 u16 twiceMaxRegulatoryPower, 763 u16 twiceMaxRegulatoryPower,
1474 u16 powerLimit) 764 u16 powerLimit)
1475{ 765{
1476 struct ath_hal_5416 *ahp = AH5416(ah); 766 struct ar5416_eeprom_4k *pEepData = &ah->eeprom.map4k;
1477 struct ar5416_eeprom_4k *pEepData = &ahp->ah_eeprom.map4k;
1478 u16 twiceMaxEdgePower = AR5416_MAX_RATE_POWER; 767 u16 twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
1479 static const u16 tpScaleReductionTable[5] = 768 static const u16 tpScaleReductionTable[5] =
1480 { 0, 3, 6, 9, AR5416_MAX_RATE_POWER }; 769 { 0, 3, 6, 9, AR5416_MAX_RATE_POWER };
@@ -1502,7 +791,7 @@ static bool ath9k_hw_set_4k_power_per_rate_table(struct ath_hal *ah,
1502 int tx_chainmask; 791 int tx_chainmask;
1503 u16 twiceMinEdgePower; 792 u16 twiceMinEdgePower;
1504 793
1505 tx_chainmask = ahp->ah_txchainmask; 794 tx_chainmask = ah->txchainmask;
1506 795
1507 ath9k_hw_get_channel_centers(ah, chan, &centers); 796 ath9k_hw_get_channel_centers(ah, chan, &centers);
1508 797
@@ -1513,9 +802,9 @@ static bool ath9k_hw_set_4k_power_per_rate_table(struct ath_hal *ah,
1513 802
1514 maxRegAllowedPower = twiceMaxRegulatoryPower + twiceLargestAntenna; 803 maxRegAllowedPower = twiceMaxRegulatoryPower + twiceLargestAntenna;
1515 804
1516 if (ah->ah_tpScale != ATH9K_TP_SCALE_MAX) { 805 if (ah->regulatory.tp_scale != ATH9K_TP_SCALE_MAX) {
1517 maxRegAllowedPower -= 806 maxRegAllowedPower -=
1518 (tpScaleReductionTable[(ah->ah_tpScale)] * 2); 807 (tpScaleReductionTable[(ah->regulatory.tp_scale)] * 2);
1519 } 808 }
1520 809
1521 scaledPower = min(powerLimit, maxRegAllowedPower); 810 scaledPower = min(powerLimit, maxRegAllowedPower);
@@ -1563,8 +852,8 @@ static bool ath9k_hw_set_4k_power_per_rate_table(struct ath_hal *ah,
1563 else 852 else
1564 freq = centers.ctl_center; 853 freq = centers.ctl_center;
1565 854
1566 if (ar5416_get_eep_ver(ahp) == 14 && 855 if (ah->eep_ops->get_eeprom_ver(ah) == 14 &&
1567 ar5416_get_eep_rev(ahp) <= 2) 856 ah->eep_ops->get_eeprom_rev(ah) <= 2)
1568 twiceMaxEdgePower = AR5416_MAX_RATE_POWER; 857 twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
1569 858
1570 DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT, 859 DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
@@ -1701,17 +990,15 @@ static bool ath9k_hw_set_4k_power_per_rate_table(struct ath_hal *ah,
1701 return true; 990 return true;
1702} 991}
1703 992
1704static int ath9k_hw_def_set_txpower(struct ath_hal *ah, 993static int ath9k_hw_4k_set_txpower(struct ath_hw *ah,
1705 struct ath9k_channel *chan, 994 struct ath9k_channel *chan,
1706 u16 cfgCtl, 995 u16 cfgCtl,
1707 u8 twiceAntennaReduction, 996 u8 twiceAntennaReduction,
1708 u8 twiceMaxRegulatoryPower, 997 u8 twiceMaxRegulatoryPower,
1709 u8 powerLimit) 998 u8 powerLimit)
1710{ 999{
1711 struct ath_hal_5416 *ahp = AH5416(ah); 1000 struct ar5416_eeprom_4k *pEepData = &ah->eeprom.map4k;
1712 struct ar5416_eeprom_def *pEepData = &ahp->ah_eeprom.def; 1001 struct modal_eep_4k_header *pModal = &pEepData->modalHeader;
1713 struct modal_eep_header *pModal =
1714 &(pEepData->modalHeader[IS_CHAN_2GHZ(chan)]);
1715 int16_t ratesArray[Ar5416RateSize]; 1002 int16_t ratesArray[Ar5416RateSize];
1716 int16_t txPowerIndexOffset = 0; 1003 int16_t txPowerIndexOffset = 0;
1717 u8 ht40PowerIncForPdadc = 2; 1004 u8 ht40PowerIncForPdadc = 2;
@@ -1724,7 +1011,7 @@ static int ath9k_hw_def_set_txpower(struct ath_hal *ah,
1724 ht40PowerIncForPdadc = pModal->ht40PowerIncForPdadc; 1011 ht40PowerIncForPdadc = pModal->ht40PowerIncForPdadc;
1725 } 1012 }
1726 1013
1727 if (!ath9k_hw_set_def_power_per_rate_table(ah, chan, 1014 if (!ath9k_hw_set_4k_power_per_rate_table(ah, chan,
1728 &ratesArray[0], cfgCtl, 1015 &ratesArray[0], cfgCtl,
1729 twiceAntennaReduction, 1016 twiceAntennaReduction,
1730 twiceMaxRegulatoryPower, 1017 twiceMaxRegulatoryPower,
@@ -1735,7 +1022,7 @@ static int ath9k_hw_def_set_txpower(struct ath_hal *ah,
1735 return -EIO; 1022 return -EIO;
1736 } 1023 }
1737 1024
1738 if (!ath9k_hw_set_def_power_cal_table(ah, chan, &txPowerIndexOffset)) { 1025 if (!ath9k_hw_set_4k_power_cal_table(ah, chan, &txPowerIndexOffset)) {
1739 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, 1026 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
1740 "ath9k_hw_set_txpower: unable to set power table\n"); 1027 "ath9k_hw_set_txpower: unable to set power table\n");
1741 return -EIO; 1028 return -EIO;
@@ -1814,10 +1101,6 @@ static int ath9k_hw_def_set_txpower(struct ath_hal *ah,
1814 | ATH9K_POW_SM(ratesArray[rateDupCck], 0)); 1101 | ATH9K_POW_SM(ratesArray[rateDupCck], 0));
1815 } 1102 }
1816 1103
1817 REG_WRITE(ah, AR_PHY_POWER_TX_SUB,
1818 ATH9K_POW_SM(pModal->pwrDecreaseFor3Chain, 6)
1819 | ATH9K_POW_SM(pModal->pwrDecreaseFor2Chain, 0));
1820
1821 i = rate6mb; 1104 i = rate6mb;
1822 1105
1823 if (IS_CHAN_HT40(chan)) 1106 if (IS_CHAN_HT40(chan))
@@ -1826,263 +1109,509 @@ static int ath9k_hw_def_set_txpower(struct ath_hal *ah,
1826 i = rateHt20_0; 1109 i = rateHt20_0;
1827 1110
1828 if (AR_SREV_9280_10_OR_LATER(ah)) 1111 if (AR_SREV_9280_10_OR_LATER(ah))
1829 ah->ah_maxPowerLevel = 1112 ah->regulatory.max_power_level =
1830 ratesArray[i] + AR5416_PWR_TABLE_OFFSET * 2; 1113 ratesArray[i] + AR5416_PWR_TABLE_OFFSET * 2;
1831 else 1114 else
1832 ah->ah_maxPowerLevel = ratesArray[i]; 1115 ah->regulatory.max_power_level = ratesArray[i];
1833 1116
1834 return 0; 1117 return 0;
1835} 1118}
1836 1119
1837static int ath9k_hw_4k_set_txpower(struct ath_hal *ah, 1120static void ath9k_hw_4k_set_addac(struct ath_hw *ah,
1838 struct ath9k_channel *chan, 1121 struct ath9k_channel *chan)
1839 u16 cfgCtl,
1840 u8 twiceAntennaReduction,
1841 u8 twiceMaxRegulatoryPower,
1842 u8 powerLimit)
1843{ 1122{
1844 struct ath_hal_5416 *ahp = AH5416(ah); 1123 struct modal_eep_4k_header *pModal;
1845 struct ar5416_eeprom_4k *pEepData = &ahp->ah_eeprom.map4k; 1124 struct ar5416_eeprom_4k *eep = &ah->eeprom.map4k;
1846 struct modal_eep_4k_header *pModal = &pEepData->modalHeader; 1125 u8 biaslevel;
1847 int16_t ratesArray[Ar5416RateSize];
1848 int16_t txPowerIndexOffset = 0;
1849 u8 ht40PowerIncForPdadc = 2;
1850 int i;
1851 1126
1852 memset(ratesArray, 0, sizeof(ratesArray)); 1127 if (ah->hw_version.macVersion != AR_SREV_VERSION_9160)
1128 return;
1853 1129
1854 if ((pEepData->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >= 1130 if (ah->eep_ops->get_eeprom_rev(ah) < AR5416_EEP_MINOR_VER_7)
1855 AR5416_EEP_MINOR_VER_2) { 1131 return;
1856 ht40PowerIncForPdadc = pModal->ht40PowerIncForPdadc; 1132
1133 pModal = &eep->modalHeader;
1134
1135 if (pModal->xpaBiasLvl != 0xff) {
1136 biaslevel = pModal->xpaBiasLvl;
1137 INI_RA(&ah->iniAddac, 7, 1) =
1138 (INI_RA(&ah->iniAddac, 7, 1) & (~0x18)) | biaslevel << 3;
1857 } 1139 }
1140}
1858 1141
1859 if (!ath9k_hw_set_4k_power_per_rate_table(ah, chan, 1142static bool ath9k_hw_4k_set_board_values(struct ath_hw *ah,
1860 &ratesArray[0], cfgCtl, 1143 struct ath9k_channel *chan)
1861 twiceAntennaReduction, 1144{
1862 twiceMaxRegulatoryPower, 1145 struct modal_eep_4k_header *pModal;
1863 powerLimit)) { 1146 struct ar5416_eeprom_4k *eep = &ah->eeprom.map4k;
1864 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, 1147 int regChainOffset;
1865 "ath9k_hw_set_txpower: unable to set " 1148 u8 txRxAttenLocal;
1866 "tx power per rate table\n"); 1149 u8 ob[5], db1[5], db2[5];
1867 return -EIO; 1150 u8 ant_div_control1, ant_div_control2;
1151 u32 regVal;
1152
1153
1154 pModal = &eep->modalHeader;
1155
1156 txRxAttenLocal = 23;
1157
1158 REG_WRITE(ah, AR_PHY_SWITCH_COM,
1159 ah->eep_ops->get_eeprom_antenna_cfg(ah, chan));
1160
1161 regChainOffset = 0;
1162 REG_WRITE(ah, AR_PHY_SWITCH_CHAIN_0 + regChainOffset,
1163 pModal->antCtrlChain[0]);
1164
1165 REG_WRITE(ah, AR_PHY_TIMING_CTRL4(0) + regChainOffset,
1166 (REG_READ(ah, AR_PHY_TIMING_CTRL4(0) + regChainOffset) &
1167 ~(AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF |
1168 AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF)) |
1169 SM(pModal->iqCalICh[0], AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF) |
1170 SM(pModal->iqCalQCh[0], AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF));
1171
1172 if ((eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
1173 AR5416_EEP_MINOR_VER_3) {
1174 txRxAttenLocal = pModal->txRxAttenCh[0];
1175 REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
1176 AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN, pModal->bswMargin[0]);
1177 REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
1178 AR_PHY_GAIN_2GHZ_XATTEN1_DB, pModal->bswAtten[0]);
1179 REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
1180 AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN,
1181 pModal->xatten2Margin[0]);
1182 REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
1183 AR_PHY_GAIN_2GHZ_XATTEN2_DB, pModal->xatten2Db[0]);
1868 } 1184 }
1869 1185
1870 if (!ath9k_hw_set_4k_power_cal_table(ah, chan, &txPowerIndexOffset)) { 1186 REG_RMW_FIELD(ah, AR_PHY_RXGAIN + regChainOffset,
1187 AR9280_PHY_RXGAIN_TXRX_ATTEN, txRxAttenLocal);
1188 REG_RMW_FIELD(ah, AR_PHY_RXGAIN + regChainOffset,
1189 AR9280_PHY_RXGAIN_TXRX_MARGIN, pModal->rxTxMarginCh[0]);
1190
1191 if (AR_SREV_9285_11(ah))
1192 REG_WRITE(ah, AR9285_AN_TOP4, (AR9285_AN_TOP4_DEFAULT | 0x14));
1193
1194 /* Initialize Ant Diversity settings from EEPROM */
1195 if (pModal->version == 3) {
1196 ant_div_control1 = ((pModal->ob_234 >> 12) & 0xf);
1197 ant_div_control2 = ((pModal->db1_234 >> 12) & 0xf);
1198 regVal = REG_READ(ah, 0x99ac);
1199 regVal &= (~(0x7f000000));
1200 regVal |= ((ant_div_control1 & 0x1) << 24);
1201 regVal |= (((ant_div_control1 >> 1) & 0x1) << 29);
1202 regVal |= (((ant_div_control1 >> 2) & 0x1) << 30);
1203 regVal |= ((ant_div_control2 & 0x3) << 25);
1204 regVal |= (((ant_div_control2 >> 2) & 0x3) << 27);
1205 REG_WRITE(ah, 0x99ac, regVal);
1206 regVal = REG_READ(ah, 0x99ac);
1207 regVal = REG_READ(ah, 0xa208);
1208 regVal &= (~(0x1 << 13));
1209 regVal |= (((ant_div_control1 >> 3) & 0x1) << 13);
1210 REG_WRITE(ah, 0xa208, regVal);
1211 regVal = REG_READ(ah, 0xa208);
1212 }
1213
1214 if (pModal->version >= 2) {
1215 ob[0] = (pModal->ob_01 & 0xf);
1216 ob[1] = (pModal->ob_01 >> 4) & 0xf;
1217 ob[2] = (pModal->ob_234 & 0xf);
1218 ob[3] = ((pModal->ob_234 >> 4) & 0xf);
1219 ob[4] = ((pModal->ob_234 >> 8) & 0xf);
1220
1221 db1[0] = (pModal->db1_01 & 0xf);
1222 db1[1] = ((pModal->db1_01 >> 4) & 0xf);
1223 db1[2] = (pModal->db1_234 & 0xf);
1224 db1[3] = ((pModal->db1_234 >> 4) & 0xf);
1225 db1[4] = ((pModal->db1_234 >> 8) & 0xf);
1226
1227 db2[0] = (pModal->db2_01 & 0xf);
1228 db2[1] = ((pModal->db2_01 >> 4) & 0xf);
1229 db2[2] = (pModal->db2_234 & 0xf);
1230 db2[3] = ((pModal->db2_234 >> 4) & 0xf);
1231 db2[4] = ((pModal->db2_234 >> 8) & 0xf);
1232
1233 } else if (pModal->version == 1) {
1234
1871 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, 1235 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
1872 "ath9k_hw_set_txpower: unable to set power table\n"); 1236 "EEPROM Model version is set to 1 \n");
1873 return -EIO; 1237 ob[0] = (pModal->ob_01 & 0xf);
1238 ob[1] = ob[2] = ob[3] = ob[4] = (pModal->ob_01 >> 4) & 0xf;
1239 db1[0] = (pModal->db1_01 & 0xf);
1240 db1[1] = db1[2] = db1[3] =
1241 db1[4] = ((pModal->db1_01 >> 4) & 0xf);
1242 db2[0] = (pModal->db2_01 & 0xf);
1243 db2[1] = db2[2] = db2[3] =
1244 db2[4] = ((pModal->db2_01 >> 4) & 0xf);
1245 } else {
1246 int i;
1247 for (i = 0; i < 5; i++) {
1248 ob[i] = pModal->ob_01;
1249 db1[i] = pModal->db1_01;
1250 db2[i] = pModal->db1_01;
1251 }
1874 } 1252 }
1875 1253
1876 for (i = 0; i < ARRAY_SIZE(ratesArray); i++) { 1254 ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3,
1877 ratesArray[i] = (int16_t)(txPowerIndexOffset + ratesArray[i]); 1255 AR9285_AN_RF2G3_OB_0, AR9285_AN_RF2G3_OB_0_S, ob[0]);
1878 if (ratesArray[i] > AR5416_MAX_RATE_POWER) 1256 ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3,
1879 ratesArray[i] = AR5416_MAX_RATE_POWER; 1257 AR9285_AN_RF2G3_OB_1, AR9285_AN_RF2G3_OB_1_S, ob[1]);
1258 ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3,
1259 AR9285_AN_RF2G3_OB_2, AR9285_AN_RF2G3_OB_2_S, ob[2]);
1260 ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3,
1261 AR9285_AN_RF2G3_OB_3, AR9285_AN_RF2G3_OB_3_S, ob[3]);
1262 ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3,
1263 AR9285_AN_RF2G3_OB_4, AR9285_AN_RF2G3_OB_4_S, ob[4]);
1264
1265 ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3,
1266 AR9285_AN_RF2G3_DB1_0, AR9285_AN_RF2G3_DB1_0_S, db1[0]);
1267 ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3,
1268 AR9285_AN_RF2G3_DB1_1, AR9285_AN_RF2G3_DB1_1_S, db1[1]);
1269 ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3,
1270 AR9285_AN_RF2G3_DB1_2, AR9285_AN_RF2G3_DB1_2_S, db1[2]);
1271 ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4,
1272 AR9285_AN_RF2G4_DB1_3, AR9285_AN_RF2G4_DB1_3_S, db1[3]);
1273 ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4,
1274 AR9285_AN_RF2G4_DB1_4, AR9285_AN_RF2G4_DB1_4_S, db1[4]);
1275
1276 ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4,
1277 AR9285_AN_RF2G4_DB2_0, AR9285_AN_RF2G4_DB2_0_S, db2[0]);
1278 ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4,
1279 AR9285_AN_RF2G4_DB2_1, AR9285_AN_RF2G4_DB2_1_S, db2[1]);
1280 ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4,
1281 AR9285_AN_RF2G4_DB2_2, AR9285_AN_RF2G4_DB2_2_S, db2[2]);
1282 ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4,
1283 AR9285_AN_RF2G4_DB2_3, AR9285_AN_RF2G4_DB2_3_S, db2[3]);
1284 ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4,
1285 AR9285_AN_RF2G4_DB2_4, AR9285_AN_RF2G4_DB2_4_S, db2[4]);
1286
1287
1288 if (AR_SREV_9285_11(ah))
1289 REG_WRITE(ah, AR9285_AN_TOP4, AR9285_AN_TOP4_DEFAULT);
1290
1291 REG_RMW_FIELD(ah, AR_PHY_SETTLING, AR_PHY_SETTLING_SWITCH,
1292 pModal->switchSettling);
1293 REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ, AR_PHY_DESIRED_SZ_ADC,
1294 pModal->adcDesiredSize);
1295
1296 REG_WRITE(ah, AR_PHY_RF_CTL4,
1297 SM(pModal->txEndToXpaOff, AR_PHY_RF_CTL4_TX_END_XPAA_OFF) |
1298 SM(pModal->txEndToXpaOff, AR_PHY_RF_CTL4_TX_END_XPAB_OFF) |
1299 SM(pModal->txFrameToXpaOn, AR_PHY_RF_CTL4_FRAME_XPAA_ON) |
1300 SM(pModal->txFrameToXpaOn, AR_PHY_RF_CTL4_FRAME_XPAB_ON));
1301
1302 REG_RMW_FIELD(ah, AR_PHY_RF_CTL3, AR_PHY_TX_END_TO_A2_RX_ON,
1303 pModal->txEndToRxOn);
1304 REG_RMW_FIELD(ah, AR_PHY_CCA, AR9280_PHY_CCA_THRESH62,
1305 pModal->thresh62);
1306 REG_RMW_FIELD(ah, AR_PHY_EXT_CCA0, AR_PHY_EXT_CCA0_THRESH62,
1307 pModal->thresh62);
1308
1309 if ((eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
1310 AR5416_EEP_MINOR_VER_2) {
1311 REG_RMW_FIELD(ah, AR_PHY_RF_CTL2, AR_PHY_TX_END_DATA_START,
1312 pModal->txFrameToDataStart);
1313 REG_RMW_FIELD(ah, AR_PHY_RF_CTL2, AR_PHY_TX_END_PA_ON,
1314 pModal->txFrameToPaOn);
1880 } 1315 }
1881 1316
1882 if (AR_SREV_9280_10_OR_LATER(ah)) { 1317 if ((eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
1883 for (i = 0; i < Ar5416RateSize; i++) 1318 AR5416_EEP_MINOR_VER_3) {
1884 ratesArray[i] -= AR5416_PWR_TABLE_OFFSET * 2; 1319 if (IS_CHAN_HT40(chan))
1320 REG_RMW_FIELD(ah, AR_PHY_SETTLING,
1321 AR_PHY_SETTLING_SWITCH,
1322 pModal->swSettleHt40);
1885 } 1323 }
1886 1324
1887 REG_WRITE(ah, AR_PHY_POWER_TX_RATE1, 1325 return true;
1888 ATH9K_POW_SM(ratesArray[rate18mb], 24) 1326}
1889 | ATH9K_POW_SM(ratesArray[rate12mb], 16)
1890 | ATH9K_POW_SM(ratesArray[rate9mb], 8)
1891 | ATH9K_POW_SM(ratesArray[rate6mb], 0));
1892 REG_WRITE(ah, AR_PHY_POWER_TX_RATE2,
1893 ATH9K_POW_SM(ratesArray[rate54mb], 24)
1894 | ATH9K_POW_SM(ratesArray[rate48mb], 16)
1895 | ATH9K_POW_SM(ratesArray[rate36mb], 8)
1896 | ATH9K_POW_SM(ratesArray[rate24mb], 0));
1897 1327
1898 if (IS_CHAN_2GHZ(chan)) { 1328static u16 ath9k_hw_4k_get_eeprom_antenna_cfg(struct ath_hw *ah,
1899 REG_WRITE(ah, AR_PHY_POWER_TX_RATE3, 1329 struct ath9k_channel *chan)
1900 ATH9K_POW_SM(ratesArray[rate2s], 24) 1330{
1901 | ATH9K_POW_SM(ratesArray[rate2l], 16) 1331 struct ar5416_eeprom_4k *eep = &ah->eeprom.map4k;
1902 | ATH9K_POW_SM(ratesArray[rateXr], 8) 1332 struct modal_eep_4k_header *pModal = &eep->modalHeader;
1903 | ATH9K_POW_SM(ratesArray[rate1l], 0));
1904 REG_WRITE(ah, AR_PHY_POWER_TX_RATE4,
1905 ATH9K_POW_SM(ratesArray[rate11s], 24)
1906 | ATH9K_POW_SM(ratesArray[rate11l], 16)
1907 | ATH9K_POW_SM(ratesArray[rate5_5s], 8)
1908 | ATH9K_POW_SM(ratesArray[rate5_5l], 0));
1909 }
1910 1333
1911 REG_WRITE(ah, AR_PHY_POWER_TX_RATE5, 1334 return pModal->antCtrlCommon & 0xFFFF;
1912 ATH9K_POW_SM(ratesArray[rateHt20_3], 24) 1335}
1913 | ATH9K_POW_SM(ratesArray[rateHt20_2], 16)
1914 | ATH9K_POW_SM(ratesArray[rateHt20_1], 8)
1915 | ATH9K_POW_SM(ratesArray[rateHt20_0], 0));
1916 REG_WRITE(ah, AR_PHY_POWER_TX_RATE6,
1917 ATH9K_POW_SM(ratesArray[rateHt20_7], 24)
1918 | ATH9K_POW_SM(ratesArray[rateHt20_6], 16)
1919 | ATH9K_POW_SM(ratesArray[rateHt20_5], 8)
1920 | ATH9K_POW_SM(ratesArray[rateHt20_4], 0));
1921 1336
1922 if (IS_CHAN_HT40(chan)) { 1337static u8 ath9k_hw_4k_get_num_ant_config(struct ath_hw *ah,
1923 REG_WRITE(ah, AR_PHY_POWER_TX_RATE7, 1338 enum ieee80211_band freq_band)
1924 ATH9K_POW_SM(ratesArray[rateHt40_3] + 1339{
1925 ht40PowerIncForPdadc, 24) 1340 return 1;
1926 | ATH9K_POW_SM(ratesArray[rateHt40_2] + 1341}
1927 ht40PowerIncForPdadc, 16)
1928 | ATH9K_POW_SM(ratesArray[rateHt40_1] +
1929 ht40PowerIncForPdadc, 8)
1930 | ATH9K_POW_SM(ratesArray[rateHt40_0] +
1931 ht40PowerIncForPdadc, 0));
1932 REG_WRITE(ah, AR_PHY_POWER_TX_RATE8,
1933 ATH9K_POW_SM(ratesArray[rateHt40_7] +
1934 ht40PowerIncForPdadc, 24)
1935 | ATH9K_POW_SM(ratesArray[rateHt40_6] +
1936 ht40PowerIncForPdadc, 16)
1937 | ATH9K_POW_SM(ratesArray[rateHt40_5] +
1938 ht40PowerIncForPdadc, 8)
1939 | ATH9K_POW_SM(ratesArray[rateHt40_4] +
1940 ht40PowerIncForPdadc, 0));
1941 1342
1942 REG_WRITE(ah, AR_PHY_POWER_TX_RATE9, 1343u16 ath9k_hw_4k_get_spur_channel(struct ath_hw *ah, u16 i, bool is2GHz)
1943 ATH9K_POW_SM(ratesArray[rateExtOfdm], 24) 1344{
1944 | ATH9K_POW_SM(ratesArray[rateExtCck], 16) 1345#define EEP_MAP4K_SPURCHAN \
1945 | ATH9K_POW_SM(ratesArray[rateDupOfdm], 8) 1346 (ah->eeprom.map4k.modalHeader.spurChans[i].spurChan)
1946 | ATH9K_POW_SM(ratesArray[rateDupCck], 0));
1947 }
1948 1347
1949 i = rate6mb; 1348 u16 spur_val = AR_NO_SPUR;
1950 1349
1951 if (IS_CHAN_HT40(chan)) 1350 DPRINTF(ah->ah_sc, ATH_DBG_ANI,
1952 i = rateHt40_0; 1351 "Getting spur idx %d is2Ghz. %d val %x\n",
1953 else if (IS_CHAN_HT20(chan)) 1352 i, is2GHz, ah->config.spurchans[i][is2GHz]);
1954 i = rateHt20_0;
1955 1353
1956 if (AR_SREV_9280_10_OR_LATER(ah)) 1354 switch (ah->config.spurmode) {
1957 ah->ah_maxPowerLevel = 1355 case SPUR_DISABLE:
1958 ratesArray[i] + AR5416_PWR_TABLE_OFFSET * 2; 1356 break;
1959 else 1357 case SPUR_ENABLE_IOCTL:
1960 ah->ah_maxPowerLevel = ratesArray[i]; 1358 spur_val = ah->config.spurchans[i][is2GHz];
1359 DPRINTF(ah->ah_sc, ATH_DBG_ANI,
1360 "Getting spur val from new loc. %d\n", spur_val);
1361 break;
1362 case SPUR_ENABLE_EEPROM:
1363 spur_val = EEP_MAP4K_SPURCHAN;
1364 break;
1365 }
1961 1366
1962 return 0; 1367 return spur_val;
1368
1369#undef EEP_MAP4K_SPURCHAN
1963} 1370}
1964 1371
1965static int (*ath9k_set_txpower[]) (struct ath_hal *, 1372struct eeprom_ops eep_4k_ops = {
1966 struct ath9k_channel *, 1373 .check_eeprom = ath9k_hw_4k_check_eeprom,
1967 u16, u8, u8, u8) = { 1374 .get_eeprom = ath9k_hw_4k_get_eeprom,
1968 ath9k_hw_def_set_txpower, 1375 .fill_eeprom = ath9k_hw_4k_fill_eeprom,
1969 ath9k_hw_4k_set_txpower 1376 .get_eeprom_ver = ath9k_hw_4k_get_eeprom_ver,
1377 .get_eeprom_rev = ath9k_hw_4k_get_eeprom_rev,
1378 .get_num_ant_config = ath9k_hw_4k_get_num_ant_config,
1379 .get_eeprom_antenna_cfg = ath9k_hw_4k_get_eeprom_antenna_cfg,
1380 .set_board_values = ath9k_hw_4k_set_board_values,
1381 .set_addac = ath9k_hw_4k_set_addac,
1382 .set_txpower = ath9k_hw_4k_set_txpower,
1383 .get_spur_channel = ath9k_hw_4k_get_spur_channel
1970}; 1384};
1971 1385
1972int ath9k_hw_set_txpower(struct ath_hal *ah, 1386/************************************************/
1973 struct ath9k_channel *chan, 1387/* EEPROM Operations for non-4K (Default) cards */
1974 u16 cfgCtl, 1388/************************************************/
1975 u8 twiceAntennaReduction, 1389
1976 u8 twiceMaxRegulatoryPower, 1390static int ath9k_hw_def_get_eeprom_ver(struct ath_hw *ah)
1977 u8 powerLimit)
1978{ 1391{
1979 struct ath_hal_5416 *ahp = AH5416(ah); 1392 return ((ah->eeprom.def.baseEepHeader.version >> 12) & 0xF);
1393}
1980 1394
1981 return ath9k_set_txpower[ahp->ah_eep_map](ah, chan, cfgCtl, 1395static int ath9k_hw_def_get_eeprom_rev(struct ath_hw *ah)
1982 twiceAntennaReduction, twiceMaxRegulatoryPower, 1396{
1983 powerLimit); 1397 return ((ah->eeprom.def.baseEepHeader.version) & 0xFFF);
1984} 1398}
1985 1399
1986static void ath9k_hw_set_def_addac(struct ath_hal *ah, 1400static bool ath9k_hw_def_fill_eeprom(struct ath_hw *ah)
1987 struct ath9k_channel *chan)
1988{ 1401{
1989#define XPA_LVL_FREQ(cnt) (pModal->xpaBiasLvlFreq[cnt]) 1402#define SIZE_EEPROM_DEF (sizeof(struct ar5416_eeprom_def) / sizeof(u16))
1990 struct modal_eep_header *pModal; 1403 struct ar5416_eeprom_def *eep = &ah->eeprom.def;
1991 struct ath_hal_5416 *ahp = AH5416(ah); 1404 u16 *eep_data;
1992 struct ar5416_eeprom_def *eep = &ahp->ah_eeprom.def; 1405 int addr, ar5416_eep_start_loc = 0x100;
1993 u8 biaslevel;
1994 1406
1995 if (ah->ah_macVersion != AR_SREV_VERSION_9160) 1407 eep_data = (u16 *)eep;
1996 return;
1997 1408
1998 if (ar5416_get_eep_rev(ahp) < AR5416_EEP_MINOR_VER_7) 1409 for (addr = 0; addr < SIZE_EEPROM_DEF; addr++) {
1999 return; 1410 if (!ath9k_hw_nvram_read(ah, addr + ar5416_eep_start_loc,
1411 eep_data)) {
1412 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
1413 "Unable to read eeprom region\n");
1414 return false;
1415 }
1416 eep_data++;
1417 }
1418 return true;
1419#undef SIZE_EEPROM_DEF
1420}
2000 1421
2001 pModal = &(eep->modalHeader[IS_CHAN_2GHZ(chan)]); 1422static int ath9k_hw_def_check_eeprom(struct ath_hw *ah)
1423{
1424 struct ar5416_eeprom_def *eep =
1425 (struct ar5416_eeprom_def *) &ah->eeprom.def;
1426 u16 *eepdata, temp, magic, magic2;
1427 u32 sum = 0, el;
1428 bool need_swap = false;
1429 int i, addr, size;
2002 1430
2003 if (pModal->xpaBiasLvl != 0xff) { 1431 if (!ath9k_hw_nvram_read(ah, AR5416_EEPROM_MAGIC_OFFSET,
2004 biaslevel = pModal->xpaBiasLvl; 1432 &magic)) {
2005 } else { 1433 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
2006 u16 resetFreqBin, freqBin, freqCount = 0; 1434 "Reading Magic # failed\n");
2007 struct chan_centers centers; 1435 return false;
1436 }
2008 1437
2009 ath9k_hw_get_channel_centers(ah, chan, &centers); 1438 if (!ath9k_hw_use_flash(ah)) {
2010 1439
2011 resetFreqBin = FREQ2FBIN(centers.synth_center, 1440 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
2012 IS_CHAN_2GHZ(chan)); 1441 "Read Magic = 0x%04X\n", magic);
2013 freqBin = XPA_LVL_FREQ(0) & 0xff;
2014 biaslevel = (u8) (XPA_LVL_FREQ(0) >> 14);
2015 1442
2016 freqCount++; 1443 if (magic != AR5416_EEPROM_MAGIC) {
1444 magic2 = swab16(magic);
2017 1445
2018 while (freqCount < 3) { 1446 if (magic2 == AR5416_EEPROM_MAGIC) {
2019 if (XPA_LVL_FREQ(freqCount) == 0x0) 1447 size = sizeof(struct ar5416_eeprom_def);
2020 break; 1448 need_swap = true;
1449 eepdata = (u16 *) (&ah->eeprom);
2021 1450
2022 freqBin = XPA_LVL_FREQ(freqCount) & 0xff; 1451 for (addr = 0; addr < size / sizeof(u16); addr++) {
2023 if (resetFreqBin >= freqBin) 1452 temp = swab16(*eepdata);
2024 biaslevel = (u8)(XPA_LVL_FREQ(freqCount) >> 14); 1453 *eepdata = temp;
2025 else 1454 eepdata++;
2026 break; 1455
2027 freqCount++; 1456 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
1457 "0x%04X ", *eepdata);
1458
1459 if (((addr + 1) % 6) == 0)
1460 DPRINTF(ah->ah_sc,
1461 ATH_DBG_EEPROM, "\n");
1462 }
1463 } else {
1464 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
1465 "Invalid EEPROM Magic. "
1466 "endianness mismatch.\n");
1467 return -EINVAL;
1468 }
2028 } 1469 }
2029 } 1470 }
2030 1471
2031 if (IS_CHAN_2GHZ(chan)) { 1472 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, "need_swap = %s.\n",
2032 INI_RA(&ahp->ah_iniAddac, 7, 1) = (INI_RA(&ahp->ah_iniAddac, 1473 need_swap ? "True" : "False");
2033 7, 1) & (~0x18)) | biaslevel << 3;
2034 } else {
2035 INI_RA(&ahp->ah_iniAddac, 6, 1) = (INI_RA(&ahp->ah_iniAddac,
2036 6, 1) & (~0xc0)) | biaslevel << 6;
2037 }
2038#undef XPA_LVL_FREQ
2039}
2040 1474
2041static void ath9k_hw_set_4k_addac(struct ath_hal *ah, 1475 if (need_swap)
2042 struct ath9k_channel *chan) 1476 el = swab16(ah->eeprom.def.baseEepHeader.length);
2043{ 1477 else
2044 struct modal_eep_4k_header *pModal; 1478 el = ah->eeprom.def.baseEepHeader.length;
2045 struct ath_hal_5416 *ahp = AH5416(ah);
2046 struct ar5416_eeprom_4k *eep = &ahp->ah_eeprom.map4k;
2047 u8 biaslevel;
2048 1479
2049 if (ah->ah_macVersion != AR_SREV_VERSION_9160) 1480 if (el > sizeof(struct ar5416_eeprom_def))
2050 return; 1481 el = sizeof(struct ar5416_eeprom_def) / sizeof(u16);
1482 else
1483 el = el / sizeof(u16);
2051 1484
2052 if (ar5416_get_eep_rev(ahp) < AR5416_EEP_MINOR_VER_7) 1485 eepdata = (u16 *)(&ah->eeprom);
2053 return;
2054 1486
2055 pModal = &eep->modalHeader; 1487 for (i = 0; i < el; i++)
1488 sum ^= *eepdata++;
2056 1489
2057 if (pModal->xpaBiasLvl != 0xff) { 1490 if (need_swap) {
2058 biaslevel = pModal->xpaBiasLvl; 1491 u32 integer, j;
2059 INI_RA(&ahp->ah_iniAddac, 7, 1) = 1492 u16 word;
2060 (INI_RA(&ahp->ah_iniAddac, 7, 1) & (~0x18)) | biaslevel << 3;
2061 }
2062}
2063 1493
2064static void (*ath9k_set_addac[]) (struct ath_hal *, struct ath9k_channel *) = { 1494 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
2065 ath9k_hw_set_def_addac, 1495 "EEPROM Endianness is not native.. Changing \n");
2066 ath9k_hw_set_4k_addac
2067};
2068 1496
2069void ath9k_hw_set_addac(struct ath_hal *ah, struct ath9k_channel *chan) 1497 word = swab16(eep->baseEepHeader.length);
2070{ 1498 eep->baseEepHeader.length = word;
2071 struct ath_hal_5416 *ahp = AH5416(ah); 1499
1500 word = swab16(eep->baseEepHeader.checksum);
1501 eep->baseEepHeader.checksum = word;
1502
1503 word = swab16(eep->baseEepHeader.version);
1504 eep->baseEepHeader.version = word;
1505
1506 word = swab16(eep->baseEepHeader.regDmn[0]);
1507 eep->baseEepHeader.regDmn[0] = word;
1508
1509 word = swab16(eep->baseEepHeader.regDmn[1]);
1510 eep->baseEepHeader.regDmn[1] = word;
1511
1512 word = swab16(eep->baseEepHeader.rfSilent);
1513 eep->baseEepHeader.rfSilent = word;
1514
1515 word = swab16(eep->baseEepHeader.blueToothOptions);
1516 eep->baseEepHeader.blueToothOptions = word;
1517
1518 word = swab16(eep->baseEepHeader.deviceCap);
1519 eep->baseEepHeader.deviceCap = word;
1520
1521 for (j = 0; j < ARRAY_SIZE(eep->modalHeader); j++) {
1522 struct modal_eep_header *pModal =
1523 &eep->modalHeader[j];
1524 integer = swab32(pModal->antCtrlCommon);
1525 pModal->antCtrlCommon = integer;
2072 1526
2073 ath9k_set_addac[ahp->ah_eep_map](ah, chan); 1527 for (i = 0; i < AR5416_MAX_CHAINS; i++) {
1528 integer = swab32(pModal->antCtrlChain[i]);
1529 pModal->antCtrlChain[i] = integer;
1530 }
1531
1532 for (i = 0; i < AR5416_EEPROM_MODAL_SPURS; i++) {
1533 word = swab16(pModal->spurChans[i].spurChan);
1534 pModal->spurChans[i].spurChan = word;
1535 }
1536 }
1537 }
1538
1539 if (sum != 0xffff || ah->eep_ops->get_eeprom_ver(ah) != AR5416_EEP_VER ||
1540 ah->eep_ops->get_eeprom_rev(ah) < AR5416_EEP_NO_BACK_VER) {
1541 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
1542 "Bad EEPROM checksum 0x%x or revision 0x%04x\n",
1543 sum, ah->eep_ops->get_eeprom_ver(ah));
1544 return -EINVAL;
1545 }
1546
1547 return 0;
2074} 1548}
2075 1549
1550static u32 ath9k_hw_def_get_eeprom(struct ath_hw *ah,
1551 enum eeprom_param param)
1552{
1553#define AR5416_VER_MASK (pBase->version & AR5416_EEP_VER_MINOR_MASK)
1554 struct ar5416_eeprom_def *eep = &ah->eeprom.def;
1555 struct modal_eep_header *pModal = eep->modalHeader;
1556 struct base_eep_header *pBase = &eep->baseEepHeader;
2076 1557
1558 switch (param) {
1559 case EEP_NFTHRESH_5:
1560 return pModal[0].noiseFloorThreshCh[0];
1561 case EEP_NFTHRESH_2:
1562 return pModal[1].noiseFloorThreshCh[0];
1563 case AR_EEPROM_MAC(0):
1564 return pBase->macAddr[0] << 8 | pBase->macAddr[1];
1565 case AR_EEPROM_MAC(1):
1566 return pBase->macAddr[2] << 8 | pBase->macAddr[3];
1567 case AR_EEPROM_MAC(2):
1568 return pBase->macAddr[4] << 8 | pBase->macAddr[5];
1569 case EEP_REG_0:
1570 return pBase->regDmn[0];
1571 case EEP_REG_1:
1572 return pBase->regDmn[1];
1573 case EEP_OP_CAP:
1574 return pBase->deviceCap;
1575 case EEP_OP_MODE:
1576 return pBase->opCapFlags;
1577 case EEP_RF_SILENT:
1578 return pBase->rfSilent;
1579 case EEP_OB_5:
1580 return pModal[0].ob;
1581 case EEP_DB_5:
1582 return pModal[0].db;
1583 case EEP_OB_2:
1584 return pModal[1].ob;
1585 case EEP_DB_2:
1586 return pModal[1].db;
1587 case EEP_MINOR_REV:
1588 return AR5416_VER_MASK;
1589 case EEP_TX_MASK:
1590 return pBase->txMask;
1591 case EEP_RX_MASK:
1592 return pBase->rxMask;
1593 case EEP_RXGAIN_TYPE:
1594 return pBase->rxGainType;
1595 case EEP_TXGAIN_TYPE:
1596 return pBase->txGainType;
1597 case EEP_DAC_HPWR_5G:
1598 if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_20)
1599 return pBase->dacHiPwrMode_5G;
1600 else
1601 return 0;
1602 default:
1603 return 0;
1604 }
1605#undef AR5416_VER_MASK
1606}
2077 1607
2078/* XXX: Clean me up, make me more legible */ 1608/* XXX: Clean me up, make me more legible */
2079static bool ath9k_hw_eeprom_set_def_board_values(struct ath_hal *ah, 1609static bool ath9k_hw_def_set_board_values(struct ath_hw *ah,
2080 struct ath9k_channel *chan) 1610 struct ath9k_channel *chan)
2081{ 1611{
2082#define AR5416_VER_MASK (eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) 1612#define AR5416_VER_MASK (eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK)
2083 struct modal_eep_header *pModal; 1613 struct modal_eep_header *pModal;
2084 struct ath_hal_5416 *ahp = AH5416(ah); 1614 struct ar5416_eeprom_def *eep = &ah->eeprom.def;
2085 struct ar5416_eeprom_def *eep = &ahp->ah_eeprom.def;
2086 int i, regChainOffset; 1615 int i, regChainOffset;
2087 u8 txRxAttenLocal; 1616 u8 txRxAttenLocal;
2088 1617
@@ -2091,7 +1620,7 @@ static bool ath9k_hw_eeprom_set_def_board_values(struct ath_hal *ah,
2091 txRxAttenLocal = IS_CHAN_2GHZ(chan) ? 23 : 44; 1620 txRxAttenLocal = IS_CHAN_2GHZ(chan) ? 23 : 44;
2092 1621
2093 REG_WRITE(ah, AR_PHY_SWITCH_COM, 1622 REG_WRITE(ah, AR_PHY_SWITCH_COM,
2094 ath9k_hw_get_eeprom_antenna_cfg(ah, chan)); 1623 ah->eep_ops->get_eeprom_antenna_cfg(ah, chan));
2095 1624
2096 for (i = 0; i < AR5416_MAX_CHAINS; i++) { 1625 for (i = 0; i < AR5416_MAX_CHAINS; i++) {
2097 if (AR_SREV_9280(ah)) { 1626 if (AR_SREV_9280(ah)) {
@@ -2100,7 +1629,7 @@ static bool ath9k_hw_eeprom_set_def_board_values(struct ath_hal *ah,
2100 } 1629 }
2101 1630
2102 if (AR_SREV_5416_V20_OR_LATER(ah) && 1631 if (AR_SREV_5416_V20_OR_LATER(ah) &&
2103 (ahp->ah_rxchainmask == 5 || ahp->ah_txchainmask == 5) 1632 (ah->rxchainmask == 5 || ah->txchainmask == 5)
2104 && (i != 0)) 1633 && (i != 0))
2105 regChainOffset = (i == 1) ? 0x2000 : 0x1000; 1634 regChainOffset = (i == 1) ? 0x2000 : 0x1000;
2106 else 1635 else
@@ -2321,253 +1850,778 @@ static bool ath9k_hw_eeprom_set_def_board_values(struct ath_hal *ah,
2321#undef AR5416_VER_MASK 1850#undef AR5416_VER_MASK
2322} 1851}
2323 1852
2324static bool ath9k_hw_eeprom_set_4k_board_values(struct ath_hal *ah, 1853static void ath9k_hw_def_set_addac(struct ath_hw *ah,
2325 struct ath9k_channel *chan) 1854 struct ath9k_channel *chan)
2326{ 1855{
2327 struct modal_eep_4k_header *pModal; 1856#define XPA_LVL_FREQ(cnt) (pModal->xpaBiasLvlFreq[cnt])
2328 struct ath_hal_5416 *ahp = AH5416(ah); 1857 struct modal_eep_header *pModal;
2329 struct ar5416_eeprom_4k *eep = &ahp->ah_eeprom.map4k; 1858 struct ar5416_eeprom_def *eep = &ah->eeprom.def;
2330 int regChainOffset; 1859 u8 biaslevel;
2331 u8 txRxAttenLocal;
2332 u8 ob[5], db1[5], db2[5];
2333 u8 ant_div_control1, ant_div_control2;
2334 u32 regVal;
2335 1860
1861 if (ah->hw_version.macVersion != AR_SREV_VERSION_9160)
1862 return;
2336 1863
2337 pModal = &eep->modalHeader; 1864 if (ah->eep_ops->get_eeprom_rev(ah) < AR5416_EEP_MINOR_VER_7)
1865 return;
2338 1866
2339 txRxAttenLocal = 23; 1867 pModal = &(eep->modalHeader[IS_CHAN_2GHZ(chan)]);
2340 1868
2341 REG_WRITE(ah, AR_PHY_SWITCH_COM, 1869 if (pModal->xpaBiasLvl != 0xff) {
2342 ath9k_hw_get_eeprom_antenna_cfg(ah, chan)); 1870 biaslevel = pModal->xpaBiasLvl;
1871 } else {
1872 u16 resetFreqBin, freqBin, freqCount = 0;
1873 struct chan_centers centers;
2343 1874
2344 regChainOffset = 0; 1875 ath9k_hw_get_channel_centers(ah, chan, &centers);
2345 REG_WRITE(ah, AR_PHY_SWITCH_CHAIN_0 + regChainOffset,
2346 pModal->antCtrlChain[0]);
2347 1876
2348 REG_WRITE(ah, AR_PHY_TIMING_CTRL4(0) + regChainOffset, 1877 resetFreqBin = FREQ2FBIN(centers.synth_center,
2349 (REG_READ(ah, AR_PHY_TIMING_CTRL4(0) + regChainOffset) & 1878 IS_CHAN_2GHZ(chan));
2350 ~(AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF | 1879 freqBin = XPA_LVL_FREQ(0) & 0xff;
2351 AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF)) | 1880 biaslevel = (u8) (XPA_LVL_FREQ(0) >> 14);
2352 SM(pModal->iqCalICh[0], AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF) |
2353 SM(pModal->iqCalQCh[0], AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF));
2354 1881
2355 if ((eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >= 1882 freqCount++;
2356 AR5416_EEP_MINOR_VER_3) {
2357 txRxAttenLocal = pModal->txRxAttenCh[0];
2358 REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
2359 AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN, pModal->bswMargin[0]);
2360 REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
2361 AR_PHY_GAIN_2GHZ_XATTEN1_DB, pModal->bswAtten[0]);
2362 REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
2363 AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN,
2364 pModal->xatten2Margin[0]);
2365 REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
2366 AR_PHY_GAIN_2GHZ_XATTEN2_DB, pModal->xatten2Db[0]);
2367 }
2368 1883
2369 REG_RMW_FIELD(ah, AR_PHY_RXGAIN + regChainOffset, 1884 while (freqCount < 3) {
2370 AR9280_PHY_RXGAIN_TXRX_ATTEN, txRxAttenLocal); 1885 if (XPA_LVL_FREQ(freqCount) == 0x0)
2371 REG_RMW_FIELD(ah, AR_PHY_RXGAIN + regChainOffset, 1886 break;
2372 AR9280_PHY_RXGAIN_TXRX_MARGIN, pModal->rxTxMarginCh[0]);
2373 1887
2374 if (AR_SREV_9285_11(ah)) 1888 freqBin = XPA_LVL_FREQ(freqCount) & 0xff;
2375 REG_WRITE(ah, AR9285_AN_TOP4, (AR9285_AN_TOP4_DEFAULT | 0x14)); 1889 if (resetFreqBin >= freqBin)
1890 biaslevel = (u8)(XPA_LVL_FREQ(freqCount) >> 14);
1891 else
1892 break;
1893 freqCount++;
1894 }
1895 }
2376 1896
2377 /* Initialize Ant Diversity settings from EEPROM */ 1897 if (IS_CHAN_2GHZ(chan)) {
2378 if (pModal->version == 3) { 1898 INI_RA(&ah->iniAddac, 7, 1) = (INI_RA(&ah->iniAddac,
2379 ant_div_control1 = ((pModal->ob_234 >> 12) & 0xf); 1899 7, 1) & (~0x18)) | biaslevel << 3;
2380 ant_div_control2 = ((pModal->db1_234 >> 12) & 0xf); 1900 } else {
2381 regVal = REG_READ(ah, 0x99ac); 1901 INI_RA(&ah->iniAddac, 6, 1) = (INI_RA(&ah->iniAddac,
2382 regVal &= (~(0x7f000000)); 1902 6, 1) & (~0xc0)) | biaslevel << 6;
2383 regVal |= ((ant_div_control1 & 0x1) << 24);
2384 regVal |= (((ant_div_control1 >> 1) & 0x1) << 29);
2385 regVal |= (((ant_div_control1 >> 2) & 0x1) << 30);
2386 regVal |= ((ant_div_control2 & 0x3) << 25);
2387 regVal |= (((ant_div_control2 >> 2) & 0x3) << 27);
2388 REG_WRITE(ah, 0x99ac, regVal);
2389 regVal = REG_READ(ah, 0x99ac);
2390 regVal = REG_READ(ah, 0xa208);
2391 regVal &= (~(0x1 << 13));
2392 regVal |= (((ant_div_control1 >> 3) & 0x1) << 13);
2393 REG_WRITE(ah, 0xa208, regVal);
2394 regVal = REG_READ(ah, 0xa208);
2395 } 1903 }
1904#undef XPA_LVL_FREQ
1905}
2396 1906
2397 if (pModal->version >= 2) { 1907static void ath9k_hw_get_def_gain_boundaries_pdadcs(struct ath_hw *ah,
2398 ob[0] = (pModal->ob_01 & 0xf); 1908 struct ath9k_channel *chan,
2399 ob[1] = (pModal->ob_01 >> 4) & 0xf; 1909 struct cal_data_per_freq *pRawDataSet,
2400 ob[2] = (pModal->ob_234 & 0xf); 1910 u8 *bChans, u16 availPiers,
2401 ob[3] = ((pModal->ob_234 >> 4) & 0xf); 1911 u16 tPdGainOverlap, int16_t *pMinCalPower,
2402 ob[4] = ((pModal->ob_234 >> 8) & 0xf); 1912 u16 *pPdGainBoundaries, u8 *pPDADCValues,
1913 u16 numXpdGains)
1914{
1915 int i, j, k;
1916 int16_t ss;
1917 u16 idxL = 0, idxR = 0, numPiers;
1918 static u8 vpdTableL[AR5416_NUM_PD_GAINS]
1919 [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
1920 static u8 vpdTableR[AR5416_NUM_PD_GAINS]
1921 [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
1922 static u8 vpdTableI[AR5416_NUM_PD_GAINS]
1923 [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
2403 1924
2404 db1[0] = (pModal->db1_01 & 0xf); 1925 u8 *pVpdL, *pVpdR, *pPwrL, *pPwrR;
2405 db1[1] = ((pModal->db1_01 >> 4) & 0xf); 1926 u8 minPwrT4[AR5416_NUM_PD_GAINS];
2406 db1[2] = (pModal->db1_234 & 0xf); 1927 u8 maxPwrT4[AR5416_NUM_PD_GAINS];
2407 db1[3] = ((pModal->db1_234 >> 4) & 0xf); 1928 int16_t vpdStep;
2408 db1[4] = ((pModal->db1_234 >> 8) & 0xf); 1929 int16_t tmpVal;
1930 u16 sizeCurrVpdTable, maxIndex, tgtIndex;
1931 bool match;
1932 int16_t minDelta = 0;
1933 struct chan_centers centers;
2409 1934
2410 db2[0] = (pModal->db2_01 & 0xf); 1935 ath9k_hw_get_channel_centers(ah, chan, &centers);
2411 db2[1] = ((pModal->db2_01 >> 4) & 0xf);
2412 db2[2] = (pModal->db2_234 & 0xf);
2413 db2[3] = ((pModal->db2_234 >> 4) & 0xf);
2414 db2[4] = ((pModal->db2_234 >> 8) & 0xf);
2415 1936
2416 } else if (pModal->version == 1) { 1937 for (numPiers = 0; numPiers < availPiers; numPiers++) {
1938 if (bChans[numPiers] == AR5416_BCHAN_UNUSED)
1939 break;
1940 }
2417 1941
2418 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, 1942 match = ath9k_hw_get_lower_upper_index((u8)FREQ2FBIN(centers.synth_center,
2419 "EEPROM Model version is set to 1 \n"); 1943 IS_CHAN_2GHZ(chan)),
2420 ob[0] = (pModal->ob_01 & 0xf); 1944 bChans, numPiers, &idxL, &idxR);
2421 ob[1] = ob[2] = ob[3] = ob[4] = (pModal->ob_01 >> 4) & 0xf; 1945
2422 db1[0] = (pModal->db1_01 & 0xf); 1946 if (match) {
2423 db1[1] = db1[2] = db1[3] = 1947 for (i = 0; i < numXpdGains; i++) {
2424 db1[4] = ((pModal->db1_01 >> 4) & 0xf); 1948 minPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][0];
2425 db2[0] = (pModal->db2_01 & 0xf); 1949 maxPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][4];
2426 db2[1] = db2[2] = db2[3] = 1950 ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
2427 db2[4] = ((pModal->db2_01 >> 4) & 0xf); 1951 pRawDataSet[idxL].pwrPdg[i],
1952 pRawDataSet[idxL].vpdPdg[i],
1953 AR5416_PD_GAIN_ICEPTS,
1954 vpdTableI[i]);
1955 }
2428 } else { 1956 } else {
2429 int i; 1957 for (i = 0; i < numXpdGains; i++) {
2430 for (i = 0; i < 5; i++) { 1958 pVpdL = pRawDataSet[idxL].vpdPdg[i];
2431 ob[i] = pModal->ob_01; 1959 pPwrL = pRawDataSet[idxL].pwrPdg[i];
2432 db1[i] = pModal->db1_01; 1960 pVpdR = pRawDataSet[idxR].vpdPdg[i];
2433 db2[i] = pModal->db1_01; 1961 pPwrR = pRawDataSet[idxR].pwrPdg[i];
1962
1963 minPwrT4[i] = max(pPwrL[0], pPwrR[0]);
1964
1965 maxPwrT4[i] =
1966 min(pPwrL[AR5416_PD_GAIN_ICEPTS - 1],
1967 pPwrR[AR5416_PD_GAIN_ICEPTS - 1]);
1968
1969
1970 ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
1971 pPwrL, pVpdL,
1972 AR5416_PD_GAIN_ICEPTS,
1973 vpdTableL[i]);
1974 ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
1975 pPwrR, pVpdR,
1976 AR5416_PD_GAIN_ICEPTS,
1977 vpdTableR[i]);
1978
1979 for (j = 0; j <= (maxPwrT4[i] - minPwrT4[i]) / 2; j++) {
1980 vpdTableI[i][j] =
1981 (u8)(ath9k_hw_interpolate((u16)
1982 FREQ2FBIN(centers.
1983 synth_center,
1984 IS_CHAN_2GHZ
1985 (chan)),
1986 bChans[idxL], bChans[idxR],
1987 vpdTableL[i][j], vpdTableR[i][j]));
1988 }
2434 } 1989 }
2435 } 1990 }
2436 1991
2437 ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3, 1992 *pMinCalPower = (int16_t)(minPwrT4[0] / 2);
2438 AR9285_AN_RF2G3_OB_0, AR9285_AN_RF2G3_OB_0_S, ob[0]);
2439 ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3,
2440 AR9285_AN_RF2G3_OB_1, AR9285_AN_RF2G3_OB_1_S, ob[1]);
2441 ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3,
2442 AR9285_AN_RF2G3_OB_2, AR9285_AN_RF2G3_OB_2_S, ob[2]);
2443 ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3,
2444 AR9285_AN_RF2G3_OB_3, AR9285_AN_RF2G3_OB_3_S, ob[3]);
2445 ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3,
2446 AR9285_AN_RF2G3_OB_4, AR9285_AN_RF2G3_OB_4_S, ob[4]);
2447 1993
2448 ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3, 1994 k = 0;
2449 AR9285_AN_RF2G3_DB1_0, AR9285_AN_RF2G3_DB1_0_S, db1[0]);
2450 ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3,
2451 AR9285_AN_RF2G3_DB1_1, AR9285_AN_RF2G3_DB1_1_S, db1[1]);
2452 ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3,
2453 AR9285_AN_RF2G3_DB1_2, AR9285_AN_RF2G3_DB1_2_S, db1[2]);
2454 ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4,
2455 AR9285_AN_RF2G4_DB1_3, AR9285_AN_RF2G4_DB1_3_S, db1[3]);
2456 ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4,
2457 AR9285_AN_RF2G4_DB1_4, AR9285_AN_RF2G4_DB1_4_S, db1[4]);
2458 1995
2459 ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4, 1996 for (i = 0; i < numXpdGains; i++) {
2460 AR9285_AN_RF2G4_DB2_0, AR9285_AN_RF2G4_DB2_0_S, db2[0]); 1997 if (i == (numXpdGains - 1))
2461 ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4, 1998 pPdGainBoundaries[i] =
2462 AR9285_AN_RF2G4_DB2_1, AR9285_AN_RF2G4_DB2_1_S, db2[1]); 1999 (u16)(maxPwrT4[i] / 2);
2463 ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4, 2000 else
2464 AR9285_AN_RF2G4_DB2_2, AR9285_AN_RF2G4_DB2_2_S, db2[2]); 2001 pPdGainBoundaries[i] =
2465 ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4, 2002 (u16)((maxPwrT4[i] + minPwrT4[i + 1]) / 4);
2466 AR9285_AN_RF2G4_DB2_3, AR9285_AN_RF2G4_DB2_3_S, db2[3]);
2467 ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4,
2468 AR9285_AN_RF2G4_DB2_4, AR9285_AN_RF2G4_DB2_4_S, db2[4]);
2469 2003
2004 pPdGainBoundaries[i] =
2005 min((u16)AR5416_MAX_RATE_POWER, pPdGainBoundaries[i]);
2470 2006
2471 if (AR_SREV_9285_11(ah)) 2007 if ((i == 0) && !AR_SREV_5416_V20_OR_LATER(ah)) {
2472 REG_WRITE(ah, AR9285_AN_TOP4, AR9285_AN_TOP4_DEFAULT); 2008 minDelta = pPdGainBoundaries[0] - 23;
2009 pPdGainBoundaries[0] = 23;
2010 } else {
2011 minDelta = 0;
2012 }
2473 2013
2474 REG_RMW_FIELD(ah, AR_PHY_SETTLING, AR_PHY_SETTLING_SWITCH, 2014 if (i == 0) {
2475 pModal->switchSettling); 2015 if (AR_SREV_9280_10_OR_LATER(ah))
2476 REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ, AR_PHY_DESIRED_SZ_ADC, 2016 ss = (int16_t)(0 - (minPwrT4[i] / 2));
2477 pModal->adcDesiredSize); 2017 else
2018 ss = 0;
2019 } else {
2020 ss = (int16_t)((pPdGainBoundaries[i - 1] -
2021 (minPwrT4[i] / 2)) -
2022 tPdGainOverlap + 1 + minDelta);
2023 }
2024 vpdStep = (int16_t)(vpdTableI[i][1] - vpdTableI[i][0]);
2025 vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep);
2478 2026
2479 REG_WRITE(ah, AR_PHY_RF_CTL4, 2027 while ((ss < 0) && (k < (AR5416_NUM_PDADC_VALUES - 1))) {
2480 SM(pModal->txEndToXpaOff, AR_PHY_RF_CTL4_TX_END_XPAA_OFF) | 2028 tmpVal = (int16_t)(vpdTableI[i][0] + ss * vpdStep);
2481 SM(pModal->txEndToXpaOff, AR_PHY_RF_CTL4_TX_END_XPAB_OFF) | 2029 pPDADCValues[k++] = (u8)((tmpVal < 0) ? 0 : tmpVal);
2482 SM(pModal->txFrameToXpaOn, AR_PHY_RF_CTL4_FRAME_XPAA_ON) | 2030 ss++;
2483 SM(pModal->txFrameToXpaOn, AR_PHY_RF_CTL4_FRAME_XPAB_ON)); 2031 }
2484 2032
2485 REG_RMW_FIELD(ah, AR_PHY_RF_CTL3, AR_PHY_TX_END_TO_A2_RX_ON, 2033 sizeCurrVpdTable = (u8) ((maxPwrT4[i] - minPwrT4[i]) / 2 + 1);
2486 pModal->txEndToRxOn); 2034 tgtIndex = (u8)(pPdGainBoundaries[i] + tPdGainOverlap -
2487 REG_RMW_FIELD(ah, AR_PHY_CCA, AR9280_PHY_CCA_THRESH62, 2035 (minPwrT4[i] / 2));
2488 pModal->thresh62); 2036 maxIndex = (tgtIndex < sizeCurrVpdTable) ?
2489 REG_RMW_FIELD(ah, AR_PHY_EXT_CCA0, AR_PHY_EXT_CCA0_THRESH62, 2037 tgtIndex : sizeCurrVpdTable;
2490 pModal->thresh62);
2491 2038
2492 if ((eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >= 2039 while ((ss < maxIndex) && (k < (AR5416_NUM_PDADC_VALUES - 1))) {
2493 AR5416_EEP_MINOR_VER_2) { 2040 pPDADCValues[k++] = vpdTableI[i][ss++];
2494 REG_RMW_FIELD(ah, AR_PHY_RF_CTL2, AR_PHY_TX_END_DATA_START, 2041 }
2495 pModal->txFrameToDataStart); 2042
2496 REG_RMW_FIELD(ah, AR_PHY_RF_CTL2, AR_PHY_TX_END_PA_ON, 2043 vpdStep = (int16_t)(vpdTableI[i][sizeCurrVpdTable - 1] -
2497 pModal->txFrameToPaOn); 2044 vpdTableI[i][sizeCurrVpdTable - 2]);
2045 vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep);
2046
2047 if (tgtIndex > maxIndex) {
2048 while ((ss <= tgtIndex) &&
2049 (k < (AR5416_NUM_PDADC_VALUES - 1))) {
2050 tmpVal = (int16_t)((vpdTableI[i][sizeCurrVpdTable - 1] +
2051 (ss - maxIndex + 1) * vpdStep));
2052 pPDADCValues[k++] = (u8)((tmpVal > 255) ?
2053 255 : tmpVal);
2054 ss++;
2055 }
2056 }
2498 } 2057 }
2499 2058
2500 if ((eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >= 2059 while (i < AR5416_PD_GAINS_IN_MASK) {
2501 AR5416_EEP_MINOR_VER_3) { 2060 pPdGainBoundaries[i] = pPdGainBoundaries[i - 1];
2502 if (IS_CHAN_HT40(chan)) 2061 i++;
2503 REG_RMW_FIELD(ah, AR_PHY_SETTLING,
2504 AR_PHY_SETTLING_SWITCH,
2505 pModal->swSettleHt40);
2506 } 2062 }
2507 2063
2508 return true; 2064 while (k < AR5416_NUM_PDADC_VALUES) {
2509} 2065 pPDADCValues[k] = pPDADCValues[k - 1];
2066 k++;
2067 }
2510 2068
2511static bool (*ath9k_eeprom_set_board_values[])(struct ath_hal *, 2069 return;
2512 struct ath9k_channel *) = { 2070}
2513 ath9k_hw_eeprom_set_def_board_values,
2514 ath9k_hw_eeprom_set_4k_board_values
2515};
2516 2071
2517bool ath9k_hw_eeprom_set_board_values(struct ath_hal *ah, 2072static bool ath9k_hw_set_def_power_cal_table(struct ath_hw *ah,
2518 struct ath9k_channel *chan) 2073 struct ath9k_channel *chan,
2074 int16_t *pTxPowerIndexOffset)
2519{ 2075{
2520 struct ath_hal_5416 *ahp = AH5416(ah); 2076 struct ar5416_eeprom_def *pEepData = &ah->eeprom.def;
2077 struct cal_data_per_freq *pRawDataset;
2078 u8 *pCalBChans = NULL;
2079 u16 pdGainOverlap_t2;
2080 static u8 pdadcValues[AR5416_NUM_PDADC_VALUES];
2081 u16 gainBoundaries[AR5416_PD_GAINS_IN_MASK];
2082 u16 numPiers, i, j;
2083 int16_t tMinCalPower;
2084 u16 numXpdGain, xpdMask;
2085 u16 xpdGainValues[AR5416_NUM_PD_GAINS] = { 0, 0, 0, 0 };
2086 u32 reg32, regOffset, regChainOffset;
2087 int16_t modalIdx;
2521 2088
2522 return ath9k_eeprom_set_board_values[ahp->ah_eep_map](ah, chan); 2089 modalIdx = IS_CHAN_2GHZ(chan) ? 1 : 0;
2523} 2090 xpdMask = pEepData->modalHeader[modalIdx].xpdGain;
2524 2091
2525static u16 ath9k_hw_get_def_eeprom_antenna_cfg(struct ath_hal *ah, 2092 if ((pEepData->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
2526 struct ath9k_channel *chan) 2093 AR5416_EEP_MINOR_VER_2) {
2527{ 2094 pdGainOverlap_t2 =
2528 struct ath_hal_5416 *ahp = AH5416(ah); 2095 pEepData->modalHeader[modalIdx].pdGainOverlap;
2529 struct ar5416_eeprom_def *eep = &ahp->ah_eeprom.def; 2096 } else {
2530 struct modal_eep_header *pModal = 2097 pdGainOverlap_t2 = (u16)(MS(REG_READ(ah, AR_PHY_TPCRG5),
2531 &(eep->modalHeader[IS_CHAN_2GHZ(chan)]); 2098 AR_PHY_TPCRG5_PD_GAIN_OVERLAP));
2099 }
2532 2100
2533 return pModal->antCtrlCommon & 0xFFFF; 2101 if (IS_CHAN_2GHZ(chan)) {
2102 pCalBChans = pEepData->calFreqPier2G;
2103 numPiers = AR5416_NUM_2G_CAL_PIERS;
2104 } else {
2105 pCalBChans = pEepData->calFreqPier5G;
2106 numPiers = AR5416_NUM_5G_CAL_PIERS;
2107 }
2108
2109 numXpdGain = 0;
2110
2111 for (i = 1; i <= AR5416_PD_GAINS_IN_MASK; i++) {
2112 if ((xpdMask >> (AR5416_PD_GAINS_IN_MASK - i)) & 1) {
2113 if (numXpdGain >= AR5416_NUM_PD_GAINS)
2114 break;
2115 xpdGainValues[numXpdGain] =
2116 (u16)(AR5416_PD_GAINS_IN_MASK - i);
2117 numXpdGain++;
2118 }
2119 }
2120
2121 REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_NUM_PD_GAIN,
2122 (numXpdGain - 1) & 0x3);
2123 REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_1,
2124 xpdGainValues[0]);
2125 REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_2,
2126 xpdGainValues[1]);
2127 REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_3,
2128 xpdGainValues[2]);
2129
2130 for (i = 0; i < AR5416_MAX_CHAINS; i++) {
2131 if (AR_SREV_5416_V20_OR_LATER(ah) &&
2132 (ah->rxchainmask == 5 || ah->txchainmask == 5) &&
2133 (i != 0)) {
2134 regChainOffset = (i == 1) ? 0x2000 : 0x1000;
2135 } else
2136 regChainOffset = i * 0x1000;
2137
2138 if (pEepData->baseEepHeader.txMask & (1 << i)) {
2139 if (IS_CHAN_2GHZ(chan))
2140 pRawDataset = pEepData->calPierData2G[i];
2141 else
2142 pRawDataset = pEepData->calPierData5G[i];
2143
2144 ath9k_hw_get_def_gain_boundaries_pdadcs(ah, chan,
2145 pRawDataset, pCalBChans,
2146 numPiers, pdGainOverlap_t2,
2147 &tMinCalPower, gainBoundaries,
2148 pdadcValues, numXpdGain);
2149
2150 if ((i == 0) || AR_SREV_5416_V20_OR_LATER(ah)) {
2151 REG_WRITE(ah,
2152 AR_PHY_TPCRG5 + regChainOffset,
2153 SM(pdGainOverlap_t2,
2154 AR_PHY_TPCRG5_PD_GAIN_OVERLAP)
2155 | SM(gainBoundaries[0],
2156 AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1)
2157 | SM(gainBoundaries[1],
2158 AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2)
2159 | SM(gainBoundaries[2],
2160 AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3)
2161 | SM(gainBoundaries[3],
2162 AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4));
2163 }
2164
2165 regOffset = AR_PHY_BASE + (672 << 2) + regChainOffset;
2166 for (j = 0; j < 32; j++) {
2167 reg32 = ((pdadcValues[4 * j + 0] & 0xFF) << 0) |
2168 ((pdadcValues[4 * j + 1] & 0xFF) << 8) |
2169 ((pdadcValues[4 * j + 2] & 0xFF) << 16)|
2170 ((pdadcValues[4 * j + 3] & 0xFF) << 24);
2171 REG_WRITE(ah, regOffset, reg32);
2172
2173 DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
2174 "PDADC (%d,%4x): %4.4x %8.8x\n",
2175 i, regChainOffset, regOffset,
2176 reg32);
2177 DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
2178 "PDADC: Chain %d | PDADC %3d "
2179 "Value %3d | PDADC %3d Value %3d | "
2180 "PDADC %3d Value %3d | PDADC %3d "
2181 "Value %3d |\n",
2182 i, 4 * j, pdadcValues[4 * j],
2183 4 * j + 1, pdadcValues[4 * j + 1],
2184 4 * j + 2, pdadcValues[4 * j + 2],
2185 4 * j + 3,
2186 pdadcValues[4 * j + 3]);
2187
2188 regOffset += 4;
2189 }
2190 }
2191 }
2192
2193 *pTxPowerIndexOffset = 0;
2194
2195 return true;
2534} 2196}
2535 2197
2536static u16 ath9k_hw_get_4k_eeprom_antenna_cfg(struct ath_hal *ah, 2198static bool ath9k_hw_set_def_power_per_rate_table(struct ath_hw *ah,
2537 struct ath9k_channel *chan) 2199 struct ath9k_channel *chan,
2200 int16_t *ratesArray,
2201 u16 cfgCtl,
2202 u16 AntennaReduction,
2203 u16 twiceMaxRegulatoryPower,
2204 u16 powerLimit)
2538{ 2205{
2539 struct ath_hal_5416 *ahp = AH5416(ah); 2206#define REDUCE_SCALED_POWER_BY_TWO_CHAIN 6 /* 10*log10(2)*2 */
2540 struct ar5416_eeprom_4k *eep = &ahp->ah_eeprom.map4k; 2207#define REDUCE_SCALED_POWER_BY_THREE_CHAIN 10 /* 10*log10(3)*2 */
2541 struct modal_eep_4k_header *pModal = &eep->modalHeader;
2542 2208
2543 return pModal->antCtrlCommon & 0xFFFF; 2209 struct ar5416_eeprom_def *pEepData = &ah->eeprom.def;
2544} 2210 u16 twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
2211 static const u16 tpScaleReductionTable[5] =
2212 { 0, 3, 6, 9, AR5416_MAX_RATE_POWER };
2545 2213
2546static u16 (*ath9k_get_eeprom_antenna_cfg[])(struct ath_hal *, 2214 int i;
2547 struct ath9k_channel *) = { 2215 int16_t twiceLargestAntenna;
2548 ath9k_hw_get_def_eeprom_antenna_cfg, 2216 struct cal_ctl_data *rep;
2549 ath9k_hw_get_4k_eeprom_antenna_cfg 2217 struct cal_target_power_leg targetPowerOfdm, targetPowerCck = {
2550}; 2218 0, { 0, 0, 0, 0}
2219 };
2220 struct cal_target_power_leg targetPowerOfdmExt = {
2221 0, { 0, 0, 0, 0} }, targetPowerCckExt = {
2222 0, { 0, 0, 0, 0 }
2223 };
2224 struct cal_target_power_ht targetPowerHt20, targetPowerHt40 = {
2225 0, {0, 0, 0, 0}
2226 };
2227 u16 scaledPower = 0, minCtlPower, maxRegAllowedPower;
2228 u16 ctlModesFor11a[] =
2229 { CTL_11A, CTL_5GHT20, CTL_11A_EXT, CTL_5GHT40 };
2230 u16 ctlModesFor11g[] =
2231 { CTL_11B, CTL_11G, CTL_2GHT20, CTL_11B_EXT, CTL_11G_EXT,
2232 CTL_2GHT40
2233 };
2234 u16 numCtlModes, *pCtlMode, ctlMode, freq;
2235 struct chan_centers centers;
2236 int tx_chainmask;
2237 u16 twiceMinEdgePower;
2551 2238
2552u16 ath9k_hw_get_eeprom_antenna_cfg(struct ath_hal *ah, 2239 tx_chainmask = ah->txchainmask;
2553 struct ath9k_channel *chan) 2240
2554{ 2241 ath9k_hw_get_channel_centers(ah, chan, &centers);
2555 struct ath_hal_5416 *ahp = AH5416(ah); 2242
2243 twiceLargestAntenna = max(
2244 pEepData->modalHeader
2245 [IS_CHAN_2GHZ(chan)].antennaGainCh[0],
2246 pEepData->modalHeader
2247 [IS_CHAN_2GHZ(chan)].antennaGainCh[1]);
2248
2249 twiceLargestAntenna = max((u8)twiceLargestAntenna,
2250 pEepData->modalHeader
2251 [IS_CHAN_2GHZ(chan)].antennaGainCh[2]);
2252
2253 twiceLargestAntenna = (int16_t)min(AntennaReduction -
2254 twiceLargestAntenna, 0);
2255
2256 maxRegAllowedPower = twiceMaxRegulatoryPower + twiceLargestAntenna;
2257
2258 if (ah->regulatory.tp_scale != ATH9K_TP_SCALE_MAX) {
2259 maxRegAllowedPower -=
2260 (tpScaleReductionTable[(ah->regulatory.tp_scale)] * 2);
2261 }
2262
2263 scaledPower = min(powerLimit, maxRegAllowedPower);
2264
2265 switch (ar5416_get_ntxchains(tx_chainmask)) {
2266 case 1:
2267 break;
2268 case 2:
2269 scaledPower -= REDUCE_SCALED_POWER_BY_TWO_CHAIN;
2270 break;
2271 case 3:
2272 scaledPower -= REDUCE_SCALED_POWER_BY_THREE_CHAIN;
2273 break;
2274 }
2275
2276 scaledPower = max((u16)0, scaledPower);
2277
2278 if (IS_CHAN_2GHZ(chan)) {
2279 numCtlModes = ARRAY_SIZE(ctlModesFor11g) -
2280 SUB_NUM_CTL_MODES_AT_2G_40;
2281 pCtlMode = ctlModesFor11g;
2282
2283 ath9k_hw_get_legacy_target_powers(ah, chan,
2284 pEepData->calTargetPowerCck,
2285 AR5416_NUM_2G_CCK_TARGET_POWERS,
2286 &targetPowerCck, 4, false);
2287 ath9k_hw_get_legacy_target_powers(ah, chan,
2288 pEepData->calTargetPower2G,
2289 AR5416_NUM_2G_20_TARGET_POWERS,
2290 &targetPowerOfdm, 4, false);
2291 ath9k_hw_get_target_powers(ah, chan,
2292 pEepData->calTargetPower2GHT20,
2293 AR5416_NUM_2G_20_TARGET_POWERS,
2294 &targetPowerHt20, 8, false);
2295
2296 if (IS_CHAN_HT40(chan)) {
2297 numCtlModes = ARRAY_SIZE(ctlModesFor11g);
2298 ath9k_hw_get_target_powers(ah, chan,
2299 pEepData->calTargetPower2GHT40,
2300 AR5416_NUM_2G_40_TARGET_POWERS,
2301 &targetPowerHt40, 8, true);
2302 ath9k_hw_get_legacy_target_powers(ah, chan,
2303 pEepData->calTargetPowerCck,
2304 AR5416_NUM_2G_CCK_TARGET_POWERS,
2305 &targetPowerCckExt, 4, true);
2306 ath9k_hw_get_legacy_target_powers(ah, chan,
2307 pEepData->calTargetPower2G,
2308 AR5416_NUM_2G_20_TARGET_POWERS,
2309 &targetPowerOfdmExt, 4, true);
2310 }
2311 } else {
2312 numCtlModes = ARRAY_SIZE(ctlModesFor11a) -
2313 SUB_NUM_CTL_MODES_AT_5G_40;
2314 pCtlMode = ctlModesFor11a;
2315
2316 ath9k_hw_get_legacy_target_powers(ah, chan,
2317 pEepData->calTargetPower5G,
2318 AR5416_NUM_5G_20_TARGET_POWERS,
2319 &targetPowerOfdm, 4, false);
2320 ath9k_hw_get_target_powers(ah, chan,
2321 pEepData->calTargetPower5GHT20,
2322 AR5416_NUM_5G_20_TARGET_POWERS,
2323 &targetPowerHt20, 8, false);
2324
2325 if (IS_CHAN_HT40(chan)) {
2326 numCtlModes = ARRAY_SIZE(ctlModesFor11a);
2327 ath9k_hw_get_target_powers(ah, chan,
2328 pEepData->calTargetPower5GHT40,
2329 AR5416_NUM_5G_40_TARGET_POWERS,
2330 &targetPowerHt40, 8, true);
2331 ath9k_hw_get_legacy_target_powers(ah, chan,
2332 pEepData->calTargetPower5G,
2333 AR5416_NUM_5G_20_TARGET_POWERS,
2334 &targetPowerOfdmExt, 4, true);
2335 }
2336 }
2337
2338 for (ctlMode = 0; ctlMode < numCtlModes; ctlMode++) {
2339 bool isHt40CtlMode = (pCtlMode[ctlMode] == CTL_5GHT40) ||
2340 (pCtlMode[ctlMode] == CTL_2GHT40);
2341 if (isHt40CtlMode)
2342 freq = centers.synth_center;
2343 else if (pCtlMode[ctlMode] & EXT_ADDITIVE)
2344 freq = centers.ext_center;
2345 else
2346 freq = centers.ctl_center;
2347
2348 if (ah->eep_ops->get_eeprom_ver(ah) == 14 &&
2349 ah->eep_ops->get_eeprom_rev(ah) <= 2)
2350 twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
2351
2352 DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
2353 "LOOP-Mode ctlMode %d < %d, isHt40CtlMode %d, "
2354 "EXT_ADDITIVE %d\n",
2355 ctlMode, numCtlModes, isHt40CtlMode,
2356 (pCtlMode[ctlMode] & EXT_ADDITIVE));
2357
2358 for (i = 0; (i < AR5416_NUM_CTLS) && pEepData->ctlIndex[i]; i++) {
2359 DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
2360 " LOOP-Ctlidx %d: cfgCtl 0x%2.2x "
2361 "pCtlMode 0x%2.2x ctlIndex 0x%2.2x "
2362 "chan %d\n",
2363 i, cfgCtl, pCtlMode[ctlMode],
2364 pEepData->ctlIndex[i], chan->channel);
2365
2366 if ((((cfgCtl & ~CTL_MODE_M) |
2367 (pCtlMode[ctlMode] & CTL_MODE_M)) ==
2368 pEepData->ctlIndex[i]) ||
2369 (((cfgCtl & ~CTL_MODE_M) |
2370 (pCtlMode[ctlMode] & CTL_MODE_M)) ==
2371 ((pEepData->ctlIndex[i] & CTL_MODE_M) | SD_NO_CTL))) {
2372 rep = &(pEepData->ctlData[i]);
2373
2374 twiceMinEdgePower = ath9k_hw_get_max_edge_power(freq,
2375 rep->ctlEdges[ar5416_get_ntxchains(tx_chainmask) - 1],
2376 IS_CHAN_2GHZ(chan), AR5416_NUM_BAND_EDGES);
2377
2378 DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
2379 " MATCH-EE_IDX %d: ch %d is2 %d "
2380 "2xMinEdge %d chainmask %d chains %d\n",
2381 i, freq, IS_CHAN_2GHZ(chan),
2382 twiceMinEdgePower, tx_chainmask,
2383 ar5416_get_ntxchains
2384 (tx_chainmask));
2385 if ((cfgCtl & ~CTL_MODE_M) == SD_NO_CTL) {
2386 twiceMaxEdgePower = min(twiceMaxEdgePower,
2387 twiceMinEdgePower);
2388 } else {
2389 twiceMaxEdgePower = twiceMinEdgePower;
2390 break;
2391 }
2392 }
2393 }
2394
2395 minCtlPower = min(twiceMaxEdgePower, scaledPower);
2396
2397 DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
2398 " SEL-Min ctlMode %d pCtlMode %d "
2399 "2xMaxEdge %d sP %d minCtlPwr %d\n",
2400 ctlMode, pCtlMode[ctlMode], twiceMaxEdgePower,
2401 scaledPower, minCtlPower);
2556 2402
2557 return ath9k_get_eeprom_antenna_cfg[ahp->ah_eep_map](ah, chan); 2403 switch (pCtlMode[ctlMode]) {
2404 case CTL_11B:
2405 for (i = 0; i < ARRAY_SIZE(targetPowerCck.tPow2x); i++) {
2406 targetPowerCck.tPow2x[i] =
2407 min((u16)targetPowerCck.tPow2x[i],
2408 minCtlPower);
2409 }
2410 break;
2411 case CTL_11A:
2412 case CTL_11G:
2413 for (i = 0; i < ARRAY_SIZE(targetPowerOfdm.tPow2x); i++) {
2414 targetPowerOfdm.tPow2x[i] =
2415 min((u16)targetPowerOfdm.tPow2x[i],
2416 minCtlPower);
2417 }
2418 break;
2419 case CTL_5GHT20:
2420 case CTL_2GHT20:
2421 for (i = 0; i < ARRAY_SIZE(targetPowerHt20.tPow2x); i++) {
2422 targetPowerHt20.tPow2x[i] =
2423 min((u16)targetPowerHt20.tPow2x[i],
2424 minCtlPower);
2425 }
2426 break;
2427 case CTL_11B_EXT:
2428 targetPowerCckExt.tPow2x[0] = min((u16)
2429 targetPowerCckExt.tPow2x[0],
2430 minCtlPower);
2431 break;
2432 case CTL_11A_EXT:
2433 case CTL_11G_EXT:
2434 targetPowerOfdmExt.tPow2x[0] = min((u16)
2435 targetPowerOfdmExt.tPow2x[0],
2436 minCtlPower);
2437 break;
2438 case CTL_5GHT40:
2439 case CTL_2GHT40:
2440 for (i = 0; i < ARRAY_SIZE(targetPowerHt40.tPow2x); i++) {
2441 targetPowerHt40.tPow2x[i] =
2442 min((u16)targetPowerHt40.tPow2x[i],
2443 minCtlPower);
2444 }
2445 break;
2446 default:
2447 break;
2448 }
2449 }
2450
2451 ratesArray[rate6mb] = ratesArray[rate9mb] = ratesArray[rate12mb] =
2452 ratesArray[rate18mb] = ratesArray[rate24mb] =
2453 targetPowerOfdm.tPow2x[0];
2454 ratesArray[rate36mb] = targetPowerOfdm.tPow2x[1];
2455 ratesArray[rate48mb] = targetPowerOfdm.tPow2x[2];
2456 ratesArray[rate54mb] = targetPowerOfdm.tPow2x[3];
2457 ratesArray[rateXr] = targetPowerOfdm.tPow2x[0];
2458
2459 for (i = 0; i < ARRAY_SIZE(targetPowerHt20.tPow2x); i++)
2460 ratesArray[rateHt20_0 + i] = targetPowerHt20.tPow2x[i];
2461
2462 if (IS_CHAN_2GHZ(chan)) {
2463 ratesArray[rate1l] = targetPowerCck.tPow2x[0];
2464 ratesArray[rate2s] = ratesArray[rate2l] =
2465 targetPowerCck.tPow2x[1];
2466 ratesArray[rate5_5s] = ratesArray[rate5_5l] =
2467 targetPowerCck.tPow2x[2];
2468 ;
2469 ratesArray[rate11s] = ratesArray[rate11l] =
2470 targetPowerCck.tPow2x[3];
2471 ;
2472 }
2473 if (IS_CHAN_HT40(chan)) {
2474 for (i = 0; i < ARRAY_SIZE(targetPowerHt40.tPow2x); i++) {
2475 ratesArray[rateHt40_0 + i] =
2476 targetPowerHt40.tPow2x[i];
2477 }
2478 ratesArray[rateDupOfdm] = targetPowerHt40.tPow2x[0];
2479 ratesArray[rateDupCck] = targetPowerHt40.tPow2x[0];
2480 ratesArray[rateExtOfdm] = targetPowerOfdmExt.tPow2x[0];
2481 if (IS_CHAN_2GHZ(chan)) {
2482 ratesArray[rateExtCck] =
2483 targetPowerCckExt.tPow2x[0];
2484 }
2485 }
2486 return true;
2558} 2487}
2559 2488
2560static u8 ath9k_hw_get_4k_num_ant_config(struct ath_hal *ah, 2489static int ath9k_hw_def_set_txpower(struct ath_hw *ah,
2561 enum ieee80211_band freq_band) 2490 struct ath9k_channel *chan,
2491 u16 cfgCtl,
2492 u8 twiceAntennaReduction,
2493 u8 twiceMaxRegulatoryPower,
2494 u8 powerLimit)
2562{ 2495{
2563 return 1; 2496 struct ar5416_eeprom_def *pEepData = &ah->eeprom.def;
2497 struct modal_eep_header *pModal =
2498 &(pEepData->modalHeader[IS_CHAN_2GHZ(chan)]);
2499 int16_t ratesArray[Ar5416RateSize];
2500 int16_t txPowerIndexOffset = 0;
2501 u8 ht40PowerIncForPdadc = 2;
2502 int i;
2503
2504 memset(ratesArray, 0, sizeof(ratesArray));
2505
2506 if ((pEepData->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
2507 AR5416_EEP_MINOR_VER_2) {
2508 ht40PowerIncForPdadc = pModal->ht40PowerIncForPdadc;
2509 }
2510
2511 if (!ath9k_hw_set_def_power_per_rate_table(ah, chan,
2512 &ratesArray[0], cfgCtl,
2513 twiceAntennaReduction,
2514 twiceMaxRegulatoryPower,
2515 powerLimit)) {
2516 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
2517 "ath9k_hw_set_txpower: unable to set "
2518 "tx power per rate table\n");
2519 return -EIO;
2520 }
2521
2522 if (!ath9k_hw_set_def_power_cal_table(ah, chan, &txPowerIndexOffset)) {
2523 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
2524 "ath9k_hw_set_txpower: unable to set power table\n");
2525 return -EIO;
2526 }
2527
2528 for (i = 0; i < ARRAY_SIZE(ratesArray); i++) {
2529 ratesArray[i] = (int16_t)(txPowerIndexOffset + ratesArray[i]);
2530 if (ratesArray[i] > AR5416_MAX_RATE_POWER)
2531 ratesArray[i] = AR5416_MAX_RATE_POWER;
2532 }
2533
2534 if (AR_SREV_9280_10_OR_LATER(ah)) {
2535 for (i = 0; i < Ar5416RateSize; i++)
2536 ratesArray[i] -= AR5416_PWR_TABLE_OFFSET * 2;
2537 }
2538
2539 REG_WRITE(ah, AR_PHY_POWER_TX_RATE1,
2540 ATH9K_POW_SM(ratesArray[rate18mb], 24)
2541 | ATH9K_POW_SM(ratesArray[rate12mb], 16)
2542 | ATH9K_POW_SM(ratesArray[rate9mb], 8)
2543 | ATH9K_POW_SM(ratesArray[rate6mb], 0));
2544 REG_WRITE(ah, AR_PHY_POWER_TX_RATE2,
2545 ATH9K_POW_SM(ratesArray[rate54mb], 24)
2546 | ATH9K_POW_SM(ratesArray[rate48mb], 16)
2547 | ATH9K_POW_SM(ratesArray[rate36mb], 8)
2548 | ATH9K_POW_SM(ratesArray[rate24mb], 0));
2549
2550 if (IS_CHAN_2GHZ(chan)) {
2551 REG_WRITE(ah, AR_PHY_POWER_TX_RATE3,
2552 ATH9K_POW_SM(ratesArray[rate2s], 24)
2553 | ATH9K_POW_SM(ratesArray[rate2l], 16)
2554 | ATH9K_POW_SM(ratesArray[rateXr], 8)
2555 | ATH9K_POW_SM(ratesArray[rate1l], 0));
2556 REG_WRITE(ah, AR_PHY_POWER_TX_RATE4,
2557 ATH9K_POW_SM(ratesArray[rate11s], 24)
2558 | ATH9K_POW_SM(ratesArray[rate11l], 16)
2559 | ATH9K_POW_SM(ratesArray[rate5_5s], 8)
2560 | ATH9K_POW_SM(ratesArray[rate5_5l], 0));
2561 }
2562
2563 REG_WRITE(ah, AR_PHY_POWER_TX_RATE5,
2564 ATH9K_POW_SM(ratesArray[rateHt20_3], 24)
2565 | ATH9K_POW_SM(ratesArray[rateHt20_2], 16)
2566 | ATH9K_POW_SM(ratesArray[rateHt20_1], 8)
2567 | ATH9K_POW_SM(ratesArray[rateHt20_0], 0));
2568 REG_WRITE(ah, AR_PHY_POWER_TX_RATE6,
2569 ATH9K_POW_SM(ratesArray[rateHt20_7], 24)
2570 | ATH9K_POW_SM(ratesArray[rateHt20_6], 16)
2571 | ATH9K_POW_SM(ratesArray[rateHt20_5], 8)
2572 | ATH9K_POW_SM(ratesArray[rateHt20_4], 0));
2573
2574 if (IS_CHAN_HT40(chan)) {
2575 REG_WRITE(ah, AR_PHY_POWER_TX_RATE7,
2576 ATH9K_POW_SM(ratesArray[rateHt40_3] +
2577 ht40PowerIncForPdadc, 24)
2578 | ATH9K_POW_SM(ratesArray[rateHt40_2] +
2579 ht40PowerIncForPdadc, 16)
2580 | ATH9K_POW_SM(ratesArray[rateHt40_1] +
2581 ht40PowerIncForPdadc, 8)
2582 | ATH9K_POW_SM(ratesArray[rateHt40_0] +
2583 ht40PowerIncForPdadc, 0));
2584 REG_WRITE(ah, AR_PHY_POWER_TX_RATE8,
2585 ATH9K_POW_SM(ratesArray[rateHt40_7] +
2586 ht40PowerIncForPdadc, 24)
2587 | ATH9K_POW_SM(ratesArray[rateHt40_6] +
2588 ht40PowerIncForPdadc, 16)
2589 | ATH9K_POW_SM(ratesArray[rateHt40_5] +
2590 ht40PowerIncForPdadc, 8)
2591 | ATH9K_POW_SM(ratesArray[rateHt40_4] +
2592 ht40PowerIncForPdadc, 0));
2593
2594 REG_WRITE(ah, AR_PHY_POWER_TX_RATE9,
2595 ATH9K_POW_SM(ratesArray[rateExtOfdm], 24)
2596 | ATH9K_POW_SM(ratesArray[rateExtCck], 16)
2597 | ATH9K_POW_SM(ratesArray[rateDupOfdm], 8)
2598 | ATH9K_POW_SM(ratesArray[rateDupCck], 0));
2599 }
2600
2601 REG_WRITE(ah, AR_PHY_POWER_TX_SUB,
2602 ATH9K_POW_SM(pModal->pwrDecreaseFor3Chain, 6)
2603 | ATH9K_POW_SM(pModal->pwrDecreaseFor2Chain, 0));
2604
2605 i = rate6mb;
2606
2607 if (IS_CHAN_HT40(chan))
2608 i = rateHt40_0;
2609 else if (IS_CHAN_HT20(chan))
2610 i = rateHt20_0;
2611
2612 if (AR_SREV_9280_10_OR_LATER(ah))
2613 ah->regulatory.max_power_level =
2614 ratesArray[i] + AR5416_PWR_TABLE_OFFSET * 2;
2615 else
2616 ah->regulatory.max_power_level = ratesArray[i];
2617
2618 return 0;
2564} 2619}
2565 2620
2566static u8 ath9k_hw_get_def_num_ant_config(struct ath_hal *ah, 2621static u8 ath9k_hw_def_get_num_ant_config(struct ath_hw *ah,
2567 enum ieee80211_band freq_band) 2622 enum ieee80211_band freq_band)
2568{ 2623{
2569 struct ath_hal_5416 *ahp = AH5416(ah); 2624 struct ar5416_eeprom_def *eep = &ah->eeprom.def;
2570 struct ar5416_eeprom_def *eep = &ahp->ah_eeprom.def;
2571 struct modal_eep_header *pModal = 2625 struct modal_eep_header *pModal =
2572 &(eep->modalHeader[ATH9K_HAL_FREQ_BAND_2GHZ == freq_band]); 2626 &(eep->modalHeader[ATH9K_HAL_FREQ_BAND_2GHZ == freq_band]);
2573 struct base_eep_header *pBase = &eep->baseEepHeader; 2627 struct base_eep_header *pBase = &eep->baseEepHeader;
@@ -2582,183 +2636,75 @@ static u8 ath9k_hw_get_def_num_ant_config(struct ath_hal *ah,
2582 return num_ant_config; 2636 return num_ant_config;
2583} 2637}
2584 2638
2585static u8 (*ath9k_get_num_ant_config[])(struct ath_hal *, 2639static u16 ath9k_hw_def_get_eeprom_antenna_cfg(struct ath_hw *ah,
2586 enum ieee80211_band) = { 2640 struct ath9k_channel *chan)
2587 ath9k_hw_get_def_num_ant_config,
2588 ath9k_hw_get_4k_num_ant_config
2589};
2590
2591u8 ath9k_hw_get_num_ant_config(struct ath_hal *ah,
2592 enum ieee80211_band freq_band)
2593{ 2641{
2594 struct ath_hal_5416 *ahp = AH5416(ah); 2642 struct ar5416_eeprom_def *eep = &ah->eeprom.def;
2643 struct modal_eep_header *pModal =
2644 &(eep->modalHeader[IS_CHAN_2GHZ(chan)]);
2595 2645
2596 return ath9k_get_num_ant_config[ahp->ah_eep_map](ah, freq_band); 2646 return pModal->antCtrlCommon & 0xFFFF;
2597} 2647}
2598 2648
2599u16 ath9k_hw_eeprom_get_spur_chan(struct ath_hal *ah, u16 i, bool is2GHz) 2649u16 ath9k_hw_def_get_spur_channel(struct ath_hw *ah, u16 i, bool is2GHz)
2600{ 2650{
2601#define EEP_MAP4K_SPURCHAN \
2602 (ahp->ah_eeprom.map4k.modalHeader.spurChans[i].spurChan)
2603#define EEP_DEF_SPURCHAN \ 2651#define EEP_DEF_SPURCHAN \
2604 (ahp->ah_eeprom.def.modalHeader[is2GHz].spurChans[i].spurChan) 2652 (ah->eeprom.def.modalHeader[is2GHz].spurChans[i].spurChan)
2605 struct ath_hal_5416 *ahp = AH5416(ah); 2653
2606 u16 spur_val = AR_NO_SPUR; 2654 u16 spur_val = AR_NO_SPUR;
2607 2655
2608 DPRINTF(ah->ah_sc, ATH_DBG_ANI, 2656 DPRINTF(ah->ah_sc, ATH_DBG_ANI,
2609 "Getting spur idx %d is2Ghz. %d val %x\n", 2657 "Getting spur idx %d is2Ghz. %d val %x\n",
2610 i, is2GHz, ah->ah_config.spurchans[i][is2GHz]); 2658 i, is2GHz, ah->config.spurchans[i][is2GHz]);
2611 2659
2612 switch (ah->ah_config.spurmode) { 2660 switch (ah->config.spurmode) {
2613 case SPUR_DISABLE: 2661 case SPUR_DISABLE:
2614 break; 2662 break;
2615 case SPUR_ENABLE_IOCTL: 2663 case SPUR_ENABLE_IOCTL:
2616 spur_val = ah->ah_config.spurchans[i][is2GHz]; 2664 spur_val = ah->config.spurchans[i][is2GHz];
2617 DPRINTF(ah->ah_sc, ATH_DBG_ANI, 2665 DPRINTF(ah->ah_sc, ATH_DBG_ANI,
2618 "Getting spur val from new loc. %d\n", spur_val); 2666 "Getting spur val from new loc. %d\n", spur_val);
2619 break; 2667 break;
2620 case SPUR_ENABLE_EEPROM: 2668 case SPUR_ENABLE_EEPROM:
2621 if (ahp->ah_eep_map == EEP_MAP_4KBITS) 2669 spur_val = EEP_DEF_SPURCHAN;
2622 spur_val = EEP_MAP4K_SPURCHAN;
2623 else
2624 spur_val = EEP_DEF_SPURCHAN;
2625 break; 2670 break;
2626
2627 } 2671 }
2628 2672
2629 return spur_val; 2673 return spur_val;
2630#undef EEP_DEF_SPURCHAN
2631#undef EEP_MAP4K_SPURCHAN
2632}
2633
2634static u32 ath9k_hw_get_eeprom_4k(struct ath_hal *ah,
2635 enum eeprom_param param)
2636{
2637 struct ath_hal_5416 *ahp = AH5416(ah);
2638 struct ar5416_eeprom_4k *eep = &ahp->ah_eeprom.map4k;
2639 struct modal_eep_4k_header *pModal = &eep->modalHeader;
2640 struct base_eep_header_4k *pBase = &eep->baseEepHeader;
2641
2642 switch (param) {
2643 case EEP_NFTHRESH_2:
2644 return pModal[1].noiseFloorThreshCh[0];
2645 case AR_EEPROM_MAC(0):
2646 return pBase->macAddr[0] << 8 | pBase->macAddr[1];
2647 case AR_EEPROM_MAC(1):
2648 return pBase->macAddr[2] << 8 | pBase->macAddr[3];
2649 case AR_EEPROM_MAC(2):
2650 return pBase->macAddr[4] << 8 | pBase->macAddr[5];
2651 case EEP_REG_0:
2652 return pBase->regDmn[0];
2653 case EEP_REG_1:
2654 return pBase->regDmn[1];
2655 case EEP_OP_CAP:
2656 return pBase->deviceCap;
2657 case EEP_OP_MODE:
2658 return pBase->opCapFlags;
2659 case EEP_RF_SILENT:
2660 return pBase->rfSilent;
2661 case EEP_OB_2:
2662 return pModal->ob_01;
2663 case EEP_DB_2:
2664 return pModal->db1_01;
2665 case EEP_MINOR_REV:
2666 return pBase->version & AR5416_EEP_VER_MINOR_MASK;
2667 case EEP_TX_MASK:
2668 return pBase->txMask;
2669 case EEP_RX_MASK:
2670 return pBase->rxMask;
2671 default:
2672 return 0;
2673 }
2674}
2675
2676static u32 ath9k_hw_get_eeprom_def(struct ath_hal *ah,
2677 enum eeprom_param param)
2678{
2679#define AR5416_VER_MASK (pBase->version & AR5416_EEP_VER_MINOR_MASK)
2680 struct ath_hal_5416 *ahp = AH5416(ah);
2681 struct ar5416_eeprom_def *eep = &ahp->ah_eeprom.def;
2682 struct modal_eep_header *pModal = eep->modalHeader;
2683 struct base_eep_header *pBase = &eep->baseEepHeader;
2684 2674
2685 switch (param) { 2675#undef EEP_DEF_SPURCHAN
2686 case EEP_NFTHRESH_5:
2687 return pModal[0].noiseFloorThreshCh[0];
2688 case EEP_NFTHRESH_2:
2689 return pModal[1].noiseFloorThreshCh[0];
2690 case AR_EEPROM_MAC(0):
2691 return pBase->macAddr[0] << 8 | pBase->macAddr[1];
2692 case AR_EEPROM_MAC(1):
2693 return pBase->macAddr[2] << 8 | pBase->macAddr[3];
2694 case AR_EEPROM_MAC(2):
2695 return pBase->macAddr[4] << 8 | pBase->macAddr[5];
2696 case EEP_REG_0:
2697 return pBase->regDmn[0];
2698 case EEP_REG_1:
2699 return pBase->regDmn[1];
2700 case EEP_OP_CAP:
2701 return pBase->deviceCap;
2702 case EEP_OP_MODE:
2703 return pBase->opCapFlags;
2704 case EEP_RF_SILENT:
2705 return pBase->rfSilent;
2706 case EEP_OB_5:
2707 return pModal[0].ob;
2708 case EEP_DB_5:
2709 return pModal[0].db;
2710 case EEP_OB_2:
2711 return pModal[1].ob;
2712 case EEP_DB_2:
2713 return pModal[1].db;
2714 case EEP_MINOR_REV:
2715 return AR5416_VER_MASK;
2716 case EEP_TX_MASK:
2717 return pBase->txMask;
2718 case EEP_RX_MASK:
2719 return pBase->rxMask;
2720 case EEP_RXGAIN_TYPE:
2721 return pBase->rxGainType;
2722 case EEP_TXGAIN_TYPE:
2723 return pBase->txGainType;
2724 case EEP_DAC_HPWR_5G:
2725 if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_20)
2726 return pBase->dacHiPwrMode_5G;
2727 else
2728 return 0;
2729 default:
2730 return 0;
2731 }
2732#undef AR5416_VER_MASK
2733} 2676}
2734 2677
2735static u32 (*ath9k_get_eeprom[])(struct ath_hal *, enum eeprom_param) = { 2678struct eeprom_ops eep_def_ops = {
2736 ath9k_hw_get_eeprom_def, 2679 .check_eeprom = ath9k_hw_def_check_eeprom,
2737 ath9k_hw_get_eeprom_4k 2680 .get_eeprom = ath9k_hw_def_get_eeprom,
2681 .fill_eeprom = ath9k_hw_def_fill_eeprom,
2682 .get_eeprom_ver = ath9k_hw_def_get_eeprom_ver,
2683 .get_eeprom_rev = ath9k_hw_def_get_eeprom_rev,
2684 .get_num_ant_config = ath9k_hw_def_get_num_ant_config,
2685 .get_eeprom_antenna_cfg = ath9k_hw_def_get_eeprom_antenna_cfg,
2686 .set_board_values = ath9k_hw_def_set_board_values,
2687 .set_addac = ath9k_hw_def_set_addac,
2688 .set_txpower = ath9k_hw_def_set_txpower,
2689 .get_spur_channel = ath9k_hw_def_get_spur_channel
2738}; 2690};
2739 2691
2740u32 ath9k_hw_get_eeprom(struct ath_hal *ah, 2692int ath9k_hw_eeprom_attach(struct ath_hw *ah)
2741 enum eeprom_param param)
2742{
2743 struct ath_hal_5416 *ahp = AH5416(ah);
2744
2745 return ath9k_get_eeprom[ahp->ah_eep_map](ah, param);
2746}
2747
2748int ath9k_hw_eeprom_attach(struct ath_hal *ah)
2749{ 2693{
2750 int status; 2694 int status;
2751 struct ath_hal_5416 *ahp = AH5416(ah);
2752 2695
2753 if (AR_SREV_9285(ah)) 2696 if (AR_SREV_9285(ah)) {
2754 ahp->ah_eep_map = EEP_MAP_4KBITS; 2697 ah->eep_map = EEP_MAP_4KBITS;
2755 else 2698 ah->eep_ops = &eep_4k_ops;
2756 ahp->ah_eep_map = EEP_MAP_DEFAULT; 2699 } else {
2700 ah->eep_map = EEP_MAP_DEFAULT;
2701 ah->eep_ops = &eep_def_ops;
2702 }
2757 2703
2758 if (!ath9k_hw_fill_eeprom(ah)) 2704 if (!ah->eep_ops->fill_eeprom(ah))
2759 return -EIO; 2705 return -EIO;
2760 2706
2761 status = ath9k_hw_check_eeprom(ah); 2707 status = ah->eep_ops->check_eeprom(ah);
2762 2708
2763 return status; 2709 return status;
2764} 2710}
diff --git a/drivers/net/wireless/ath9k/eeprom.h b/drivers/net/wireless/ath9k/eeprom.h
new file mode 100644
index 000000000000..99863b570441
--- /dev/null
+++ b/drivers/net/wireless/ath9k/eeprom.h
@@ -0,0 +1,473 @@
1/*
2 * Copyright (c) 2008 Atheros Communications Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#ifndef EEPROM_H
18#define EEPROM_H
19
20#define AH_USE_EEPROM 0x1
21
22#ifdef __BIG_ENDIAN
23#define AR5416_EEPROM_MAGIC 0x5aa5
24#else
25#define AR5416_EEPROM_MAGIC 0xa55a
26#endif
27
28#define CTRY_DEBUG 0x1ff
29#define CTRY_DEFAULT 0
30
31#define AR_EEPROM_EEPCAP_COMPRESS_DIS 0x0001
32#define AR_EEPROM_EEPCAP_AES_DIS 0x0002
33#define AR_EEPROM_EEPCAP_FASTFRAME_DIS 0x0004
34#define AR_EEPROM_EEPCAP_BURST_DIS 0x0008
35#define AR_EEPROM_EEPCAP_MAXQCU 0x01F0
36#define AR_EEPROM_EEPCAP_MAXQCU_S 4
37#define AR_EEPROM_EEPCAP_HEAVY_CLIP_EN 0x0200
38#define AR_EEPROM_EEPCAP_KC_ENTRIES 0xF000
39#define AR_EEPROM_EEPCAP_KC_ENTRIES_S 12
40
41#define AR_EEPROM_EEREGCAP_EN_FCC_MIDBAND 0x0040
42#define AR_EEPROM_EEREGCAP_EN_KK_U1_EVEN 0x0080
43#define AR_EEPROM_EEREGCAP_EN_KK_U2 0x0100
44#define AR_EEPROM_EEREGCAP_EN_KK_MIDBAND 0x0200
45#define AR_EEPROM_EEREGCAP_EN_KK_U1_ODD 0x0400
46#define AR_EEPROM_EEREGCAP_EN_KK_NEW_11A 0x0800
47
48#define AR_EEPROM_EEREGCAP_EN_KK_U1_ODD_PRE4_0 0x4000
49#define AR_EEPROM_EEREGCAP_EN_KK_NEW_11A_PRE4_0 0x8000
50
51#define AR5416_EEPROM_MAGIC_OFFSET 0x0
52#define AR5416_EEPROM_S 2
53#define AR5416_EEPROM_OFFSET 0x2000
54#define AR5416_EEPROM_MAX 0xae0
55
56#define AR5416_EEPROM_START_ADDR \
57 (AR_SREV_9100(ah)) ? 0x1fff1000 : 0x503f1200
58
59#define SD_NO_CTL 0xE0
60#define NO_CTL 0xff
61#define CTL_MODE_M 7
62#define CTL_11A 0
63#define CTL_11B 1
64#define CTL_11G 2
65#define CTL_2GHT20 5
66#define CTL_5GHT20 6
67#define CTL_2GHT40 7
68#define CTL_5GHT40 8
69
70#define EXT_ADDITIVE (0x8000)
71#define CTL_11A_EXT (CTL_11A | EXT_ADDITIVE)
72#define CTL_11G_EXT (CTL_11G | EXT_ADDITIVE)
73#define CTL_11B_EXT (CTL_11B | EXT_ADDITIVE)
74
75#define SUB_NUM_CTL_MODES_AT_5G_40 2
76#define SUB_NUM_CTL_MODES_AT_2G_40 3
77
78#define AR_EEPROM_MAC(i) (0x1d+(i))
79#define ATH9K_POW_SM(_r, _s) (((_r) & 0x3f) << (_s))
80#define FREQ2FBIN(x, y) ((y) ? ((x) - 2300) : (((x) - 4800) / 5))
81#define ath9k_hw_use_flash(_ah) (!(_ah->ah_flags & AH_USE_EEPROM))
82
83#define AR_EEPROM_RFSILENT_GPIO_SEL 0x001c
84#define AR_EEPROM_RFSILENT_GPIO_SEL_S 2
85#define AR_EEPROM_RFSILENT_POLARITY 0x0002
86#define AR_EEPROM_RFSILENT_POLARITY_S 1
87
88#define EEP_RFSILENT_ENABLED 0x0001
89#define EEP_RFSILENT_ENABLED_S 0
90#define EEP_RFSILENT_POLARITY 0x0002
91#define EEP_RFSILENT_POLARITY_S 1
92#define EEP_RFSILENT_GPIO_SEL 0x001c
93#define EEP_RFSILENT_GPIO_SEL_S 2
94
95#define AR5416_OPFLAGS_11A 0x01
96#define AR5416_OPFLAGS_11G 0x02
97#define AR5416_OPFLAGS_N_5G_HT40 0x04
98#define AR5416_OPFLAGS_N_2G_HT40 0x08
99#define AR5416_OPFLAGS_N_5G_HT20 0x10
100#define AR5416_OPFLAGS_N_2G_HT20 0x20
101
102#define AR5416_EEP_NO_BACK_VER 0x1
103#define AR5416_EEP_VER 0xE
104#define AR5416_EEP_VER_MINOR_MASK 0x0FFF
105#define AR5416_EEP_MINOR_VER_2 0x2
106#define AR5416_EEP_MINOR_VER_3 0x3
107#define AR5416_EEP_MINOR_VER_7 0x7
108#define AR5416_EEP_MINOR_VER_9 0x9
109#define AR5416_EEP_MINOR_VER_16 0x10
110#define AR5416_EEP_MINOR_VER_17 0x11
111#define AR5416_EEP_MINOR_VER_19 0x13
112#define AR5416_EEP_MINOR_VER_20 0x14
113
114#define AR5416_NUM_5G_CAL_PIERS 8
115#define AR5416_NUM_2G_CAL_PIERS 4
116#define AR5416_NUM_5G_20_TARGET_POWERS 8
117#define AR5416_NUM_5G_40_TARGET_POWERS 8
118#define AR5416_NUM_2G_CCK_TARGET_POWERS 3
119#define AR5416_NUM_2G_20_TARGET_POWERS 4
120#define AR5416_NUM_2G_40_TARGET_POWERS 4
121#define AR5416_NUM_CTLS 24
122#define AR5416_NUM_BAND_EDGES 8
123#define AR5416_NUM_PD_GAINS 4
124#define AR5416_PD_GAINS_IN_MASK 4
125#define AR5416_PD_GAIN_ICEPTS 5
126#define AR5416_EEPROM_MODAL_SPURS 5
127#define AR5416_MAX_RATE_POWER 63
128#define AR5416_NUM_PDADC_VALUES 128
129#define AR5416_BCHAN_UNUSED 0xFF
130#define AR5416_MAX_PWR_RANGE_IN_HALF_DB 64
131#define AR5416_MAX_CHAINS 3
132#define AR5416_PWR_TABLE_OFFSET -5
133
134/* Rx gain type values */
135#define AR5416_EEP_RXGAIN_23DB_BACKOFF 0
136#define AR5416_EEP_RXGAIN_13DB_BACKOFF 1
137#define AR5416_EEP_RXGAIN_ORIG 2
138
139/* Tx gain type values */
140#define AR5416_EEP_TXGAIN_ORIGINAL 0
141#define AR5416_EEP_TXGAIN_HIGH_POWER 1
142
143#define AR5416_EEP4K_START_LOC 64
144#define AR5416_EEP4K_NUM_2G_CAL_PIERS 3
145#define AR5416_EEP4K_NUM_2G_CCK_TARGET_POWERS 3
146#define AR5416_EEP4K_NUM_2G_20_TARGET_POWERS 3
147#define AR5416_EEP4K_NUM_2G_40_TARGET_POWERS 3
148#define AR5416_EEP4K_NUM_CTLS 12
149#define AR5416_EEP4K_NUM_BAND_EDGES 4
150#define AR5416_EEP4K_NUM_PD_GAINS 2
151#define AR5416_EEP4K_PD_GAINS_IN_MASK 4
152#define AR5416_EEP4K_PD_GAIN_ICEPTS 5
153#define AR5416_EEP4K_MAX_CHAINS 1
154
155enum eeprom_param {
156 EEP_NFTHRESH_5,
157 EEP_NFTHRESH_2,
158 EEP_MAC_MSW,
159 EEP_MAC_MID,
160 EEP_MAC_LSW,
161 EEP_REG_0,
162 EEP_REG_1,
163 EEP_OP_CAP,
164 EEP_OP_MODE,
165 EEP_RF_SILENT,
166 EEP_OB_5,
167 EEP_DB_5,
168 EEP_OB_2,
169 EEP_DB_2,
170 EEP_MINOR_REV,
171 EEP_TX_MASK,
172 EEP_RX_MASK,
173 EEP_RXGAIN_TYPE,
174 EEP_TXGAIN_TYPE,
175 EEP_DAC_HPWR_5G,
176};
177
178enum ar5416_rates {
179 rate6mb, rate9mb, rate12mb, rate18mb,
180 rate24mb, rate36mb, rate48mb, rate54mb,
181 rate1l, rate2l, rate2s, rate5_5l,
182 rate5_5s, rate11l, rate11s, rateXr,
183 rateHt20_0, rateHt20_1, rateHt20_2, rateHt20_3,
184 rateHt20_4, rateHt20_5, rateHt20_6, rateHt20_7,
185 rateHt40_0, rateHt40_1, rateHt40_2, rateHt40_3,
186 rateHt40_4, rateHt40_5, rateHt40_6, rateHt40_7,
187 rateDupCck, rateDupOfdm, rateExtCck, rateExtOfdm,
188 Ar5416RateSize
189};
190
191enum ath9k_hal_freq_band {
192 ATH9K_HAL_FREQ_BAND_5GHZ = 0,
193 ATH9K_HAL_FREQ_BAND_2GHZ = 1
194};
195
196struct base_eep_header {
197 u16 length;
198 u16 checksum;
199 u16 version;
200 u8 opCapFlags;
201 u8 eepMisc;
202 u16 regDmn[2];
203 u8 macAddr[6];
204 u8 rxMask;
205 u8 txMask;
206 u16 rfSilent;
207 u16 blueToothOptions;
208 u16 deviceCap;
209 u32 binBuildNumber;
210 u8 deviceType;
211 u8 pwdclkind;
212 u8 futureBase_1[2];
213 u8 rxGainType;
214 u8 dacHiPwrMode_5G;
215 u8 futureBase_2;
216 u8 dacLpMode;
217 u8 txGainType;
218 u8 rcChainMask;
219 u8 desiredScaleCCK;
220 u8 futureBase_3[23];
221} __packed;
222
223struct base_eep_header_4k {
224 u16 length;
225 u16 checksum;
226 u16 version;
227 u8 opCapFlags;
228 u8 eepMisc;
229 u16 regDmn[2];
230 u8 macAddr[6];
231 u8 rxMask;
232 u8 txMask;
233 u16 rfSilent;
234 u16 blueToothOptions;
235 u16 deviceCap;
236 u32 binBuildNumber;
237 u8 deviceType;
238 u8 futureBase[1];
239} __packed;
240
241
242struct spur_chan {
243 u16 spurChan;
244 u8 spurRangeLow;
245 u8 spurRangeHigh;
246} __packed;
247
248struct modal_eep_header {
249 u32 antCtrlChain[AR5416_MAX_CHAINS];
250 u32 antCtrlCommon;
251 u8 antennaGainCh[AR5416_MAX_CHAINS];
252 u8 switchSettling;
253 u8 txRxAttenCh[AR5416_MAX_CHAINS];
254 u8 rxTxMarginCh[AR5416_MAX_CHAINS];
255 u8 adcDesiredSize;
256 u8 pgaDesiredSize;
257 u8 xlnaGainCh[AR5416_MAX_CHAINS];
258 u8 txEndToXpaOff;
259 u8 txEndToRxOn;
260 u8 txFrameToXpaOn;
261 u8 thresh62;
262 u8 noiseFloorThreshCh[AR5416_MAX_CHAINS];
263 u8 xpdGain;
264 u8 xpd;
265 u8 iqCalICh[AR5416_MAX_CHAINS];
266 u8 iqCalQCh[AR5416_MAX_CHAINS];
267 u8 pdGainOverlap;
268 u8 ob;
269 u8 db;
270 u8 xpaBiasLvl;
271 u8 pwrDecreaseFor2Chain;
272 u8 pwrDecreaseFor3Chain;
273 u8 txFrameToDataStart;
274 u8 txFrameToPaOn;
275 u8 ht40PowerIncForPdadc;
276 u8 bswAtten[AR5416_MAX_CHAINS];
277 u8 bswMargin[AR5416_MAX_CHAINS];
278 u8 swSettleHt40;
279 u8 xatten2Db[AR5416_MAX_CHAINS];
280 u8 xatten2Margin[AR5416_MAX_CHAINS];
281 u8 ob_ch1;
282 u8 db_ch1;
283 u8 useAnt1:1,
284 force_xpaon:1,
285 local_bias:1,
286 femBandSelectUsed:1, xlnabufin:1, xlnaisel:2, xlnabufmode:1;
287 u8 miscBits;
288 u16 xpaBiasLvlFreq[3];
289 u8 futureModal[6];
290
291 struct spur_chan spurChans[AR5416_EEPROM_MODAL_SPURS];
292} __packed;
293
294struct modal_eep_4k_header {
295 u32 antCtrlChain[AR5416_EEP4K_MAX_CHAINS];
296 u32 antCtrlCommon;
297 u8 antennaGainCh[AR5416_EEP4K_MAX_CHAINS];
298 u8 switchSettling;
299 u8 txRxAttenCh[AR5416_EEP4K_MAX_CHAINS];
300 u8 rxTxMarginCh[AR5416_EEP4K_MAX_CHAINS];
301 u8 adcDesiredSize;
302 u8 pgaDesiredSize;
303 u8 xlnaGainCh[AR5416_EEP4K_MAX_CHAINS];
304 u8 txEndToXpaOff;
305 u8 txEndToRxOn;
306 u8 txFrameToXpaOn;
307 u8 thresh62;
308 u8 noiseFloorThreshCh[AR5416_EEP4K_MAX_CHAINS];
309 u8 xpdGain;
310 u8 xpd;
311 u8 iqCalICh[AR5416_EEP4K_MAX_CHAINS];
312 u8 iqCalQCh[AR5416_EEP4K_MAX_CHAINS];
313 u8 pdGainOverlap;
314 u8 ob_01;
315 u8 db1_01;
316 u8 xpaBiasLvl;
317 u8 txFrameToDataStart;
318 u8 txFrameToPaOn;
319 u8 ht40PowerIncForPdadc;
320 u8 bswAtten[AR5416_EEP4K_MAX_CHAINS];
321 u8 bswMargin[AR5416_EEP4K_MAX_CHAINS];
322 u8 swSettleHt40;
323 u8 xatten2Db[AR5416_EEP4K_MAX_CHAINS];
324 u8 xatten2Margin[AR5416_EEP4K_MAX_CHAINS];
325 u8 db2_01;
326 u8 version;
327 u16 ob_234;
328 u16 db1_234;
329 u16 db2_234;
330 u8 futureModal[4];
331
332 struct spur_chan spurChans[AR5416_EEPROM_MODAL_SPURS];
333} __packed;
334
335
336struct cal_data_per_freq {
337 u8 pwrPdg[AR5416_NUM_PD_GAINS][AR5416_PD_GAIN_ICEPTS];
338 u8 vpdPdg[AR5416_NUM_PD_GAINS][AR5416_PD_GAIN_ICEPTS];
339} __packed;
340
341struct cal_data_per_freq_4k {
342 u8 pwrPdg[AR5416_EEP4K_NUM_PD_GAINS][AR5416_EEP4K_PD_GAIN_ICEPTS];
343 u8 vpdPdg[AR5416_EEP4K_NUM_PD_GAINS][AR5416_EEP4K_PD_GAIN_ICEPTS];
344} __packed;
345
346struct cal_target_power_leg {
347 u8 bChannel;
348 u8 tPow2x[4];
349} __packed;
350
351struct cal_target_power_ht {
352 u8 bChannel;
353 u8 tPow2x[8];
354} __packed;
355
356
357#ifdef __BIG_ENDIAN_BITFIELD
358struct cal_ctl_edges {
359 u8 bChannel;
360 u8 flag:2, tPower:6;
361} __packed;
362#else
363struct cal_ctl_edges {
364 u8 bChannel;
365 u8 tPower:6, flag:2;
366} __packed;
367#endif
368
369struct cal_ctl_data {
370 struct cal_ctl_edges
371 ctlEdges[AR5416_MAX_CHAINS][AR5416_NUM_BAND_EDGES];
372} __packed;
373
374struct cal_ctl_data_4k {
375 struct cal_ctl_edges
376 ctlEdges[AR5416_EEP4K_MAX_CHAINS][AR5416_EEP4K_NUM_BAND_EDGES];
377} __packed;
378
379struct ar5416_eeprom_def {
380 struct base_eep_header baseEepHeader;
381 u8 custData[64];
382 struct modal_eep_header modalHeader[2];
383 u8 calFreqPier5G[AR5416_NUM_5G_CAL_PIERS];
384 u8 calFreqPier2G[AR5416_NUM_2G_CAL_PIERS];
385 struct cal_data_per_freq
386 calPierData5G[AR5416_MAX_CHAINS][AR5416_NUM_5G_CAL_PIERS];
387 struct cal_data_per_freq
388 calPierData2G[AR5416_MAX_CHAINS][AR5416_NUM_2G_CAL_PIERS];
389 struct cal_target_power_leg
390 calTargetPower5G[AR5416_NUM_5G_20_TARGET_POWERS];
391 struct cal_target_power_ht
392 calTargetPower5GHT20[AR5416_NUM_5G_20_TARGET_POWERS];
393 struct cal_target_power_ht
394 calTargetPower5GHT40[AR5416_NUM_5G_40_TARGET_POWERS];
395 struct cal_target_power_leg
396 calTargetPowerCck[AR5416_NUM_2G_CCK_TARGET_POWERS];
397 struct cal_target_power_leg
398 calTargetPower2G[AR5416_NUM_2G_20_TARGET_POWERS];
399 struct cal_target_power_ht
400 calTargetPower2GHT20[AR5416_NUM_2G_20_TARGET_POWERS];
401 struct cal_target_power_ht
402 calTargetPower2GHT40[AR5416_NUM_2G_40_TARGET_POWERS];
403 u8 ctlIndex[AR5416_NUM_CTLS];
404 struct cal_ctl_data ctlData[AR5416_NUM_CTLS];
405 u8 padding;
406} __packed;
407
408struct ar5416_eeprom_4k {
409 struct base_eep_header_4k baseEepHeader;
410 u8 custData[20];
411 struct modal_eep_4k_header modalHeader;
412 u8 calFreqPier2G[AR5416_EEP4K_NUM_2G_CAL_PIERS];
413 struct cal_data_per_freq_4k
414 calPierData2G[AR5416_EEP4K_MAX_CHAINS][AR5416_EEP4K_NUM_2G_CAL_PIERS];
415 struct cal_target_power_leg
416 calTargetPowerCck[AR5416_EEP4K_NUM_2G_CCK_TARGET_POWERS];
417 struct cal_target_power_leg
418 calTargetPower2G[AR5416_EEP4K_NUM_2G_20_TARGET_POWERS];
419 struct cal_target_power_ht
420 calTargetPower2GHT20[AR5416_EEP4K_NUM_2G_20_TARGET_POWERS];
421 struct cal_target_power_ht
422 calTargetPower2GHT40[AR5416_EEP4K_NUM_2G_40_TARGET_POWERS];
423 u8 ctlIndex[AR5416_EEP4K_NUM_CTLS];
424 struct cal_ctl_data_4k ctlData[AR5416_EEP4K_NUM_CTLS];
425 u8 padding;
426} __packed;
427
428enum reg_ext_bitmap {
429 REG_EXT_JAPAN_MIDBAND = 1,
430 REG_EXT_FCC_DFS_HT40 = 2,
431 REG_EXT_JAPAN_NONDFS_HT40 = 3,
432 REG_EXT_JAPAN_DFS_HT40 = 4
433};
434
435struct ath9k_country_entry {
436 u16 countryCode;
437 u16 regDmnEnum;
438 u16 regDmn5G;
439 u16 regDmn2G;
440 u8 isMultidomain;
441 u8 iso[3];
442};
443
444enum ath9k_eep_map {
445 EEP_MAP_DEFAULT = 0x0,
446 EEP_MAP_4KBITS,
447 EEP_MAP_MAX
448};
449
450struct eeprom_ops {
451 int (*check_eeprom)(struct ath_hw *hw);
452 u32 (*get_eeprom)(struct ath_hw *hw, enum eeprom_param param);
453 bool (*fill_eeprom)(struct ath_hw *hw);
454 int (*get_eeprom_ver)(struct ath_hw *hw);
455 int (*get_eeprom_rev)(struct ath_hw *hw);
456 u8 (*get_num_ant_config)(struct ath_hw *hw, enum ieee80211_band band);
457 u16 (*get_eeprom_antenna_cfg)(struct ath_hw *hw,
458 struct ath9k_channel *chan);
459 bool (*set_board_values)(struct ath_hw *hw, struct ath9k_channel *chan);
460 void (*set_addac)(struct ath_hw *hw, struct ath9k_channel *chan);
461 int (*set_txpower)(struct ath_hw *hw, struct ath9k_channel *chan,
462 u16 cfgCtl, u8 twiceAntennaReduction,
463 u8 twiceMaxRegulatoryPower, u8 powerLimit);
464 u16 (*get_spur_channel)(struct ath_hw *ah, u16 i, bool is2GHz);
465};
466
467#define ar5416_get_ntxchains(_txchainmask) \
468 (((_txchainmask >> 2) & 1) + \
469 ((_txchainmask >> 1) & 1) + (_txchainmask & 1))
470
471int ath9k_hw_eeprom_attach(struct ath_hw *ah);
472
473#endif /* EEPROM_H */
diff --git a/drivers/net/wireless/ath9k/hw.c b/drivers/net/wireless/ath9k/hw.c
index 00ed44a0c313..cad8e39c201e 100644
--- a/drivers/net/wireless/ath9k/hw.c
+++ b/drivers/net/wireless/ath9k/hw.c
@@ -17,10 +17,7 @@
17#include <linux/io.h> 17#include <linux/io.h>
18#include <asm/unaligned.h> 18#include <asm/unaligned.h>
19 19
20#include "core.h" 20#include "ath9k.h"
21#include "hw.h"
22#include "reg.h"
23#include "phy.h"
24#include "initvals.h" 21#include "initvals.h"
25 22
26static int btcoex_enable; 23static int btcoex_enable;
@@ -31,58 +28,63 @@ MODULE_PARM_DESC(btcoex_enable, "Enable Bluetooth coexistence support");
31#define ATH9K_CLOCK_RATE_5GHZ_OFDM 40 28#define ATH9K_CLOCK_RATE_5GHZ_OFDM 40
32#define ATH9K_CLOCK_RATE_2GHZ_OFDM 44 29#define ATH9K_CLOCK_RATE_2GHZ_OFDM 44
33 30
34static bool ath9k_hw_set_reset_reg(struct ath_hal *ah, u32 type); 31static bool ath9k_hw_set_reset_reg(struct ath_hw *ah, u32 type);
35static void ath9k_hw_set_regs(struct ath_hal *ah, struct ath9k_channel *chan, 32static void ath9k_hw_set_regs(struct ath_hw *ah, struct ath9k_channel *chan,
36 enum ath9k_ht_macmode macmode); 33 enum ath9k_ht_macmode macmode);
37static u32 ath9k_hw_ini_fixup(struct ath_hal *ah, 34static u32 ath9k_hw_ini_fixup(struct ath_hw *ah,
38 struct ar5416_eeprom_def *pEepData, 35 struct ar5416_eeprom_def *pEepData,
39 u32 reg, u32 value); 36 u32 reg, u32 value);
40static void ath9k_hw_9280_spur_mitigate(struct ath_hal *ah, struct ath9k_channel *chan); 37static void ath9k_hw_9280_spur_mitigate(struct ath_hw *ah, struct ath9k_channel *chan);
41static void ath9k_hw_spur_mitigate(struct ath_hal *ah, struct ath9k_channel *chan); 38static void ath9k_hw_spur_mitigate(struct ath_hw *ah, struct ath9k_channel *chan);
42 39
43/********************/ 40/********************/
44/* Helper Functions */ 41/* Helper Functions */
45/********************/ 42/********************/
46 43
47static u32 ath9k_hw_mac_usec(struct ath_hal *ah, u32 clks) 44static u32 ath9k_hw_mac_usec(struct ath_hw *ah, u32 clks)
48{ 45{
49 struct ieee80211_conf *conf = &ah->ah_sc->hw->conf; 46 struct ieee80211_conf *conf = &ah->ah_sc->hw->conf;
50 if (!ah->ah_curchan) /* should really check for CCK instead */ 47
48 if (!ah->curchan) /* should really check for CCK instead */
51 return clks / ATH9K_CLOCK_RATE_CCK; 49 return clks / ATH9K_CLOCK_RATE_CCK;
52 if (conf->channel->band == IEEE80211_BAND_2GHZ) 50 if (conf->channel->band == IEEE80211_BAND_2GHZ)
53 return clks / ATH9K_CLOCK_RATE_2GHZ_OFDM; 51 return clks / ATH9K_CLOCK_RATE_2GHZ_OFDM;
52
54 return clks / ATH9K_CLOCK_RATE_5GHZ_OFDM; 53 return clks / ATH9K_CLOCK_RATE_5GHZ_OFDM;
55} 54}
56 55
57static u32 ath9k_hw_mac_to_usec(struct ath_hal *ah, u32 clks) 56static u32 ath9k_hw_mac_to_usec(struct ath_hw *ah, u32 clks)
58{ 57{
59 struct ieee80211_conf *conf = &ah->ah_sc->hw->conf; 58 struct ieee80211_conf *conf = &ah->ah_sc->hw->conf;
59
60 if (conf_is_ht40(conf)) 60 if (conf_is_ht40(conf))
61 return ath9k_hw_mac_usec(ah, clks) / 2; 61 return ath9k_hw_mac_usec(ah, clks) / 2;
62 else 62 else
63 return ath9k_hw_mac_usec(ah, clks); 63 return ath9k_hw_mac_usec(ah, clks);
64} 64}
65 65
66static u32 ath9k_hw_mac_clks(struct ath_hal *ah, u32 usecs) 66static u32 ath9k_hw_mac_clks(struct ath_hw *ah, u32 usecs)
67{ 67{
68 struct ieee80211_conf *conf = &ah->ah_sc->hw->conf; 68 struct ieee80211_conf *conf = &ah->ah_sc->hw->conf;
69 if (!ah->ah_curchan) /* should really check for CCK instead */ 69
70 if (!ah->curchan) /* should really check for CCK instead */
70 return usecs *ATH9K_CLOCK_RATE_CCK; 71 return usecs *ATH9K_CLOCK_RATE_CCK;
71 if (conf->channel->band == IEEE80211_BAND_2GHZ) 72 if (conf->channel->band == IEEE80211_BAND_2GHZ)
72 return usecs *ATH9K_CLOCK_RATE_2GHZ_OFDM; 73 return usecs *ATH9K_CLOCK_RATE_2GHZ_OFDM;
73 return usecs *ATH9K_CLOCK_RATE_5GHZ_OFDM; 74 return usecs *ATH9K_CLOCK_RATE_5GHZ_OFDM;
74} 75}
75 76
76static u32 ath9k_hw_mac_to_clks(struct ath_hal *ah, u32 usecs) 77static u32 ath9k_hw_mac_to_clks(struct ath_hw *ah, u32 usecs)
77{ 78{
78 struct ieee80211_conf *conf = &ah->ah_sc->hw->conf; 79 struct ieee80211_conf *conf = &ah->ah_sc->hw->conf;
80
79 if (conf_is_ht40(conf)) 81 if (conf_is_ht40(conf))
80 return ath9k_hw_mac_clks(ah, usecs) * 2; 82 return ath9k_hw_mac_clks(ah, usecs) * 2;
81 else 83 else
82 return ath9k_hw_mac_clks(ah, usecs); 84 return ath9k_hw_mac_clks(ah, usecs);
83} 85}
84 86
85bool ath9k_hw_wait(struct ath_hal *ah, u32 reg, u32 mask, u32 val) 87bool ath9k_hw_wait(struct ath_hw *ah, u32 reg, u32 mask, u32 val)
86{ 88{
87 int i; 89 int i;
88 90
@@ -112,11 +114,11 @@ u32 ath9k_hw_reverse_bits(u32 val, u32 n)
112 return retval; 114 return retval;
113} 115}
114 116
115bool ath9k_get_channel_edges(struct ath_hal *ah, 117bool ath9k_get_channel_edges(struct ath_hw *ah,
116 u16 flags, u16 *low, 118 u16 flags, u16 *low,
117 u16 *high) 119 u16 *high)
118{ 120{
119 struct ath9k_hw_capabilities *pCap = &ah->ah_caps; 121 struct ath9k_hw_capabilities *pCap = &ah->caps;
120 122
121 if (flags & CHANNEL_5GHZ) { 123 if (flags & CHANNEL_5GHZ) {
122 *low = pCap->low_5ghz_chan; 124 *low = pCap->low_5ghz_chan;
@@ -131,7 +133,7 @@ bool ath9k_get_channel_edges(struct ath_hal *ah,
131 return false; 133 return false;
132} 134}
133 135
134u16 ath9k_hw_computetxtime(struct ath_hal *ah, 136u16 ath9k_hw_computetxtime(struct ath_hw *ah,
135 struct ath_rate_table *rates, 137 struct ath_rate_table *rates,
136 u32 frameLen, u16 rateix, 138 u32 frameLen, u16 rateix,
137 bool shortPreamble) 139 bool shortPreamble)
@@ -153,15 +155,15 @@ u16 ath9k_hw_computetxtime(struct ath_hal *ah,
153 txTime = CCK_SIFS_TIME + phyTime + ((numBits * 1000) / kbps); 155 txTime = CCK_SIFS_TIME + phyTime + ((numBits * 1000) / kbps);
154 break; 156 break;
155 case WLAN_RC_PHY_OFDM: 157 case WLAN_RC_PHY_OFDM:
156 if (ah->ah_curchan && IS_CHAN_QUARTER_RATE(ah->ah_curchan)) { 158 if (ah->curchan && IS_CHAN_QUARTER_RATE(ah->curchan)) {
157 bitsPerSymbol = (kbps * OFDM_SYMBOL_TIME_QUARTER) / 1000; 159 bitsPerSymbol = (kbps * OFDM_SYMBOL_TIME_QUARTER) / 1000;
158 numBits = OFDM_PLCP_BITS + (frameLen << 3); 160 numBits = OFDM_PLCP_BITS + (frameLen << 3);
159 numSymbols = DIV_ROUND_UP(numBits, bitsPerSymbol); 161 numSymbols = DIV_ROUND_UP(numBits, bitsPerSymbol);
160 txTime = OFDM_SIFS_TIME_QUARTER 162 txTime = OFDM_SIFS_TIME_QUARTER
161 + OFDM_PREAMBLE_TIME_QUARTER 163 + OFDM_PREAMBLE_TIME_QUARTER
162 + (numSymbols * OFDM_SYMBOL_TIME_QUARTER); 164 + (numSymbols * OFDM_SYMBOL_TIME_QUARTER);
163 } else if (ah->ah_curchan && 165 } else if (ah->curchan &&
164 IS_CHAN_HALF_RATE(ah->ah_curchan)) { 166 IS_CHAN_HALF_RATE(ah->curchan)) {
165 bitsPerSymbol = (kbps * OFDM_SYMBOL_TIME_HALF) / 1000; 167 bitsPerSymbol = (kbps * OFDM_SYMBOL_TIME_HALF) / 1000;
166 numBits = OFDM_PLCP_BITS + (frameLen << 3); 168 numBits = OFDM_PLCP_BITS + (frameLen << 3);
167 numSymbols = DIV_ROUND_UP(numBits, bitsPerSymbol); 169 numSymbols = DIV_ROUND_UP(numBits, bitsPerSymbol);
@@ -187,12 +189,11 @@ u16 ath9k_hw_computetxtime(struct ath_hal *ah,
187 return txTime; 189 return txTime;
188} 190}
189 191
190void ath9k_hw_get_channel_centers(struct ath_hal *ah, 192void ath9k_hw_get_channel_centers(struct ath_hw *ah,
191 struct ath9k_channel *chan, 193 struct ath9k_channel *chan,
192 struct chan_centers *centers) 194 struct chan_centers *centers)
193{ 195{
194 int8_t extoff; 196 int8_t extoff;
195 struct ath_hal_5416 *ahp = AH5416(ah);
196 197
197 if (!IS_CHAN_HT40(chan)) { 198 if (!IS_CHAN_HT40(chan)) {
198 centers->ctl_center = centers->ext_center = 199 centers->ctl_center = centers->ext_center =
@@ -215,16 +216,15 @@ void ath9k_hw_get_channel_centers(struct ath_hal *ah,
215 centers->synth_center - (extoff * HT40_CHANNEL_CENTER_SHIFT); 216 centers->synth_center - (extoff * HT40_CHANNEL_CENTER_SHIFT);
216 centers->ext_center = 217 centers->ext_center =
217 centers->synth_center + (extoff * 218 centers->synth_center + (extoff *
218 ((ahp->ah_extprotspacing == ATH9K_HT_EXTPROTSPACING_20) ? 219 ((ah->extprotspacing == ATH9K_HT_EXTPROTSPACING_20) ?
219 HT40_CHANNEL_CENTER_SHIFT : 15)); 220 HT40_CHANNEL_CENTER_SHIFT : 15));
220
221} 221}
222 222
223/******************/ 223/******************/
224/* Chip Revisions */ 224/* Chip Revisions */
225/******************/ 225/******************/
226 226
227static void ath9k_hw_read_revisions(struct ath_hal *ah) 227static void ath9k_hw_read_revisions(struct ath_hw *ah)
228{ 228{
229 u32 val; 229 u32 val;
230 230
@@ -232,21 +232,22 @@ static void ath9k_hw_read_revisions(struct ath_hal *ah)
232 232
233 if (val == 0xFF) { 233 if (val == 0xFF) {
234 val = REG_READ(ah, AR_SREV); 234 val = REG_READ(ah, AR_SREV);
235 ah->ah_macVersion = (val & AR_SREV_VERSION2) >> AR_SREV_TYPE2_S; 235 ah->hw_version.macVersion =
236 ah->ah_macRev = MS(val, AR_SREV_REVISION2); 236 (val & AR_SREV_VERSION2) >> AR_SREV_TYPE2_S;
237 ah->ah_isPciExpress = (val & AR_SREV_TYPE2_HOST_MODE) ? 0 : 1; 237 ah->hw_version.macRev = MS(val, AR_SREV_REVISION2);
238 ah->is_pciexpress = (val & AR_SREV_TYPE2_HOST_MODE) ? 0 : 1;
238 } else { 239 } else {
239 if (!AR_SREV_9100(ah)) 240 if (!AR_SREV_9100(ah))
240 ah->ah_macVersion = MS(val, AR_SREV_VERSION); 241 ah->hw_version.macVersion = MS(val, AR_SREV_VERSION);
241 242
242 ah->ah_macRev = val & AR_SREV_REVISION; 243 ah->hw_version.macRev = val & AR_SREV_REVISION;
243 244
244 if (ah->ah_macVersion == AR_SREV_VERSION_5416_PCIE) 245 if (ah->hw_version.macVersion == AR_SREV_VERSION_5416_PCIE)
245 ah->ah_isPciExpress = true; 246 ah->is_pciexpress = true;
246 } 247 }
247} 248}
248 249
249static int ath9k_hw_get_radiorev(struct ath_hal *ah) 250static int ath9k_hw_get_radiorev(struct ath_hw *ah)
250{ 251{
251 u32 val; 252 u32 val;
252 int i; 253 int i;
@@ -265,7 +266,7 @@ static int ath9k_hw_get_radiorev(struct ath_hal *ah)
265/* HW Attach, Detach, Init Routines */ 266/* HW Attach, Detach, Init Routines */
266/************************************/ 267/************************************/
267 268
268static void ath9k_hw_disablepcie(struct ath_hal *ah) 269static void ath9k_hw_disablepcie(struct ath_hw *ah)
269{ 270{
270 if (AR_SREV_9100(ah)) 271 if (AR_SREV_9100(ah))
271 return; 272 return;
@@ -283,7 +284,7 @@ static void ath9k_hw_disablepcie(struct ath_hal *ah)
283 REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000); 284 REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000);
284} 285}
285 286
286static bool ath9k_hw_chip_test(struct ath_hal *ah) 287static bool ath9k_hw_chip_test(struct ath_hw *ah)
287{ 288{
288 u32 regAddr[2] = { AR_STA_ID0, AR_PHY_BASE + (8 << 2) }; 289 u32 regAddr[2] = { AR_STA_ID0, AR_PHY_BASE + (8 << 2) };
289 u32 regHold[2]; 290 u32 regHold[2];
@@ -325,6 +326,7 @@ static bool ath9k_hw_chip_test(struct ath_hal *ah)
325 REG_WRITE(ah, regAddr[i], regHold[i]); 326 REG_WRITE(ah, regAddr[i], regHold[i]);
326 } 327 }
327 udelay(100); 328 udelay(100);
329
328 return true; 330 return true;
329} 331}
330 332
@@ -349,99 +351,91 @@ static const char *ath9k_hw_devname(u16 devid)
349 return NULL; 351 return NULL;
350} 352}
351 353
352static void ath9k_hw_set_defaults(struct ath_hal *ah) 354static void ath9k_hw_set_defaults(struct ath_hw *ah)
353{ 355{
354 int i; 356 int i;
355 357
356 ah->ah_config.dma_beacon_response_time = 2; 358 ah->config.dma_beacon_response_time = 2;
357 ah->ah_config.sw_beacon_response_time = 10; 359 ah->config.sw_beacon_response_time = 10;
358 ah->ah_config.additional_swba_backoff = 0; 360 ah->config.additional_swba_backoff = 0;
359 ah->ah_config.ack_6mb = 0x0; 361 ah->config.ack_6mb = 0x0;
360 ah->ah_config.cwm_ignore_extcca = 0; 362 ah->config.cwm_ignore_extcca = 0;
361 ah->ah_config.pcie_powersave_enable = 0; 363 ah->config.pcie_powersave_enable = 0;
362 ah->ah_config.pcie_l1skp_enable = 0; 364 ah->config.pcie_l1skp_enable = 0;
363 ah->ah_config.pcie_clock_req = 0; 365 ah->config.pcie_clock_req = 0;
364 ah->ah_config.pcie_power_reset = 0x100; 366 ah->config.pcie_power_reset = 0x100;
365 ah->ah_config.pcie_restore = 0; 367 ah->config.pcie_restore = 0;
366 ah->ah_config.pcie_waen = 0; 368 ah->config.pcie_waen = 0;
367 ah->ah_config.analog_shiftreg = 1; 369 ah->config.analog_shiftreg = 1;
368 ah->ah_config.ht_enable = 1; 370 ah->config.ht_enable = 1;
369 ah->ah_config.ofdm_trig_low = 200; 371 ah->config.ofdm_trig_low = 200;
370 ah->ah_config.ofdm_trig_high = 500; 372 ah->config.ofdm_trig_high = 500;
371 ah->ah_config.cck_trig_high = 200; 373 ah->config.cck_trig_high = 200;
372 ah->ah_config.cck_trig_low = 100; 374 ah->config.cck_trig_low = 100;
373 ah->ah_config.enable_ani = 1; 375 ah->config.enable_ani = 1;
374 ah->ah_config.noise_immunity_level = 4; 376 ah->config.noise_immunity_level = 4;
375 ah->ah_config.ofdm_weaksignal_det = 1; 377 ah->config.ofdm_weaksignal_det = 1;
376 ah->ah_config.cck_weaksignal_thr = 0; 378 ah->config.cck_weaksignal_thr = 0;
377 ah->ah_config.spur_immunity_level = 2; 379 ah->config.spur_immunity_level = 2;
378 ah->ah_config.firstep_level = 0; 380 ah->config.firstep_level = 0;
379 ah->ah_config.rssi_thr_high = 40; 381 ah->config.rssi_thr_high = 40;
380 ah->ah_config.rssi_thr_low = 7; 382 ah->config.rssi_thr_low = 7;
381 ah->ah_config.diversity_control = 0; 383 ah->config.diversity_control = 0;
382 ah->ah_config.antenna_switch_swap = 0; 384 ah->config.antenna_switch_swap = 0;
383 385
384 for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) { 386 for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
385 ah->ah_config.spurchans[i][0] = AR_NO_SPUR; 387 ah->config.spurchans[i][0] = AR_NO_SPUR;
386 ah->ah_config.spurchans[i][1] = AR_NO_SPUR; 388 ah->config.spurchans[i][1] = AR_NO_SPUR;
387 } 389 }
388 390
389 ah->ah_config.intr_mitigation = 1; 391 ah->config.intr_mitigation = 1;
390} 392}
391 393
392static struct ath_hal_5416 *ath9k_hw_newstate(u16 devid, 394static struct ath_hw *ath9k_hw_newstate(u16 devid, struct ath_softc *sc,
393 struct ath_softc *sc, 395 int *status)
394 void __iomem *mem,
395 int *status)
396{ 396{
397 static const u8 defbssidmask[ETH_ALEN] = 397 struct ath_hw *ah;
398 { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
399 struct ath_hal_5416 *ahp;
400 struct ath_hal *ah;
401 398
402 ahp = kzalloc(sizeof(struct ath_hal_5416), GFP_KERNEL); 399 ah = kzalloc(sizeof(struct ath_hw), GFP_KERNEL);
403 if (ahp == NULL) { 400 if (ah == NULL) {
404 DPRINTF(sc, ATH_DBG_FATAL, 401 DPRINTF(sc, ATH_DBG_FATAL,
405 "Cannot allocate memory for state block\n"); 402 "Cannot allocate memory for state block\n");
406 *status = -ENOMEM; 403 *status = -ENOMEM;
407 return NULL; 404 return NULL;
408 } 405 }
409 406
410 ah = &ahp->ah;
411 ah->ah_sc = sc; 407 ah->ah_sc = sc;
412 ah->ah_sh = mem; 408 ah->hw_version.magic = AR5416_MAGIC;
413 ah->ah_magic = AR5416_MAGIC; 409 ah->regulatory.country_code = CTRY_DEFAULT;
414 ah->ah_countryCode = CTRY_DEFAULT; 410 ah->hw_version.devid = devid;
415 ah->ah_devid = devid; 411 ah->hw_version.subvendorid = 0;
416 ah->ah_subvendorid = 0;
417 412
418 ah->ah_flags = 0; 413 ah->ah_flags = 0;
419 if ((devid == AR5416_AR9100_DEVID)) 414 if ((devid == AR5416_AR9100_DEVID))
420 ah->ah_macVersion = AR_SREV_VERSION_9100; 415 ah->hw_version.macVersion = AR_SREV_VERSION_9100;
421 if (!AR_SREV_9100(ah)) 416 if (!AR_SREV_9100(ah))
422 ah->ah_flags = AH_USE_EEPROM; 417 ah->ah_flags = AH_USE_EEPROM;
423 418
424 ah->ah_powerLimit = MAX_RATE_POWER; 419 ah->regulatory.power_limit = MAX_RATE_POWER;
425 ah->ah_tpScale = ATH9K_TP_SCALE_MAX; 420 ah->regulatory.tp_scale = ATH9K_TP_SCALE_MAX;
426 ahp->ah_atimWindow = 0; 421 ah->atim_window = 0;
427 ahp->ah_diversityControl = ah->ah_config.diversity_control; 422 ah->diversity_control = ah->config.diversity_control;
428 ahp->ah_antennaSwitchSwap = 423 ah->antenna_switch_swap =
429 ah->ah_config.antenna_switch_swap; 424 ah->config.antenna_switch_swap;
430 ahp->ah_staId1Defaults = AR_STA_ID1_CRPT_MIC_ENABLE; 425 ah->sta_id1_defaults = AR_STA_ID1_CRPT_MIC_ENABLE;
431 ahp->ah_beaconInterval = 100; 426 ah->beacon_interval = 100;
432 ahp->ah_enable32kHzClock = DONT_USE_32KHZ; 427 ah->enable_32kHz_clock = DONT_USE_32KHZ;
433 ahp->ah_slottime = (u32) -1; 428 ah->slottime = (u32) -1;
434 ahp->ah_acktimeout = (u32) -1; 429 ah->acktimeout = (u32) -1;
435 ahp->ah_ctstimeout = (u32) -1; 430 ah->ctstimeout = (u32) -1;
436 ahp->ah_globaltxtimeout = (u32) -1; 431 ah->globaltxtimeout = (u32) -1;
437 memcpy(&ahp->ah_bssidmask, defbssidmask, ETH_ALEN); 432
438 433 ah->gbeacon_rate = 0;
439 ahp->ah_gBeaconRate = 0;
440 434
441 return ahp; 435 return ah;
442} 436}
443 437
444static int ath9k_hw_rfattach(struct ath_hal *ah) 438static int ath9k_hw_rfattach(struct ath_hw *ah)
445{ 439{
446 bool rfStatus = false; 440 bool rfStatus = false;
447 int ecode = 0; 441 int ecode = 0;
@@ -456,7 +450,7 @@ static int ath9k_hw_rfattach(struct ath_hal *ah)
456 return 0; 450 return 0;
457} 451}
458 452
459static int ath9k_hw_rf_claim(struct ath_hal *ah) 453static int ath9k_hw_rf_claim(struct ath_hw *ah)
460{ 454{
461 u32 val; 455 u32 val;
462 456
@@ -476,88 +470,87 @@ static int ath9k_hw_rf_claim(struct ath_hal *ah)
476 DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL, 470 DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
477 "5G Radio Chip Rev 0x%02X is not " 471 "5G Radio Chip Rev 0x%02X is not "
478 "supported by this driver\n", 472 "supported by this driver\n",
479 ah->ah_analog5GhzRev); 473 ah->hw_version.analog5GhzRev);
480 return -EOPNOTSUPP; 474 return -EOPNOTSUPP;
481 } 475 }
482 476
483 ah->ah_analog5GhzRev = val; 477 ah->hw_version.analog5GhzRev = val;
484 478
485 return 0; 479 return 0;
486} 480}
487 481
488static int ath9k_hw_init_macaddr(struct ath_hal *ah) 482static int ath9k_hw_init_macaddr(struct ath_hw *ah)
489{ 483{
490 u32 sum; 484 u32 sum;
491 int i; 485 int i;
492 u16 eeval; 486 u16 eeval;
493 struct ath_hal_5416 *ahp = AH5416(ah);
494 487
495 sum = 0; 488 sum = 0;
496 for (i = 0; i < 3; i++) { 489 for (i = 0; i < 3; i++) {
497 eeval = ath9k_hw_get_eeprom(ah, AR_EEPROM_MAC(i)); 490 eeval = ah->eep_ops->get_eeprom(ah, AR_EEPROM_MAC(i));
498 sum += eeval; 491 sum += eeval;
499 ahp->ah_macaddr[2 * i] = eeval >> 8; 492 ah->macaddr[2 * i] = eeval >> 8;
500 ahp->ah_macaddr[2 * i + 1] = eeval & 0xff; 493 ah->macaddr[2 * i + 1] = eeval & 0xff;
501 } 494 }
502 if (sum == 0 || sum == 0xffff * 3) { 495 if (sum == 0 || sum == 0xffff * 3) {
503 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, 496 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
504 "mac address read failed: %pM\n", 497 "mac address read failed: %pM\n",
505 ahp->ah_macaddr); 498 ah->macaddr);
506 return -EADDRNOTAVAIL; 499 return -EADDRNOTAVAIL;
507 } 500 }
508 501
509 return 0; 502 return 0;
510} 503}
511 504
512static void ath9k_hw_init_rxgain_ini(struct ath_hal *ah) 505static void ath9k_hw_init_rxgain_ini(struct ath_hw *ah)
513{ 506{
514 u32 rxgain_type; 507 u32 rxgain_type;
515 struct ath_hal_5416 *ahp = AH5416(ah);
516 508
517 if (ath9k_hw_get_eeprom(ah, EEP_MINOR_REV) >= AR5416_EEP_MINOR_VER_17) { 509 if (ah->eep_ops->get_eeprom(ah, EEP_MINOR_REV) >= AR5416_EEP_MINOR_VER_17) {
518 rxgain_type = ath9k_hw_get_eeprom(ah, EEP_RXGAIN_TYPE); 510 rxgain_type = ah->eep_ops->get_eeprom(ah, EEP_RXGAIN_TYPE);
519 511
520 if (rxgain_type == AR5416_EEP_RXGAIN_13DB_BACKOFF) 512 if (rxgain_type == AR5416_EEP_RXGAIN_13DB_BACKOFF)
521 INIT_INI_ARRAY(&ahp->ah_iniModesRxGain, 513 INIT_INI_ARRAY(&ah->iniModesRxGain,
522 ar9280Modes_backoff_13db_rxgain_9280_2, 514 ar9280Modes_backoff_13db_rxgain_9280_2,
523 ARRAY_SIZE(ar9280Modes_backoff_13db_rxgain_9280_2), 6); 515 ARRAY_SIZE(ar9280Modes_backoff_13db_rxgain_9280_2), 6);
524 else if (rxgain_type == AR5416_EEP_RXGAIN_23DB_BACKOFF) 516 else if (rxgain_type == AR5416_EEP_RXGAIN_23DB_BACKOFF)
525 INIT_INI_ARRAY(&ahp->ah_iniModesRxGain, 517 INIT_INI_ARRAY(&ah->iniModesRxGain,
526 ar9280Modes_backoff_23db_rxgain_9280_2, 518 ar9280Modes_backoff_23db_rxgain_9280_2,
527 ARRAY_SIZE(ar9280Modes_backoff_23db_rxgain_9280_2), 6); 519 ARRAY_SIZE(ar9280Modes_backoff_23db_rxgain_9280_2), 6);
528 else 520 else
529 INIT_INI_ARRAY(&ahp->ah_iniModesRxGain, 521 INIT_INI_ARRAY(&ah->iniModesRxGain,
530 ar9280Modes_original_rxgain_9280_2, 522 ar9280Modes_original_rxgain_9280_2,
531 ARRAY_SIZE(ar9280Modes_original_rxgain_9280_2), 6); 523 ARRAY_SIZE(ar9280Modes_original_rxgain_9280_2), 6);
532 } else 524 } else {
533 INIT_INI_ARRAY(&ahp->ah_iniModesRxGain, 525 INIT_INI_ARRAY(&ah->iniModesRxGain,
534 ar9280Modes_original_rxgain_9280_2, 526 ar9280Modes_original_rxgain_9280_2,
535 ARRAY_SIZE(ar9280Modes_original_rxgain_9280_2), 6); 527 ARRAY_SIZE(ar9280Modes_original_rxgain_9280_2), 6);
528 }
536} 529}
537 530
538static void ath9k_hw_init_txgain_ini(struct ath_hal *ah) 531static void ath9k_hw_init_txgain_ini(struct ath_hw *ah)
539{ 532{
540 u32 txgain_type; 533 u32 txgain_type;
541 struct ath_hal_5416 *ahp = AH5416(ah);
542 534
543 if (ath9k_hw_get_eeprom(ah, EEP_MINOR_REV) >= AR5416_EEP_MINOR_VER_19) { 535 if (ah->eep_ops->get_eeprom(ah, EEP_MINOR_REV) >= AR5416_EEP_MINOR_VER_19) {
544 txgain_type = ath9k_hw_get_eeprom(ah, EEP_TXGAIN_TYPE); 536 txgain_type = ah->eep_ops->get_eeprom(ah, EEP_TXGAIN_TYPE);
545 537
546 if (txgain_type == AR5416_EEP_TXGAIN_HIGH_POWER) 538 if (txgain_type == AR5416_EEP_TXGAIN_HIGH_POWER)
547 INIT_INI_ARRAY(&ahp->ah_iniModesTxGain, 539 INIT_INI_ARRAY(&ah->iniModesTxGain,
548 ar9280Modes_high_power_tx_gain_9280_2, 540 ar9280Modes_high_power_tx_gain_9280_2,
549 ARRAY_SIZE(ar9280Modes_high_power_tx_gain_9280_2), 6); 541 ARRAY_SIZE(ar9280Modes_high_power_tx_gain_9280_2), 6);
550 else 542 else
551 INIT_INI_ARRAY(&ahp->ah_iniModesTxGain, 543 INIT_INI_ARRAY(&ah->iniModesTxGain,
552 ar9280Modes_original_tx_gain_9280_2, 544 ar9280Modes_original_tx_gain_9280_2,
553 ARRAY_SIZE(ar9280Modes_original_tx_gain_9280_2), 6); 545 ARRAY_SIZE(ar9280Modes_original_tx_gain_9280_2), 6);
554 } else 546 } else {
555 INIT_INI_ARRAY(&ahp->ah_iniModesTxGain, 547 INIT_INI_ARRAY(&ah->iniModesTxGain,
556 ar9280Modes_original_tx_gain_9280_2, 548 ar9280Modes_original_tx_gain_9280_2,
557 ARRAY_SIZE(ar9280Modes_original_tx_gain_9280_2), 6); 549 ARRAY_SIZE(ar9280Modes_original_tx_gain_9280_2), 6);
550 }
558} 551}
559 552
560static int ath9k_hw_post_attach(struct ath_hal *ah) 553static int ath9k_hw_post_attach(struct ath_hw *ah)
561{ 554{
562 int ecode; 555 int ecode;
563 556
@@ -586,237 +579,234 @@ static int ath9k_hw_post_attach(struct ath_hal *ah)
586 return 0; 579 return 0;
587} 580}
588 581
589static struct ath_hal *ath9k_hw_do_attach(u16 devid, struct ath_softc *sc, 582static struct ath_hw *ath9k_hw_do_attach(u16 devid, struct ath_softc *sc,
590 void __iomem *mem, int *status) 583 int *status)
591{ 584{
592 struct ath_hal_5416 *ahp; 585 struct ath_hw *ah;
593 struct ath_hal *ah;
594 int ecode; 586 int ecode;
595 u32 i, j; 587 u32 i, j;
596 588
597 ahp = ath9k_hw_newstate(devid, sc, mem, status); 589 ah = ath9k_hw_newstate(devid, sc, status);
598 if (ahp == NULL) 590 if (ah == NULL)
599 return NULL; 591 return NULL;
600 592
601 ah = &ahp->ah;
602
603 ath9k_hw_set_defaults(ah); 593 ath9k_hw_set_defaults(ah);
604 594
605 if (ah->ah_config.intr_mitigation != 0) 595 if (ah->config.intr_mitigation != 0)
606 ahp->ah_intrMitigation = true; 596 ah->intr_mitigation = true;
607 597
608 if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_POWER_ON)) { 598 if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_POWER_ON)) {
609 DPRINTF(ah->ah_sc, ATH_DBG_RESET, "Couldn't reset chip\n"); 599 DPRINTF(sc, ATH_DBG_RESET, "Couldn't reset chip\n");
610 ecode = -EIO; 600 ecode = -EIO;
611 goto bad; 601 goto bad;
612 } 602 }
613 603
614 if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE)) { 604 if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE)) {
615 DPRINTF(ah->ah_sc, ATH_DBG_RESET, "Couldn't wakeup chip\n"); 605 DPRINTF(sc, ATH_DBG_RESET, "Couldn't wakeup chip\n");
616 ecode = -EIO; 606 ecode = -EIO;
617 goto bad; 607 goto bad;
618 } 608 }
619 609
620 if (ah->ah_config.serialize_regmode == SER_REG_MODE_AUTO) { 610 if (ah->config.serialize_regmode == SER_REG_MODE_AUTO) {
621 if (ah->ah_macVersion == AR_SREV_VERSION_5416_PCI) { 611 if (ah->hw_version.macVersion == AR_SREV_VERSION_5416_PCI) {
622 ah->ah_config.serialize_regmode = 612 ah->config.serialize_regmode =
623 SER_REG_MODE_ON; 613 SER_REG_MODE_ON;
624 } else { 614 } else {
625 ah->ah_config.serialize_regmode = 615 ah->config.serialize_regmode =
626 SER_REG_MODE_OFF; 616 SER_REG_MODE_OFF;
627 } 617 }
628 } 618 }
629 619
630 DPRINTF(ah->ah_sc, ATH_DBG_RESET, 620 DPRINTF(sc, ATH_DBG_RESET, "serialize_regmode is %d\n",
631 "serialize_regmode is %d\n", 621 ah->config.serialize_regmode);
632 ah->ah_config.serialize_regmode);
633 622
634 if ((ah->ah_macVersion != AR_SREV_VERSION_5416_PCI) && 623 if ((ah->hw_version.macVersion != AR_SREV_VERSION_5416_PCI) &&
635 (ah->ah_macVersion != AR_SREV_VERSION_5416_PCIE) && 624 (ah->hw_version.macVersion != AR_SREV_VERSION_5416_PCIE) &&
636 (ah->ah_macVersion != AR_SREV_VERSION_9160) && 625 (ah->hw_version.macVersion != AR_SREV_VERSION_9160) &&
637 (!AR_SREV_9100(ah)) && (!AR_SREV_9280(ah)) && (!AR_SREV_9285(ah))) { 626 (!AR_SREV_9100(ah)) && (!AR_SREV_9280(ah)) && (!AR_SREV_9285(ah))) {
638 DPRINTF(ah->ah_sc, ATH_DBG_RESET, 627 DPRINTF(sc, ATH_DBG_RESET,
639 "Mac Chip Rev 0x%02x.%x is not supported by " 628 "Mac Chip Rev 0x%02x.%x is not supported by "
640 "this driver\n", ah->ah_macVersion, ah->ah_macRev); 629 "this driver\n", ah->hw_version.macVersion,
630 ah->hw_version.macRev);
641 ecode = -EOPNOTSUPP; 631 ecode = -EOPNOTSUPP;
642 goto bad; 632 goto bad;
643 } 633 }
644 634
645 if (AR_SREV_9100(ah)) { 635 if (AR_SREV_9100(ah)) {
646 ahp->ah_iqCalData.calData = &iq_cal_multi_sample; 636 ah->iq_caldata.calData = &iq_cal_multi_sample;
647 ahp->ah_suppCals = IQ_MISMATCH_CAL; 637 ah->supp_cals = IQ_MISMATCH_CAL;
648 ah->ah_isPciExpress = false; 638 ah->is_pciexpress = false;
649 } 639 }
650 ah->ah_phyRev = REG_READ(ah, AR_PHY_CHIP_ID); 640 ah->hw_version.phyRev = REG_READ(ah, AR_PHY_CHIP_ID);
651 641
652 if (AR_SREV_9160_10_OR_LATER(ah)) { 642 if (AR_SREV_9160_10_OR_LATER(ah)) {
653 if (AR_SREV_9280_10_OR_LATER(ah)) { 643 if (AR_SREV_9280_10_OR_LATER(ah)) {
654 ahp->ah_iqCalData.calData = &iq_cal_single_sample; 644 ah->iq_caldata.calData = &iq_cal_single_sample;
655 ahp->ah_adcGainCalData.calData = 645 ah->adcgain_caldata.calData =
656 &adc_gain_cal_single_sample; 646 &adc_gain_cal_single_sample;
657 ahp->ah_adcDcCalData.calData = 647 ah->adcdc_caldata.calData =
658 &adc_dc_cal_single_sample; 648 &adc_dc_cal_single_sample;
659 ahp->ah_adcDcCalInitData.calData = 649 ah->adcdc_calinitdata.calData =
660 &adc_init_dc_cal; 650 &adc_init_dc_cal;
661 } else { 651 } else {
662 ahp->ah_iqCalData.calData = &iq_cal_multi_sample; 652 ah->iq_caldata.calData = &iq_cal_multi_sample;
663 ahp->ah_adcGainCalData.calData = 653 ah->adcgain_caldata.calData =
664 &adc_gain_cal_multi_sample; 654 &adc_gain_cal_multi_sample;
665 ahp->ah_adcDcCalData.calData = 655 ah->adcdc_caldata.calData =
666 &adc_dc_cal_multi_sample; 656 &adc_dc_cal_multi_sample;
667 ahp->ah_adcDcCalInitData.calData = 657 ah->adcdc_calinitdata.calData =
668 &adc_init_dc_cal; 658 &adc_init_dc_cal;
669 } 659 }
670 ahp->ah_suppCals = ADC_GAIN_CAL | ADC_DC_CAL | IQ_MISMATCH_CAL; 660 ah->supp_cals = ADC_GAIN_CAL | ADC_DC_CAL | IQ_MISMATCH_CAL;
671 } 661 }
672 662
673 if (AR_SREV_9160(ah)) { 663 if (AR_SREV_9160(ah)) {
674 ah->ah_config.enable_ani = 1; 664 ah->config.enable_ani = 1;
675 ahp->ah_ani_function = (ATH9K_ANI_SPUR_IMMUNITY_LEVEL | 665 ah->ani_function = (ATH9K_ANI_SPUR_IMMUNITY_LEVEL |
676 ATH9K_ANI_FIRSTEP_LEVEL); 666 ATH9K_ANI_FIRSTEP_LEVEL);
677 } else { 667 } else {
678 ahp->ah_ani_function = ATH9K_ANI_ALL; 668 ah->ani_function = ATH9K_ANI_ALL;
679 if (AR_SREV_9280_10_OR_LATER(ah)) { 669 if (AR_SREV_9280_10_OR_LATER(ah)) {
680 ahp->ah_ani_function &= ~ATH9K_ANI_NOISE_IMMUNITY_LEVEL; 670 ah->ani_function &= ~ATH9K_ANI_NOISE_IMMUNITY_LEVEL;
681 } 671 }
682 } 672 }
683 673
684 DPRINTF(ah->ah_sc, ATH_DBG_RESET, 674 DPRINTF(sc, ATH_DBG_RESET,
685 "This Mac Chip Rev 0x%02x.%x is \n", 675 "This Mac Chip Rev 0x%02x.%x is \n",
686 ah->ah_macVersion, ah->ah_macRev); 676 ah->hw_version.macVersion, ah->hw_version.macRev);
687 677
688 if (AR_SREV_9285_12_OR_LATER(ah)) { 678 if (AR_SREV_9285_12_OR_LATER(ah)) {
689 INIT_INI_ARRAY(&ahp->ah_iniModes, ar9285Modes_9285_1_2, 679 INIT_INI_ARRAY(&ah->iniModes, ar9285Modes_9285_1_2,
690 ARRAY_SIZE(ar9285Modes_9285_1_2), 6); 680 ARRAY_SIZE(ar9285Modes_9285_1_2), 6);
691 INIT_INI_ARRAY(&ahp->ah_iniCommon, ar9285Common_9285_1_2, 681 INIT_INI_ARRAY(&ah->iniCommon, ar9285Common_9285_1_2,
692 ARRAY_SIZE(ar9285Common_9285_1_2), 2); 682 ARRAY_SIZE(ar9285Common_9285_1_2), 2);
693 683
694 if (ah->ah_config.pcie_clock_req) { 684 if (ah->config.pcie_clock_req) {
695 INIT_INI_ARRAY(&ahp->ah_iniPcieSerdes, 685 INIT_INI_ARRAY(&ah->iniPcieSerdes,
696 ar9285PciePhy_clkreq_off_L1_9285_1_2, 686 ar9285PciePhy_clkreq_off_L1_9285_1_2,
697 ARRAY_SIZE(ar9285PciePhy_clkreq_off_L1_9285_1_2), 2); 687 ARRAY_SIZE(ar9285PciePhy_clkreq_off_L1_9285_1_2), 2);
698 } else { 688 } else {
699 INIT_INI_ARRAY(&ahp->ah_iniPcieSerdes, 689 INIT_INI_ARRAY(&ah->iniPcieSerdes,
700 ar9285PciePhy_clkreq_always_on_L1_9285_1_2, 690 ar9285PciePhy_clkreq_always_on_L1_9285_1_2,
701 ARRAY_SIZE(ar9285PciePhy_clkreq_always_on_L1_9285_1_2), 691 ARRAY_SIZE(ar9285PciePhy_clkreq_always_on_L1_9285_1_2),
702 2); 692 2);
703 } 693 }
704 } else if (AR_SREV_9285_10_OR_LATER(ah)) { 694 } else if (AR_SREV_9285_10_OR_LATER(ah)) {
705 INIT_INI_ARRAY(&ahp->ah_iniModes, ar9285Modes_9285, 695 INIT_INI_ARRAY(&ah->iniModes, ar9285Modes_9285,
706 ARRAY_SIZE(ar9285Modes_9285), 6); 696 ARRAY_SIZE(ar9285Modes_9285), 6);
707 INIT_INI_ARRAY(&ahp->ah_iniCommon, ar9285Common_9285, 697 INIT_INI_ARRAY(&ah->iniCommon, ar9285Common_9285,
708 ARRAY_SIZE(ar9285Common_9285), 2); 698 ARRAY_SIZE(ar9285Common_9285), 2);
709 699
710 if (ah->ah_config.pcie_clock_req) { 700 if (ah->config.pcie_clock_req) {
711 INIT_INI_ARRAY(&ahp->ah_iniPcieSerdes, 701 INIT_INI_ARRAY(&ah->iniPcieSerdes,
712 ar9285PciePhy_clkreq_off_L1_9285, 702 ar9285PciePhy_clkreq_off_L1_9285,
713 ARRAY_SIZE(ar9285PciePhy_clkreq_off_L1_9285), 2); 703 ARRAY_SIZE(ar9285PciePhy_clkreq_off_L1_9285), 2);
714 } else { 704 } else {
715 INIT_INI_ARRAY(&ahp->ah_iniPcieSerdes, 705 INIT_INI_ARRAY(&ah->iniPcieSerdes,
716 ar9285PciePhy_clkreq_always_on_L1_9285, 706 ar9285PciePhy_clkreq_always_on_L1_9285,
717 ARRAY_SIZE(ar9285PciePhy_clkreq_always_on_L1_9285), 2); 707 ARRAY_SIZE(ar9285PciePhy_clkreq_always_on_L1_9285), 2);
718 } 708 }
719 } else if (AR_SREV_9280_20_OR_LATER(ah)) { 709 } else if (AR_SREV_9280_20_OR_LATER(ah)) {
720 INIT_INI_ARRAY(&ahp->ah_iniModes, ar9280Modes_9280_2, 710 INIT_INI_ARRAY(&ah->iniModes, ar9280Modes_9280_2,
721 ARRAY_SIZE(ar9280Modes_9280_2), 6); 711 ARRAY_SIZE(ar9280Modes_9280_2), 6);
722 INIT_INI_ARRAY(&ahp->ah_iniCommon, ar9280Common_9280_2, 712 INIT_INI_ARRAY(&ah->iniCommon, ar9280Common_9280_2,
723 ARRAY_SIZE(ar9280Common_9280_2), 2); 713 ARRAY_SIZE(ar9280Common_9280_2), 2);
724 714
725 if (ah->ah_config.pcie_clock_req) { 715 if (ah->config.pcie_clock_req) {
726 INIT_INI_ARRAY(&ahp->ah_iniPcieSerdes, 716 INIT_INI_ARRAY(&ah->iniPcieSerdes,
727 ar9280PciePhy_clkreq_off_L1_9280, 717 ar9280PciePhy_clkreq_off_L1_9280,
728 ARRAY_SIZE(ar9280PciePhy_clkreq_off_L1_9280),2); 718 ARRAY_SIZE(ar9280PciePhy_clkreq_off_L1_9280),2);
729 } else { 719 } else {
730 INIT_INI_ARRAY(&ahp->ah_iniPcieSerdes, 720 INIT_INI_ARRAY(&ah->iniPcieSerdes,
731 ar9280PciePhy_clkreq_always_on_L1_9280, 721 ar9280PciePhy_clkreq_always_on_L1_9280,
732 ARRAY_SIZE(ar9280PciePhy_clkreq_always_on_L1_9280), 2); 722 ARRAY_SIZE(ar9280PciePhy_clkreq_always_on_L1_9280), 2);
733 } 723 }
734 INIT_INI_ARRAY(&ahp->ah_iniModesAdditional, 724 INIT_INI_ARRAY(&ah->iniModesAdditional,
735 ar9280Modes_fast_clock_9280_2, 725 ar9280Modes_fast_clock_9280_2,
736 ARRAY_SIZE(ar9280Modes_fast_clock_9280_2), 3); 726 ARRAY_SIZE(ar9280Modes_fast_clock_9280_2), 3);
737 } else if (AR_SREV_9280_10_OR_LATER(ah)) { 727 } else if (AR_SREV_9280_10_OR_LATER(ah)) {
738 INIT_INI_ARRAY(&ahp->ah_iniModes, ar9280Modes_9280, 728 INIT_INI_ARRAY(&ah->iniModes, ar9280Modes_9280,
739 ARRAY_SIZE(ar9280Modes_9280), 6); 729 ARRAY_SIZE(ar9280Modes_9280), 6);
740 INIT_INI_ARRAY(&ahp->ah_iniCommon, ar9280Common_9280, 730 INIT_INI_ARRAY(&ah->iniCommon, ar9280Common_9280,
741 ARRAY_SIZE(ar9280Common_9280), 2); 731 ARRAY_SIZE(ar9280Common_9280), 2);
742 } else if (AR_SREV_9160_10_OR_LATER(ah)) { 732 } else if (AR_SREV_9160_10_OR_LATER(ah)) {
743 INIT_INI_ARRAY(&ahp->ah_iniModes, ar5416Modes_9160, 733 INIT_INI_ARRAY(&ah->iniModes, ar5416Modes_9160,
744 ARRAY_SIZE(ar5416Modes_9160), 6); 734 ARRAY_SIZE(ar5416Modes_9160), 6);
745 INIT_INI_ARRAY(&ahp->ah_iniCommon, ar5416Common_9160, 735 INIT_INI_ARRAY(&ah->iniCommon, ar5416Common_9160,
746 ARRAY_SIZE(ar5416Common_9160), 2); 736 ARRAY_SIZE(ar5416Common_9160), 2);
747 INIT_INI_ARRAY(&ahp->ah_iniBank0, ar5416Bank0_9160, 737 INIT_INI_ARRAY(&ah->iniBank0, ar5416Bank0_9160,
748 ARRAY_SIZE(ar5416Bank0_9160), 2); 738 ARRAY_SIZE(ar5416Bank0_9160), 2);
749 INIT_INI_ARRAY(&ahp->ah_iniBB_RfGain, ar5416BB_RfGain_9160, 739 INIT_INI_ARRAY(&ah->iniBB_RfGain, ar5416BB_RfGain_9160,
750 ARRAY_SIZE(ar5416BB_RfGain_9160), 3); 740 ARRAY_SIZE(ar5416BB_RfGain_9160), 3);
751 INIT_INI_ARRAY(&ahp->ah_iniBank1, ar5416Bank1_9160, 741 INIT_INI_ARRAY(&ah->iniBank1, ar5416Bank1_9160,
752 ARRAY_SIZE(ar5416Bank1_9160), 2); 742 ARRAY_SIZE(ar5416Bank1_9160), 2);
753 INIT_INI_ARRAY(&ahp->ah_iniBank2, ar5416Bank2_9160, 743 INIT_INI_ARRAY(&ah->iniBank2, ar5416Bank2_9160,
754 ARRAY_SIZE(ar5416Bank2_9160), 2); 744 ARRAY_SIZE(ar5416Bank2_9160), 2);
755 INIT_INI_ARRAY(&ahp->ah_iniBank3, ar5416Bank3_9160, 745 INIT_INI_ARRAY(&ah->iniBank3, ar5416Bank3_9160,
756 ARRAY_SIZE(ar5416Bank3_9160), 3); 746 ARRAY_SIZE(ar5416Bank3_9160), 3);
757 INIT_INI_ARRAY(&ahp->ah_iniBank6, ar5416Bank6_9160, 747 INIT_INI_ARRAY(&ah->iniBank6, ar5416Bank6_9160,
758 ARRAY_SIZE(ar5416Bank6_9160), 3); 748 ARRAY_SIZE(ar5416Bank6_9160), 3);
759 INIT_INI_ARRAY(&ahp->ah_iniBank6TPC, ar5416Bank6TPC_9160, 749 INIT_INI_ARRAY(&ah->iniBank6TPC, ar5416Bank6TPC_9160,
760 ARRAY_SIZE(ar5416Bank6TPC_9160), 3); 750 ARRAY_SIZE(ar5416Bank6TPC_9160), 3);
761 INIT_INI_ARRAY(&ahp->ah_iniBank7, ar5416Bank7_9160, 751 INIT_INI_ARRAY(&ah->iniBank7, ar5416Bank7_9160,
762 ARRAY_SIZE(ar5416Bank7_9160), 2); 752 ARRAY_SIZE(ar5416Bank7_9160), 2);
763 if (AR_SREV_9160_11(ah)) { 753 if (AR_SREV_9160_11(ah)) {
764 INIT_INI_ARRAY(&ahp->ah_iniAddac, 754 INIT_INI_ARRAY(&ah->iniAddac,
765 ar5416Addac_91601_1, 755 ar5416Addac_91601_1,
766 ARRAY_SIZE(ar5416Addac_91601_1), 2); 756 ARRAY_SIZE(ar5416Addac_91601_1), 2);
767 } else { 757 } else {
768 INIT_INI_ARRAY(&ahp->ah_iniAddac, ar5416Addac_9160, 758 INIT_INI_ARRAY(&ah->iniAddac, ar5416Addac_9160,
769 ARRAY_SIZE(ar5416Addac_9160), 2); 759 ARRAY_SIZE(ar5416Addac_9160), 2);
770 } 760 }
771 } else if (AR_SREV_9100_OR_LATER(ah)) { 761 } else if (AR_SREV_9100_OR_LATER(ah)) {
772 INIT_INI_ARRAY(&ahp->ah_iniModes, ar5416Modes_9100, 762 INIT_INI_ARRAY(&ah->iniModes, ar5416Modes_9100,
773 ARRAY_SIZE(ar5416Modes_9100), 6); 763 ARRAY_SIZE(ar5416Modes_9100), 6);
774 INIT_INI_ARRAY(&ahp->ah_iniCommon, ar5416Common_9100, 764 INIT_INI_ARRAY(&ah->iniCommon, ar5416Common_9100,
775 ARRAY_SIZE(ar5416Common_9100), 2); 765 ARRAY_SIZE(ar5416Common_9100), 2);
776 INIT_INI_ARRAY(&ahp->ah_iniBank0, ar5416Bank0_9100, 766 INIT_INI_ARRAY(&ah->iniBank0, ar5416Bank0_9100,
777 ARRAY_SIZE(ar5416Bank0_9100), 2); 767 ARRAY_SIZE(ar5416Bank0_9100), 2);
778 INIT_INI_ARRAY(&ahp->ah_iniBB_RfGain, ar5416BB_RfGain_9100, 768 INIT_INI_ARRAY(&ah->iniBB_RfGain, ar5416BB_RfGain_9100,
779 ARRAY_SIZE(ar5416BB_RfGain_9100), 3); 769 ARRAY_SIZE(ar5416BB_RfGain_9100), 3);
780 INIT_INI_ARRAY(&ahp->ah_iniBank1, ar5416Bank1_9100, 770 INIT_INI_ARRAY(&ah->iniBank1, ar5416Bank1_9100,
781 ARRAY_SIZE(ar5416Bank1_9100), 2); 771 ARRAY_SIZE(ar5416Bank1_9100), 2);
782 INIT_INI_ARRAY(&ahp->ah_iniBank2, ar5416Bank2_9100, 772 INIT_INI_ARRAY(&ah->iniBank2, ar5416Bank2_9100,
783 ARRAY_SIZE(ar5416Bank2_9100), 2); 773 ARRAY_SIZE(ar5416Bank2_9100), 2);
784 INIT_INI_ARRAY(&ahp->ah_iniBank3, ar5416Bank3_9100, 774 INIT_INI_ARRAY(&ah->iniBank3, ar5416Bank3_9100,
785 ARRAY_SIZE(ar5416Bank3_9100), 3); 775 ARRAY_SIZE(ar5416Bank3_9100), 3);
786 INIT_INI_ARRAY(&ahp->ah_iniBank6, ar5416Bank6_9100, 776 INIT_INI_ARRAY(&ah->iniBank6, ar5416Bank6_9100,
787 ARRAY_SIZE(ar5416Bank6_9100), 3); 777 ARRAY_SIZE(ar5416Bank6_9100), 3);
788 INIT_INI_ARRAY(&ahp->ah_iniBank6TPC, ar5416Bank6TPC_9100, 778 INIT_INI_ARRAY(&ah->iniBank6TPC, ar5416Bank6TPC_9100,
789 ARRAY_SIZE(ar5416Bank6TPC_9100), 3); 779 ARRAY_SIZE(ar5416Bank6TPC_9100), 3);
790 INIT_INI_ARRAY(&ahp->ah_iniBank7, ar5416Bank7_9100, 780 INIT_INI_ARRAY(&ah->iniBank7, ar5416Bank7_9100,
791 ARRAY_SIZE(ar5416Bank7_9100), 2); 781 ARRAY_SIZE(ar5416Bank7_9100), 2);
792 INIT_INI_ARRAY(&ahp->ah_iniAddac, ar5416Addac_9100, 782 INIT_INI_ARRAY(&ah->iniAddac, ar5416Addac_9100,
793 ARRAY_SIZE(ar5416Addac_9100), 2); 783 ARRAY_SIZE(ar5416Addac_9100), 2);
794 } else { 784 } else {
795 INIT_INI_ARRAY(&ahp->ah_iniModes, ar5416Modes, 785 INIT_INI_ARRAY(&ah->iniModes, ar5416Modes,
796 ARRAY_SIZE(ar5416Modes), 6); 786 ARRAY_SIZE(ar5416Modes), 6);
797 INIT_INI_ARRAY(&ahp->ah_iniCommon, ar5416Common, 787 INIT_INI_ARRAY(&ah->iniCommon, ar5416Common,
798 ARRAY_SIZE(ar5416Common), 2); 788 ARRAY_SIZE(ar5416Common), 2);
799 INIT_INI_ARRAY(&ahp->ah_iniBank0, ar5416Bank0, 789 INIT_INI_ARRAY(&ah->iniBank0, ar5416Bank0,
800 ARRAY_SIZE(ar5416Bank0), 2); 790 ARRAY_SIZE(ar5416Bank0), 2);
801 INIT_INI_ARRAY(&ahp->ah_iniBB_RfGain, ar5416BB_RfGain, 791 INIT_INI_ARRAY(&ah->iniBB_RfGain, ar5416BB_RfGain,
802 ARRAY_SIZE(ar5416BB_RfGain), 3); 792 ARRAY_SIZE(ar5416BB_RfGain), 3);
803 INIT_INI_ARRAY(&ahp->ah_iniBank1, ar5416Bank1, 793 INIT_INI_ARRAY(&ah->iniBank1, ar5416Bank1,
804 ARRAY_SIZE(ar5416Bank1), 2); 794 ARRAY_SIZE(ar5416Bank1), 2);
805 INIT_INI_ARRAY(&ahp->ah_iniBank2, ar5416Bank2, 795 INIT_INI_ARRAY(&ah->iniBank2, ar5416Bank2,
806 ARRAY_SIZE(ar5416Bank2), 2); 796 ARRAY_SIZE(ar5416Bank2), 2);
807 INIT_INI_ARRAY(&ahp->ah_iniBank3, ar5416Bank3, 797 INIT_INI_ARRAY(&ah->iniBank3, ar5416Bank3,
808 ARRAY_SIZE(ar5416Bank3), 3); 798 ARRAY_SIZE(ar5416Bank3), 3);
809 INIT_INI_ARRAY(&ahp->ah_iniBank6, ar5416Bank6, 799 INIT_INI_ARRAY(&ah->iniBank6, ar5416Bank6,
810 ARRAY_SIZE(ar5416Bank6), 3); 800 ARRAY_SIZE(ar5416Bank6), 3);
811 INIT_INI_ARRAY(&ahp->ah_iniBank6TPC, ar5416Bank6TPC, 801 INIT_INI_ARRAY(&ah->iniBank6TPC, ar5416Bank6TPC,
812 ARRAY_SIZE(ar5416Bank6TPC), 3); 802 ARRAY_SIZE(ar5416Bank6TPC), 3);
813 INIT_INI_ARRAY(&ahp->ah_iniBank7, ar5416Bank7, 803 INIT_INI_ARRAY(&ah->iniBank7, ar5416Bank7,
814 ARRAY_SIZE(ar5416Bank7), 2); 804 ARRAY_SIZE(ar5416Bank7), 2);
815 INIT_INI_ARRAY(&ahp->ah_iniAddac, ar5416Addac, 805 INIT_INI_ARRAY(&ah->iniAddac, ar5416Addac,
816 ARRAY_SIZE(ar5416Addac), 2); 806 ARRAY_SIZE(ar5416Addac), 2);
817 } 807 }
818 808
819 if (ah->ah_isPciExpress) 809 if (ah->is_pciexpress)
820 ath9k_hw_configpcipowersave(ah, 0); 810 ath9k_hw_configpcipowersave(ah, 0);
821 else 811 else
822 ath9k_hw_disablepcie(ah); 812 ath9k_hw_disablepcie(ah);
@@ -833,23 +823,23 @@ static struct ath_hal *ath9k_hw_do_attach(u16 devid, struct ath_softc *sc,
833 if (AR_SREV_9280_20(ah)) 823 if (AR_SREV_9280_20(ah))
834 ath9k_hw_init_txgain_ini(ah); 824 ath9k_hw_init_txgain_ini(ah);
835 825
836 if (ah->ah_devid == AR9280_DEVID_PCI) { 826 if (ah->hw_version.devid == AR9280_DEVID_PCI) {
837 for (i = 0; i < ahp->ah_iniModes.ia_rows; i++) { 827 for (i = 0; i < ah->iniModes.ia_rows; i++) {
838 u32 reg = INI_RA(&ahp->ah_iniModes, i, 0); 828 u32 reg = INI_RA(&ah->iniModes, i, 0);
839 829
840 for (j = 1; j < ahp->ah_iniModes.ia_columns; j++) { 830 for (j = 1; j < ah->iniModes.ia_columns; j++) {
841 u32 val = INI_RA(&ahp->ah_iniModes, i, j); 831 u32 val = INI_RA(&ah->iniModes, i, j);
842 832
843 INI_RA(&ahp->ah_iniModes, i, j) = 833 INI_RA(&ah->iniModes, i, j) =
844 ath9k_hw_ini_fixup(ah, 834 ath9k_hw_ini_fixup(ah,
845 &ahp->ah_eeprom.def, 835 &ah->eeprom.def,
846 reg, val); 836 reg, val);
847 } 837 }
848 } 838 }
849 } 839 }
850 840
851 if (!ath9k_hw_fill_cap_info(ah)) { 841 if (!ath9k_hw_fill_cap_info(ah)) {
852 DPRINTF(ah->ah_sc, ATH_DBG_RESET, 842 DPRINTF(sc, ATH_DBG_RESET,
853 "failed ath9k_hw_fill_cap_info\n"); 843 "failed ath9k_hw_fill_cap_info\n");
854 ecode = -EINVAL; 844 ecode = -EINVAL;
855 goto bad; 845 goto bad;
@@ -857,29 +847,29 @@ static struct ath_hal *ath9k_hw_do_attach(u16 devid, struct ath_softc *sc,
857 847
858 ecode = ath9k_hw_init_macaddr(ah); 848 ecode = ath9k_hw_init_macaddr(ah);
859 if (ecode != 0) { 849 if (ecode != 0) {
860 DPRINTF(ah->ah_sc, ATH_DBG_RESET, 850 DPRINTF(sc, ATH_DBG_RESET,
861 "failed initializing mac address\n"); 851 "failed initializing mac address\n");
862 goto bad; 852 goto bad;
863 } 853 }
864 854
865 if (AR_SREV_9285(ah)) 855 if (AR_SREV_9285(ah))
866 ah->ah_txTrigLevel = (AR_FTRIG_256B >> AR_FTRIG_S); 856 ah->tx_trig_level = (AR_FTRIG_256B >> AR_FTRIG_S);
867 else 857 else
868 ah->ah_txTrigLevel = (AR_FTRIG_512B >> AR_FTRIG_S); 858 ah->tx_trig_level = (AR_FTRIG_512B >> AR_FTRIG_S);
869 859
870 ath9k_init_nfcal_hist_buffer(ah); 860 ath9k_init_nfcal_hist_buffer(ah);
871 861
872 return ah; 862 return ah;
873bad: 863bad:
874 if (ahp) 864 if (ah)
875 ath9k_hw_detach((struct ath_hal *) ahp); 865 ath9k_hw_detach(ah);
876 if (status) 866 if (status)
877 *status = ecode; 867 *status = ecode;
878 868
879 return NULL; 869 return NULL;
880} 870}
881 871
882static void ath9k_hw_init_bb(struct ath_hal *ah, 872static void ath9k_hw_init_bb(struct ath_hw *ah,
883 struct ath9k_channel *chan) 873 struct ath9k_channel *chan)
884{ 874{
885 u32 synthDelay; 875 u32 synthDelay;
@@ -895,7 +885,7 @@ static void ath9k_hw_init_bb(struct ath_hal *ah,
895 udelay(synthDelay + BASE_ACTIVATE_DELAY); 885 udelay(synthDelay + BASE_ACTIVATE_DELAY);
896} 886}
897 887
898static void ath9k_hw_init_qos(struct ath_hal *ah) 888static void ath9k_hw_init_qos(struct ath_hw *ah)
899{ 889{
900 REG_WRITE(ah, AR_MIC_QOS_CONTROL, 0x100aa); 890 REG_WRITE(ah, AR_MIC_QOS_CONTROL, 0x100aa);
901 REG_WRITE(ah, AR_MIC_QOS_SELECT, 0x3210); 891 REG_WRITE(ah, AR_MIC_QOS_SELECT, 0x3210);
@@ -912,7 +902,7 @@ static void ath9k_hw_init_qos(struct ath_hal *ah)
912 REG_WRITE(ah, AR_TXOP_12_15, 0xFFFFFFFF); 902 REG_WRITE(ah, AR_TXOP_12_15, 0xFFFFFFFF);
913} 903}
914 904
915static void ath9k_hw_init_pll(struct ath_hal *ah, 905static void ath9k_hw_init_pll(struct ath_hw *ah,
916 struct ath9k_channel *chan) 906 struct ath9k_channel *chan)
917{ 907{
918 u32 pll; 908 u32 pll;
@@ -980,20 +970,19 @@ static void ath9k_hw_init_pll(struct ath_hal *ah,
980 REG_WRITE(ah, AR_RTC_SLEEP_CLK, AR_RTC_FORCE_DERIVED_CLK); 970 REG_WRITE(ah, AR_RTC_SLEEP_CLK, AR_RTC_FORCE_DERIVED_CLK);
981} 971}
982 972
983static void ath9k_hw_init_chain_masks(struct ath_hal *ah) 973static void ath9k_hw_init_chain_masks(struct ath_hw *ah)
984{ 974{
985 struct ath_hal_5416 *ahp = AH5416(ah);
986 int rx_chainmask, tx_chainmask; 975 int rx_chainmask, tx_chainmask;
987 976
988 rx_chainmask = ahp->ah_rxchainmask; 977 rx_chainmask = ah->rxchainmask;
989 tx_chainmask = ahp->ah_txchainmask; 978 tx_chainmask = ah->txchainmask;
990 979
991 switch (rx_chainmask) { 980 switch (rx_chainmask) {
992 case 0x5: 981 case 0x5:
993 REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP, 982 REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP,
994 AR_PHY_SWAP_ALT_CHAIN); 983 AR_PHY_SWAP_ALT_CHAIN);
995 case 0x3: 984 case 0x3:
996 if (((ah)->ah_macVersion <= AR_SREV_VERSION_9160)) { 985 if (((ah)->hw_version.macVersion <= AR_SREV_VERSION_9160)) {
997 REG_WRITE(ah, AR_PHY_RX_CHAINMASK, 0x7); 986 REG_WRITE(ah, AR_PHY_RX_CHAINMASK, 0x7);
998 REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, 0x7); 987 REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, 0x7);
999 break; 988 break;
@@ -1018,28 +1007,26 @@ static void ath9k_hw_init_chain_masks(struct ath_hal *ah)
1018 REG_READ(ah, AR_PHY_ANALOG_SWAP) | 0x00000001); 1007 REG_READ(ah, AR_PHY_ANALOG_SWAP) | 0x00000001);
1019} 1008}
1020 1009
1021static void ath9k_hw_init_interrupt_masks(struct ath_hal *ah, 1010static void ath9k_hw_init_interrupt_masks(struct ath_hw *ah,
1022 enum nl80211_iftype opmode) 1011 enum nl80211_iftype opmode)
1023{ 1012{
1024 struct ath_hal_5416 *ahp = AH5416(ah); 1013 ah->mask_reg = AR_IMR_TXERR |
1025
1026 ahp->ah_maskReg = AR_IMR_TXERR |
1027 AR_IMR_TXURN | 1014 AR_IMR_TXURN |
1028 AR_IMR_RXERR | 1015 AR_IMR_RXERR |
1029 AR_IMR_RXORN | 1016 AR_IMR_RXORN |
1030 AR_IMR_BCNMISC; 1017 AR_IMR_BCNMISC;
1031 1018
1032 if (ahp->ah_intrMitigation) 1019 if (ah->intr_mitigation)
1033 ahp->ah_maskReg |= AR_IMR_RXINTM | AR_IMR_RXMINTR; 1020 ah->mask_reg |= AR_IMR_RXINTM | AR_IMR_RXMINTR;
1034 else 1021 else
1035 ahp->ah_maskReg |= AR_IMR_RXOK; 1022 ah->mask_reg |= AR_IMR_RXOK;
1036 1023
1037 ahp->ah_maskReg |= AR_IMR_TXOK; 1024 ah->mask_reg |= AR_IMR_TXOK;
1038 1025
1039 if (opmode == NL80211_IFTYPE_AP) 1026 if (opmode == NL80211_IFTYPE_AP)
1040 ahp->ah_maskReg |= AR_IMR_MIB; 1027 ah->mask_reg |= AR_IMR_MIB;
1041 1028
1042 REG_WRITE(ah, AR_IMR, ahp->ah_maskReg); 1029 REG_WRITE(ah, AR_IMR, ah->mask_reg);
1043 REG_WRITE(ah, AR_IMR_S2, REG_READ(ah, AR_IMR_S2) | AR_IMR_S2_GTT); 1030 REG_WRITE(ah, AR_IMR_S2, REG_READ(ah, AR_IMR_S2) | AR_IMR_S2_GTT);
1044 1031
1045 if (!AR_SREV_9100(ah)) { 1032 if (!AR_SREV_9100(ah)) {
@@ -1049,72 +1036,64 @@ static void ath9k_hw_init_interrupt_masks(struct ath_hal *ah,
1049 } 1036 }
1050} 1037}
1051 1038
1052static bool ath9k_hw_set_ack_timeout(struct ath_hal *ah, u32 us) 1039static bool ath9k_hw_set_ack_timeout(struct ath_hw *ah, u32 us)
1053{ 1040{
1054 struct ath_hal_5416 *ahp = AH5416(ah);
1055
1056 if (us > ath9k_hw_mac_to_usec(ah, MS(0xffffffff, AR_TIME_OUT_ACK))) { 1041 if (us > ath9k_hw_mac_to_usec(ah, MS(0xffffffff, AR_TIME_OUT_ACK))) {
1057 DPRINTF(ah->ah_sc, ATH_DBG_RESET, "bad ack timeout %u\n", us); 1042 DPRINTF(ah->ah_sc, ATH_DBG_RESET, "bad ack timeout %u\n", us);
1058 ahp->ah_acktimeout = (u32) -1; 1043 ah->acktimeout = (u32) -1;
1059 return false; 1044 return false;
1060 } else { 1045 } else {
1061 REG_RMW_FIELD(ah, AR_TIME_OUT, 1046 REG_RMW_FIELD(ah, AR_TIME_OUT,
1062 AR_TIME_OUT_ACK, ath9k_hw_mac_to_clks(ah, us)); 1047 AR_TIME_OUT_ACK, ath9k_hw_mac_to_clks(ah, us));
1063 ahp->ah_acktimeout = us; 1048 ah->acktimeout = us;
1064 return true; 1049 return true;
1065 } 1050 }
1066} 1051}
1067 1052
1068static bool ath9k_hw_set_cts_timeout(struct ath_hal *ah, u32 us) 1053static bool ath9k_hw_set_cts_timeout(struct ath_hw *ah, u32 us)
1069{ 1054{
1070 struct ath_hal_5416 *ahp = AH5416(ah);
1071
1072 if (us > ath9k_hw_mac_to_usec(ah, MS(0xffffffff, AR_TIME_OUT_CTS))) { 1055 if (us > ath9k_hw_mac_to_usec(ah, MS(0xffffffff, AR_TIME_OUT_CTS))) {
1073 DPRINTF(ah->ah_sc, ATH_DBG_RESET, "bad cts timeout %u\n", us); 1056 DPRINTF(ah->ah_sc, ATH_DBG_RESET, "bad cts timeout %u\n", us);
1074 ahp->ah_ctstimeout = (u32) -1; 1057 ah->ctstimeout = (u32) -1;
1075 return false; 1058 return false;
1076 } else { 1059 } else {
1077 REG_RMW_FIELD(ah, AR_TIME_OUT, 1060 REG_RMW_FIELD(ah, AR_TIME_OUT,
1078 AR_TIME_OUT_CTS, ath9k_hw_mac_to_clks(ah, us)); 1061 AR_TIME_OUT_CTS, ath9k_hw_mac_to_clks(ah, us));
1079 ahp->ah_ctstimeout = us; 1062 ah->ctstimeout = us;
1080 return true; 1063 return true;
1081 } 1064 }
1082} 1065}
1083 1066
1084static bool ath9k_hw_set_global_txtimeout(struct ath_hal *ah, u32 tu) 1067static bool ath9k_hw_set_global_txtimeout(struct ath_hw *ah, u32 tu)
1085{ 1068{
1086 struct ath_hal_5416 *ahp = AH5416(ah);
1087
1088 if (tu > 0xFFFF) { 1069 if (tu > 0xFFFF) {
1089 DPRINTF(ah->ah_sc, ATH_DBG_XMIT, 1070 DPRINTF(ah->ah_sc, ATH_DBG_XMIT,
1090 "bad global tx timeout %u\n", tu); 1071 "bad global tx timeout %u\n", tu);
1091 ahp->ah_globaltxtimeout = (u32) -1; 1072 ah->globaltxtimeout = (u32) -1;
1092 return false; 1073 return false;
1093 } else { 1074 } else {
1094 REG_RMW_FIELD(ah, AR_GTXTO, AR_GTXTO_TIMEOUT_LIMIT, tu); 1075 REG_RMW_FIELD(ah, AR_GTXTO, AR_GTXTO_TIMEOUT_LIMIT, tu);
1095 ahp->ah_globaltxtimeout = tu; 1076 ah->globaltxtimeout = tu;
1096 return true; 1077 return true;
1097 } 1078 }
1098} 1079}
1099 1080
1100static void ath9k_hw_init_user_settings(struct ath_hal *ah) 1081static void ath9k_hw_init_user_settings(struct ath_hw *ah)
1101{ 1082{
1102 struct ath_hal_5416 *ahp = AH5416(ah); 1083 DPRINTF(ah->ah_sc, ATH_DBG_RESET, "ah->misc_mode 0x%x\n",
1103 1084 ah->misc_mode);
1104 DPRINTF(ah->ah_sc, ATH_DBG_RESET, "ahp->ah_miscMode 0x%x\n",
1105 ahp->ah_miscMode);
1106 1085
1107 if (ahp->ah_miscMode != 0) 1086 if (ah->misc_mode != 0)
1108 REG_WRITE(ah, AR_PCU_MISC, 1087 REG_WRITE(ah, AR_PCU_MISC,
1109 REG_READ(ah, AR_PCU_MISC) | ahp->ah_miscMode); 1088 REG_READ(ah, AR_PCU_MISC) | ah->misc_mode);
1110 if (ahp->ah_slottime != (u32) -1) 1089 if (ah->slottime != (u32) -1)
1111 ath9k_hw_setslottime(ah, ahp->ah_slottime); 1090 ath9k_hw_setslottime(ah, ah->slottime);
1112 if (ahp->ah_acktimeout != (u32) -1) 1091 if (ah->acktimeout != (u32) -1)
1113 ath9k_hw_set_ack_timeout(ah, ahp->ah_acktimeout); 1092 ath9k_hw_set_ack_timeout(ah, ah->acktimeout);
1114 if (ahp->ah_ctstimeout != (u32) -1) 1093 if (ah->ctstimeout != (u32) -1)
1115 ath9k_hw_set_cts_timeout(ah, ahp->ah_ctstimeout); 1094 ath9k_hw_set_cts_timeout(ah, ah->ctstimeout);
1116 if (ahp->ah_globaltxtimeout != (u32) -1) 1095 if (ah->globaltxtimeout != (u32) -1)
1117 ath9k_hw_set_global_txtimeout(ah, ahp->ah_globaltxtimeout); 1096 ath9k_hw_set_global_txtimeout(ah, ah->globaltxtimeout);
1118} 1097}
1119 1098
1120const char *ath9k_hw_probe(u16 vendorid, u16 devid) 1099const char *ath9k_hw_probe(u16 vendorid, u16 devid)
@@ -1123,7 +1102,7 @@ const char *ath9k_hw_probe(u16 vendorid, u16 devid)
1123 ath9k_hw_devname(devid) : NULL; 1102 ath9k_hw_devname(devid) : NULL;
1124} 1103}
1125 1104
1126void ath9k_hw_detach(struct ath_hal *ah) 1105void ath9k_hw_detach(struct ath_hw *ah)
1127{ 1106{
1128 if (!AR_SREV_9100(ah)) 1107 if (!AR_SREV_9100(ah))
1129 ath9k_hw_ani_detach(ah); 1108 ath9k_hw_ani_detach(ah);
@@ -1133,10 +1112,9 @@ void ath9k_hw_detach(struct ath_hal *ah)
1133 kfree(ah); 1112 kfree(ah);
1134} 1113}
1135 1114
1136struct ath_hal *ath9k_hw_attach(u16 devid, struct ath_softc *sc, 1115struct ath_hw *ath9k_hw_attach(u16 devid, struct ath_softc *sc, int *error)
1137 void __iomem *mem, int *error)
1138{ 1116{
1139 struct ath_hal *ah = NULL; 1117 struct ath_hw *ah = NULL;
1140 1118
1141 switch (devid) { 1119 switch (devid) {
1142 case AR5416_DEVID_PCI: 1120 case AR5416_DEVID_PCI:
@@ -1146,7 +1124,7 @@ struct ath_hal *ath9k_hw_attach(u16 devid, struct ath_softc *sc,
1146 case AR9280_DEVID_PCI: 1124 case AR9280_DEVID_PCI:
1147 case AR9280_DEVID_PCIE: 1125 case AR9280_DEVID_PCIE:
1148 case AR9285_DEVID_PCIE: 1126 case AR9285_DEVID_PCIE:
1149 ah = ath9k_hw_do_attach(devid, sc, mem, error); 1127 ah = ath9k_hw_do_attach(devid, sc, error);
1150 break; 1128 break;
1151 default: 1129 default:
1152 *error = -ENXIO; 1130 *error = -ENXIO;
@@ -1160,7 +1138,7 @@ struct ath_hal *ath9k_hw_attach(u16 devid, struct ath_softc *sc,
1160/* INI */ 1138/* INI */
1161/*******/ 1139/*******/
1162 1140
1163static void ath9k_hw_override_ini(struct ath_hal *ah, 1141static void ath9k_hw_override_ini(struct ath_hw *ah,
1164 struct ath9k_channel *chan) 1142 struct ath9k_channel *chan)
1165{ 1143{
1166 /* 1144 /*
@@ -1178,13 +1156,13 @@ static void ath9k_hw_override_ini(struct ath_hal *ah,
1178 REG_WRITE(ah, 0x9800 + (651 << 2), 0x11); 1156 REG_WRITE(ah, 0x9800 + (651 << 2), 0x11);
1179} 1157}
1180 1158
1181static u32 ath9k_hw_def_ini_fixup(struct ath_hal *ah, 1159static u32 ath9k_hw_def_ini_fixup(struct ath_hw *ah,
1182 struct ar5416_eeprom_def *pEepData, 1160 struct ar5416_eeprom_def *pEepData,
1183 u32 reg, u32 value) 1161 u32 reg, u32 value)
1184{ 1162{
1185 struct base_eep_header *pBase = &(pEepData->baseEepHeader); 1163 struct base_eep_header *pBase = &(pEepData->baseEepHeader);
1186 1164
1187 switch (ah->ah_devid) { 1165 switch (ah->hw_version.devid) {
1188 case AR9280_DEVID_PCI: 1166 case AR9280_DEVID_PCI:
1189 if (reg == 0x7894) { 1167 if (reg == 0x7894) {
1190 DPRINTF(ah->ah_sc, ATH_DBG_ANY, 1168 DPRINTF(ah->ah_sc, ATH_DBG_ANY,
@@ -1212,24 +1190,21 @@ static u32 ath9k_hw_def_ini_fixup(struct ath_hal *ah,
1212 return value; 1190 return value;
1213} 1191}
1214 1192
1215static u32 ath9k_hw_ini_fixup(struct ath_hal *ah, 1193static u32 ath9k_hw_ini_fixup(struct ath_hw *ah,
1216 struct ar5416_eeprom_def *pEepData, 1194 struct ar5416_eeprom_def *pEepData,
1217 u32 reg, u32 value) 1195 u32 reg, u32 value)
1218{ 1196{
1219 struct ath_hal_5416 *ahp = AH5416(ah); 1197 if (ah->eep_map == EEP_MAP_4KBITS)
1220
1221 if (ahp->ah_eep_map == EEP_MAP_4KBITS)
1222 return value; 1198 return value;
1223 else 1199 else
1224 return ath9k_hw_def_ini_fixup(ah, pEepData, reg, value); 1200 return ath9k_hw_def_ini_fixup(ah, pEepData, reg, value);
1225} 1201}
1226 1202
1227static int ath9k_hw_process_ini(struct ath_hal *ah, 1203static int ath9k_hw_process_ini(struct ath_hw *ah,
1228 struct ath9k_channel *chan, 1204 struct ath9k_channel *chan,
1229 enum ath9k_ht_macmode macmode) 1205 enum ath9k_ht_macmode macmode)
1230{ 1206{
1231 int i, regWrites = 0; 1207 int i, regWrites = 0;
1232 struct ath_hal_5416 *ahp = AH5416(ah);
1233 struct ieee80211_channel *channel = chan->chan; 1208 struct ieee80211_channel *channel = chan->chan;
1234 u32 modesIndex, freqIndex; 1209 u32 modesIndex, freqIndex;
1235 int status; 1210 int status;
@@ -1262,40 +1237,38 @@ static int ath9k_hw_process_ini(struct ath_hal *ah,
1262 } 1237 }
1263 1238
1264 REG_WRITE(ah, AR_PHY(0), 0x00000007); 1239 REG_WRITE(ah, AR_PHY(0), 0x00000007);
1265
1266 REG_WRITE(ah, AR_PHY_ADC_SERIAL_CTL, AR_PHY_SEL_EXTERNAL_RADIO); 1240 REG_WRITE(ah, AR_PHY_ADC_SERIAL_CTL, AR_PHY_SEL_EXTERNAL_RADIO);
1267 1241 ah->eep_ops->set_addac(ah, chan);
1268 ath9k_hw_set_addac(ah, chan);
1269 1242
1270 if (AR_SREV_5416_V22_OR_LATER(ah)) { 1243 if (AR_SREV_5416_V22_OR_LATER(ah)) {
1271 REG_WRITE_ARRAY(&ahp->ah_iniAddac, 1, regWrites); 1244 REG_WRITE_ARRAY(&ah->iniAddac, 1, regWrites);
1272 } else { 1245 } else {
1273 struct ar5416IniArray temp; 1246 struct ar5416IniArray temp;
1274 u32 addacSize = 1247 u32 addacSize =
1275 sizeof(u32) * ahp->ah_iniAddac.ia_rows * 1248 sizeof(u32) * ah->iniAddac.ia_rows *
1276 ahp->ah_iniAddac.ia_columns; 1249 ah->iniAddac.ia_columns;
1277 1250
1278 memcpy(ahp->ah_addac5416_21, 1251 memcpy(ah->addac5416_21,
1279 ahp->ah_iniAddac.ia_array, addacSize); 1252 ah->iniAddac.ia_array, addacSize);
1280 1253
1281 (ahp->ah_addac5416_21)[31 * ahp->ah_iniAddac.ia_columns + 1] = 0; 1254 (ah->addac5416_21)[31 * ah->iniAddac.ia_columns + 1] = 0;
1282 1255
1283 temp.ia_array = ahp->ah_addac5416_21; 1256 temp.ia_array = ah->addac5416_21;
1284 temp.ia_columns = ahp->ah_iniAddac.ia_columns; 1257 temp.ia_columns = ah->iniAddac.ia_columns;
1285 temp.ia_rows = ahp->ah_iniAddac.ia_rows; 1258 temp.ia_rows = ah->iniAddac.ia_rows;
1286 REG_WRITE_ARRAY(&temp, 1, regWrites); 1259 REG_WRITE_ARRAY(&temp, 1, regWrites);
1287 } 1260 }
1288 1261
1289 REG_WRITE(ah, AR_PHY_ADC_SERIAL_CTL, AR_PHY_SEL_INTERNAL_ADDAC); 1262 REG_WRITE(ah, AR_PHY_ADC_SERIAL_CTL, AR_PHY_SEL_INTERNAL_ADDAC);
1290 1263
1291 for (i = 0; i < ahp->ah_iniModes.ia_rows; i++) { 1264 for (i = 0; i < ah->iniModes.ia_rows; i++) {
1292 u32 reg = INI_RA(&ahp->ah_iniModes, i, 0); 1265 u32 reg = INI_RA(&ah->iniModes, i, 0);
1293 u32 val = INI_RA(&ahp->ah_iniModes, i, modesIndex); 1266 u32 val = INI_RA(&ah->iniModes, i, modesIndex);
1294 1267
1295 REG_WRITE(ah, reg, val); 1268 REG_WRITE(ah, reg, val);
1296 1269
1297 if (reg >= 0x7800 && reg < 0x78a0 1270 if (reg >= 0x7800 && reg < 0x78a0
1298 && ah->ah_config.analog_shiftreg) { 1271 && ah->config.analog_shiftreg) {
1299 udelay(100); 1272 udelay(100);
1300 } 1273 }
1301 1274
@@ -1303,19 +1276,19 @@ static int ath9k_hw_process_ini(struct ath_hal *ah,
1303 } 1276 }
1304 1277
1305 if (AR_SREV_9280(ah)) 1278 if (AR_SREV_9280(ah))
1306 REG_WRITE_ARRAY(&ahp->ah_iniModesRxGain, modesIndex, regWrites); 1279 REG_WRITE_ARRAY(&ah->iniModesRxGain, modesIndex, regWrites);
1307 1280
1308 if (AR_SREV_9280(ah)) 1281 if (AR_SREV_9280(ah))
1309 REG_WRITE_ARRAY(&ahp->ah_iniModesTxGain, modesIndex, regWrites); 1282 REG_WRITE_ARRAY(&ah->iniModesTxGain, modesIndex, regWrites);
1310 1283
1311 for (i = 0; i < ahp->ah_iniCommon.ia_rows; i++) { 1284 for (i = 0; i < ah->iniCommon.ia_rows; i++) {
1312 u32 reg = INI_RA(&ahp->ah_iniCommon, i, 0); 1285 u32 reg = INI_RA(&ah->iniCommon, i, 0);
1313 u32 val = INI_RA(&ahp->ah_iniCommon, i, 1); 1286 u32 val = INI_RA(&ah->iniCommon, i, 1);
1314 1287
1315 REG_WRITE(ah, reg, val); 1288 REG_WRITE(ah, reg, val);
1316 1289
1317 if (reg >= 0x7800 && reg < 0x78a0 1290 if (reg >= 0x7800 && reg < 0x78a0
1318 && ah->ah_config.analog_shiftreg) { 1291 && ah->config.analog_shiftreg) {
1319 udelay(100); 1292 udelay(100);
1320 } 1293 }
1321 1294
@@ -1325,7 +1298,7 @@ static int ath9k_hw_process_ini(struct ath_hal *ah,
1325 ath9k_hw_write_regs(ah, modesIndex, freqIndex, regWrites); 1298 ath9k_hw_write_regs(ah, modesIndex, freqIndex, regWrites);
1326 1299
1327 if (AR_SREV_9280_20(ah) && IS_CHAN_A_5MHZ_SPACED(chan)) { 1300 if (AR_SREV_9280_20(ah) && IS_CHAN_A_5MHZ_SPACED(chan)) {
1328 REG_WRITE_ARRAY(&ahp->ah_iniModesAdditional, modesIndex, 1301 REG_WRITE_ARRAY(&ah->iniModesAdditional, modesIndex,
1329 regWrites); 1302 regWrites);
1330 } 1303 }
1331 1304
@@ -1333,12 +1306,12 @@ static int ath9k_hw_process_ini(struct ath_hal *ah,
1333 ath9k_hw_set_regs(ah, chan, macmode); 1306 ath9k_hw_set_regs(ah, chan, macmode);
1334 ath9k_hw_init_chain_masks(ah); 1307 ath9k_hw_init_chain_masks(ah);
1335 1308
1336 status = ath9k_hw_set_txpower(ah, chan, 1309 status = ah->eep_ops->set_txpower(ah, chan,
1337 ath9k_regd_get_ctl(ah, chan), 1310 ath9k_regd_get_ctl(ah, chan),
1338 channel->max_antenna_gain * 2, 1311 channel->max_antenna_gain * 2,
1339 channel->max_power * 2, 1312 channel->max_power * 2,
1340 min((u32) MAX_RATE_POWER, 1313 min((u32) MAX_RATE_POWER,
1341 (u32) ah->ah_powerLimit)); 1314 (u32) ah->regulatory.power_limit));
1342 if (status != 0) { 1315 if (status != 0) {
1343 DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT, 1316 DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
1344 "error init'ing transmit power\n"); 1317 "error init'ing transmit power\n");
@@ -1358,7 +1331,7 @@ static int ath9k_hw_process_ini(struct ath_hal *ah,
1358/* Reset and Channel Switching Routines */ 1331/* Reset and Channel Switching Routines */
1359/****************************************/ 1332/****************************************/
1360 1333
1361static void ath9k_hw_set_rfmode(struct ath_hal *ah, struct ath9k_channel *chan) 1334static void ath9k_hw_set_rfmode(struct ath_hw *ah, struct ath9k_channel *chan)
1362{ 1335{
1363 u32 rfMode = 0; 1336 u32 rfMode = 0;
1364 1337
@@ -1378,12 +1351,12 @@ static void ath9k_hw_set_rfmode(struct ath_hal *ah, struct ath9k_channel *chan)
1378 REG_WRITE(ah, AR_PHY_MODE, rfMode); 1351 REG_WRITE(ah, AR_PHY_MODE, rfMode);
1379} 1352}
1380 1353
1381static void ath9k_hw_mark_phy_inactive(struct ath_hal *ah) 1354static void ath9k_hw_mark_phy_inactive(struct ath_hw *ah)
1382{ 1355{
1383 REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_DIS); 1356 REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_DIS);
1384} 1357}
1385 1358
1386static inline void ath9k_hw_set_dma(struct ath_hal *ah) 1359static inline void ath9k_hw_set_dma(struct ath_hw *ah)
1387{ 1360{
1388 u32 regval; 1361 u32 regval;
1389 1362
@@ -1393,7 +1366,7 @@ static inline void ath9k_hw_set_dma(struct ath_hal *ah)
1393 regval = REG_READ(ah, AR_TXCFG) & ~AR_TXCFG_DMASZ_MASK; 1366 regval = REG_READ(ah, AR_TXCFG) & ~AR_TXCFG_DMASZ_MASK;
1394 REG_WRITE(ah, AR_TXCFG, regval | AR_TXCFG_DMASZ_128B); 1367 REG_WRITE(ah, AR_TXCFG, regval | AR_TXCFG_DMASZ_128B);
1395 1368
1396 REG_RMW_FIELD(ah, AR_TXCFG, AR_FTRIG, ah->ah_txTrigLevel); 1369 REG_RMW_FIELD(ah, AR_TXCFG, AR_FTRIG, ah->tx_trig_level);
1397 1370
1398 regval = REG_READ(ah, AR_RXCFG) & ~AR_RXCFG_DMASZ_MASK; 1371 regval = REG_READ(ah, AR_RXCFG) & ~AR_RXCFG_DMASZ_MASK;
1399 REG_WRITE(ah, AR_RXCFG, regval | AR_RXCFG_DMASZ_128B); 1372 REG_WRITE(ah, AR_RXCFG, regval | AR_RXCFG_DMASZ_128B);
@@ -1409,7 +1382,7 @@ static inline void ath9k_hw_set_dma(struct ath_hal *ah)
1409 } 1382 }
1410} 1383}
1411 1384
1412static void ath9k_hw_set_operating_mode(struct ath_hal *ah, int opmode) 1385static void ath9k_hw_set_operating_mode(struct ath_hw *ah, int opmode)
1413{ 1386{
1414 u32 val; 1387 u32 val;
1415 1388
@@ -1433,7 +1406,7 @@ static void ath9k_hw_set_operating_mode(struct ath_hal *ah, int opmode)
1433 } 1406 }
1434} 1407}
1435 1408
1436static inline void ath9k_hw_get_delta_slope_vals(struct ath_hal *ah, 1409static inline void ath9k_hw_get_delta_slope_vals(struct ath_hw *ah,
1437 u32 coef_scaled, 1410 u32 coef_scaled,
1438 u32 *coef_mantissa, 1411 u32 *coef_mantissa,
1439 u32 *coef_exponent) 1412 u32 *coef_exponent)
@@ -1452,7 +1425,7 @@ static inline void ath9k_hw_get_delta_slope_vals(struct ath_hal *ah,
1452 *coef_exponent = coef_exp - 16; 1425 *coef_exponent = coef_exp - 16;
1453} 1426}
1454 1427
1455static void ath9k_hw_set_delta_slope(struct ath_hal *ah, 1428static void ath9k_hw_set_delta_slope(struct ath_hw *ah,
1456 struct ath9k_channel *chan) 1429 struct ath9k_channel *chan)
1457{ 1430{
1458 u32 coef_scaled, ds_coef_exp, ds_coef_man; 1431 u32 coef_scaled, ds_coef_exp, ds_coef_man;
@@ -1486,7 +1459,7 @@ static void ath9k_hw_set_delta_slope(struct ath_hal *ah,
1486 AR_PHY_HALFGI_DSC_EXP, ds_coef_exp); 1459 AR_PHY_HALFGI_DSC_EXP, ds_coef_exp);
1487} 1460}
1488 1461
1489static bool ath9k_hw_set_reset(struct ath_hal *ah, int type) 1462static bool ath9k_hw_set_reset(struct ath_hw *ah, int type)
1490{ 1463{
1491 u32 rst_flags; 1464 u32 rst_flags;
1492 u32 tmpReg; 1465 u32 tmpReg;
@@ -1534,7 +1507,7 @@ static bool ath9k_hw_set_reset(struct ath_hal *ah, int type)
1534 return true; 1507 return true;
1535} 1508}
1536 1509
1537static bool ath9k_hw_set_reset_power_on(struct ath_hal *ah) 1510static bool ath9k_hw_set_reset_power_on(struct ath_hw *ah)
1538{ 1511{
1539 REG_WRITE(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_EN | 1512 REG_WRITE(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_EN |
1540 AR_RTC_FORCE_WAKE_ON_INT); 1513 AR_RTC_FORCE_WAKE_ON_INT);
@@ -1555,7 +1528,7 @@ static bool ath9k_hw_set_reset_power_on(struct ath_hal *ah)
1555 return ath9k_hw_set_reset(ah, ATH9K_RESET_WARM); 1528 return ath9k_hw_set_reset(ah, ATH9K_RESET_WARM);
1556} 1529}
1557 1530
1558static bool ath9k_hw_set_reset_reg(struct ath_hal *ah, u32 type) 1531static bool ath9k_hw_set_reset_reg(struct ath_hw *ah, u32 type)
1559{ 1532{
1560 REG_WRITE(ah, AR_RTC_FORCE_WAKE, 1533 REG_WRITE(ah, AR_RTC_FORCE_WAKE,
1561 AR_RTC_FORCE_WAKE_EN | AR_RTC_FORCE_WAKE_ON_INT); 1534 AR_RTC_FORCE_WAKE_EN | AR_RTC_FORCE_WAKE_ON_INT);
@@ -1573,12 +1546,11 @@ static bool ath9k_hw_set_reset_reg(struct ath_hal *ah, u32 type)
1573 } 1546 }
1574} 1547}
1575 1548
1576static void ath9k_hw_set_regs(struct ath_hal *ah, struct ath9k_channel *chan, 1549static void ath9k_hw_set_regs(struct ath_hw *ah, struct ath9k_channel *chan,
1577 enum ath9k_ht_macmode macmode) 1550 enum ath9k_ht_macmode macmode)
1578{ 1551{
1579 u32 phymode; 1552 u32 phymode;
1580 u32 enableDacFifo = 0; 1553 u32 enableDacFifo = 0;
1581 struct ath_hal_5416 *ahp = AH5416(ah);
1582 1554
1583 if (AR_SREV_9285_10_OR_LATER(ah)) 1555 if (AR_SREV_9285_10_OR_LATER(ah))
1584 enableDacFifo = (REG_READ(ah, AR_PHY_TURBO) & 1556 enableDacFifo = (REG_READ(ah, AR_PHY_TURBO) &
@@ -1594,7 +1566,7 @@ static void ath9k_hw_set_regs(struct ath_hal *ah, struct ath9k_channel *chan,
1594 (chan->chanmode == CHANNEL_G_HT40PLUS)) 1566 (chan->chanmode == CHANNEL_G_HT40PLUS))
1595 phymode |= AR_PHY_FC_DYN2040_PRI_CH; 1567 phymode |= AR_PHY_FC_DYN2040_PRI_CH;
1596 1568
1597 if (ahp->ah_extprotspacing == ATH9K_HT_EXTPROTSPACING_25) 1569 if (ah->extprotspacing == ATH9K_HT_EXTPROTSPACING_25)
1598 phymode |= AR_PHY_FC_DYN2040_EXT_CH; 1570 phymode |= AR_PHY_FC_DYN2040_EXT_CH;
1599 } 1571 }
1600 REG_WRITE(ah, AR_PHY_TURBO, phymode); 1572 REG_WRITE(ah, AR_PHY_TURBO, phymode);
@@ -1605,27 +1577,23 @@ static void ath9k_hw_set_regs(struct ath_hal *ah, struct ath9k_channel *chan,
1605 REG_WRITE(ah, AR_CST, 0xF << AR_CST_TIMEOUT_LIMIT_S); 1577 REG_WRITE(ah, AR_CST, 0xF << AR_CST_TIMEOUT_LIMIT_S);
1606} 1578}
1607 1579
1608static bool ath9k_hw_chip_reset(struct ath_hal *ah, 1580static bool ath9k_hw_chip_reset(struct ath_hw *ah,
1609 struct ath9k_channel *chan) 1581 struct ath9k_channel *chan)
1610{ 1582{
1611 struct ath_hal_5416 *ahp = AH5416(ah);
1612
1613 if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_WARM)) 1583 if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_WARM))
1614 return false; 1584 return false;
1615 1585
1616 if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE)) 1586 if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE))
1617 return false; 1587 return false;
1618 1588
1619 ahp->ah_chipFullSleep = false; 1589 ah->chip_fullsleep = false;
1620
1621 ath9k_hw_init_pll(ah, chan); 1590 ath9k_hw_init_pll(ah, chan);
1622
1623 ath9k_hw_set_rfmode(ah, chan); 1591 ath9k_hw_set_rfmode(ah, chan);
1624 1592
1625 return true; 1593 return true;
1626} 1594}
1627 1595
1628static bool ath9k_hw_channel_change(struct ath_hal *ah, 1596static bool ath9k_hw_channel_change(struct ath_hw *ah,
1629 struct ath9k_channel *chan, 1597 struct ath9k_channel *chan,
1630 enum ath9k_ht_macmode macmode) 1598 enum ath9k_ht_macmode macmode)
1631{ 1599{
@@ -1664,12 +1632,12 @@ static bool ath9k_hw_channel_change(struct ath_hal *ah,
1664 } 1632 }
1665 } 1633 }
1666 1634
1667 if (ath9k_hw_set_txpower(ah, chan, 1635 if (ah->eep_ops->set_txpower(ah, chan,
1668 ath9k_regd_get_ctl(ah, chan), 1636 ath9k_regd_get_ctl(ah, chan),
1669 channel->max_antenna_gain * 2, 1637 channel->max_antenna_gain * 2,
1670 channel->max_power * 2, 1638 channel->max_power * 2,
1671 min((u32) MAX_RATE_POWER, 1639 min((u32) MAX_RATE_POWER,
1672 (u32) ah->ah_powerLimit)) != 0) { 1640 (u32) ah->regulatory.power_limit)) != 0) {
1673 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, 1641 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
1674 "error init'ing transmit power\n"); 1642 "error init'ing transmit power\n");
1675 return false; 1643 return false;
@@ -1699,7 +1667,7 @@ static bool ath9k_hw_channel_change(struct ath_hal *ah,
1699 return true; 1667 return true;
1700} 1668}
1701 1669
1702static void ath9k_hw_9280_spur_mitigate(struct ath_hal *ah, struct ath9k_channel *chan) 1670static void ath9k_hw_9280_spur_mitigate(struct ath_hw *ah, struct ath9k_channel *chan)
1703{ 1671{
1704 int bb_spur = AR_NO_SPUR; 1672 int bb_spur = AR_NO_SPUR;
1705 int freq; 1673 int freq;
@@ -1733,9 +1701,9 @@ static void ath9k_hw_9280_spur_mitigate(struct ath_hal *ah, struct ath9k_channel
1733 ath9k_hw_get_channel_centers(ah, chan, &centers); 1701 ath9k_hw_get_channel_centers(ah, chan, &centers);
1734 freq = centers.synth_center; 1702 freq = centers.synth_center;
1735 1703
1736 ah->ah_config.spurmode = SPUR_ENABLE_EEPROM; 1704 ah->config.spurmode = SPUR_ENABLE_EEPROM;
1737 for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) { 1705 for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
1738 cur_bb_spur = ath9k_hw_eeprom_get_spur_chan(ah, i, is2GHz); 1706 cur_bb_spur = ah->eep_ops->get_spur_channel(ah, i, is2GHz);
1739 1707
1740 if (is2GHz) 1708 if (is2GHz)
1741 cur_bb_spur = (cur_bb_spur / 10) + AR_BASE_FREQ_2GHZ; 1709 cur_bb_spur = (cur_bb_spur / 10) + AR_BASE_FREQ_2GHZ;
@@ -1949,7 +1917,7 @@ static void ath9k_hw_9280_spur_mitigate(struct ath_hal *ah, struct ath9k_channel
1949 REG_WRITE(ah, AR_PHY_MASK2_P_61_45, tmp_mask); 1917 REG_WRITE(ah, AR_PHY_MASK2_P_61_45, tmp_mask);
1950} 1918}
1951 1919
1952static void ath9k_hw_spur_mitigate(struct ath_hal *ah, struct ath9k_channel *chan) 1920static void ath9k_hw_spur_mitigate(struct ath_hw *ah, struct ath9k_channel *chan)
1953{ 1921{
1954 int bb_spur = AR_NO_SPUR; 1922 int bb_spur = AR_NO_SPUR;
1955 int bin, cur_bin; 1923 int bin, cur_bin;
@@ -1978,7 +1946,7 @@ static void ath9k_hw_spur_mitigate(struct ath_hal *ah, struct ath9k_channel *cha
1978 memset(&mask_p, 0, sizeof(int8_t) * 123); 1946 memset(&mask_p, 0, sizeof(int8_t) * 123);
1979 1947
1980 for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) { 1948 for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
1981 cur_bb_spur = ath9k_hw_eeprom_get_spur_chan(ah, i, is2GHz); 1949 cur_bb_spur = ah->eep_ops->get_spur_channel(ah, i, is2GHz);
1982 if (AR_NO_SPUR == cur_bb_spur) 1950 if (AR_NO_SPUR == cur_bb_spur)
1983 break; 1951 break;
1984 cur_bb_spur = cur_bb_spur - (chan->channel * 10); 1952 cur_bb_spur = cur_bb_spur - (chan->channel * 10);
@@ -2150,27 +2118,26 @@ static void ath9k_hw_spur_mitigate(struct ath_hal *ah, struct ath9k_channel *cha
2150 REG_WRITE(ah, AR_PHY_MASK2_P_61_45, tmp_mask); 2118 REG_WRITE(ah, AR_PHY_MASK2_P_61_45, tmp_mask);
2151} 2119}
2152 2120
2153int ath9k_hw_reset(struct ath_hal *ah, struct ath9k_channel *chan, 2121int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
2154 bool bChannelChange) 2122 bool bChannelChange)
2155{ 2123{
2156 u32 saveLedState; 2124 u32 saveLedState;
2157 struct ath_softc *sc = ah->ah_sc; 2125 struct ath_softc *sc = ah->ah_sc;
2158 struct ath_hal_5416 *ahp = AH5416(ah); 2126 struct ath9k_channel *curchan = ah->curchan;
2159 struct ath9k_channel *curchan = ah->ah_curchan;
2160 u32 saveDefAntenna; 2127 u32 saveDefAntenna;
2161 u32 macStaId1; 2128 u32 macStaId1;
2162 int i, rx_chainmask, r; 2129 int i, rx_chainmask, r;
2163 2130
2164 ahp->ah_extprotspacing = sc->sc_ht_extprotspacing; 2131 ah->extprotspacing = sc->ht_extprotspacing;
2165 ahp->ah_txchainmask = sc->sc_tx_chainmask; 2132 ah->txchainmask = sc->tx_chainmask;
2166 ahp->ah_rxchainmask = sc->sc_rx_chainmask; 2133 ah->rxchainmask = sc->rx_chainmask;
2167 2134
2168 if (AR_SREV_9285(ah)) { 2135 if (AR_SREV_9285(ah)) {
2169 ahp->ah_txchainmask &= 0x1; 2136 ah->txchainmask &= 0x1;
2170 ahp->ah_rxchainmask &= 0x1; 2137 ah->rxchainmask &= 0x1;
2171 } else if (AR_SREV_9280(ah)) { 2138 } else if (AR_SREV_9280(ah)) {
2172 ahp->ah_txchainmask &= 0x3; 2139 ah->txchainmask &= 0x3;
2173 ahp->ah_rxchainmask &= 0x3; 2140 ah->rxchainmask &= 0x3;
2174 } 2141 }
2175 2142
2176 if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE)) 2143 if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE))
@@ -2180,16 +2147,16 @@ int ath9k_hw_reset(struct ath_hal *ah, struct ath9k_channel *chan,
2180 ath9k_hw_getnf(ah, curchan); 2147 ath9k_hw_getnf(ah, curchan);
2181 2148
2182 if (bChannelChange && 2149 if (bChannelChange &&
2183 (ahp->ah_chipFullSleep != true) && 2150 (ah->chip_fullsleep != true) &&
2184 (ah->ah_curchan != NULL) && 2151 (ah->curchan != NULL) &&
2185 (chan->channel != ah->ah_curchan->channel) && 2152 (chan->channel != ah->curchan->channel) &&
2186 ((chan->channelFlags & CHANNEL_ALL) == 2153 ((chan->channelFlags & CHANNEL_ALL) ==
2187 (ah->ah_curchan->channelFlags & CHANNEL_ALL)) && 2154 (ah->curchan->channelFlags & CHANNEL_ALL)) &&
2188 (!AR_SREV_9280(ah) || (!IS_CHAN_A_5MHZ_SPACED(chan) && 2155 (!AR_SREV_9280(ah) || (!IS_CHAN_A_5MHZ_SPACED(chan) &&
2189 !IS_CHAN_A_5MHZ_SPACED(ah->ah_curchan)))) { 2156 !IS_CHAN_A_5MHZ_SPACED(ah->curchan)))) {
2190 2157
2191 if (ath9k_hw_channel_change(ah, chan, sc->tx_chan_width)) { 2158 if (ath9k_hw_channel_change(ah, chan, sc->tx_chan_width)) {
2192 ath9k_hw_loadnf(ah, ah->ah_curchan); 2159 ath9k_hw_loadnf(ah, ah->curchan);
2193 ath9k_hw_start_nfcal(ah); 2160 ath9k_hw_start_nfcal(ah);
2194 return 0; 2161 return 0;
2195 } 2162 }
@@ -2244,7 +2211,7 @@ int ath9k_hw_reset(struct ath_hal *ah, struct ath9k_channel *chan,
2244 else 2211 else
2245 ath9k_hw_spur_mitigate(ah, chan); 2212 ath9k_hw_spur_mitigate(ah, chan);
2246 2213
2247 if (!ath9k_hw_eeprom_set_board_values(ah, chan)) { 2214 if (!ah->eep_ops->set_board_values(ah, chan)) {
2248 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, 2215 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
2249 "error setting board options\n"); 2216 "error setting board options\n");
2250 return -EIO; 2217 return -EIO;
@@ -2252,23 +2219,23 @@ int ath9k_hw_reset(struct ath_hal *ah, struct ath9k_channel *chan,
2252 2219
2253 ath9k_hw_decrease_chain_power(ah, chan); 2220 ath9k_hw_decrease_chain_power(ah, chan);
2254 2221
2255 REG_WRITE(ah, AR_STA_ID0, get_unaligned_le32(ahp->ah_macaddr)); 2222 REG_WRITE(ah, AR_STA_ID0, get_unaligned_le32(ah->macaddr));
2256 REG_WRITE(ah, AR_STA_ID1, get_unaligned_le16(ahp->ah_macaddr + 4) 2223 REG_WRITE(ah, AR_STA_ID1, get_unaligned_le16(ah->macaddr + 4)
2257 | macStaId1 2224 | macStaId1
2258 | AR_STA_ID1_RTS_USE_DEF 2225 | AR_STA_ID1_RTS_USE_DEF
2259 | (ah->ah_config. 2226 | (ah->config.
2260 ack_6mb ? AR_STA_ID1_ACKCTS_6MB : 0) 2227 ack_6mb ? AR_STA_ID1_ACKCTS_6MB : 0)
2261 | ahp->ah_staId1Defaults); 2228 | ah->sta_id1_defaults);
2262 ath9k_hw_set_operating_mode(ah, ah->ah_opmode); 2229 ath9k_hw_set_operating_mode(ah, ah->opmode);
2263 2230
2264 REG_WRITE(ah, AR_BSSMSKL, get_unaligned_le32(ahp->ah_bssidmask)); 2231 REG_WRITE(ah, AR_BSSMSKL, get_unaligned_le32(sc->bssidmask));
2265 REG_WRITE(ah, AR_BSSMSKU, get_unaligned_le16(ahp->ah_bssidmask + 4)); 2232 REG_WRITE(ah, AR_BSSMSKU, get_unaligned_le16(sc->bssidmask + 4));
2266 2233
2267 REG_WRITE(ah, AR_DEF_ANTENNA, saveDefAntenna); 2234 REG_WRITE(ah, AR_DEF_ANTENNA, saveDefAntenna);
2268 2235
2269 REG_WRITE(ah, AR_BSS_ID0, get_unaligned_le32(ahp->ah_bssid)); 2236 REG_WRITE(ah, AR_BSS_ID0, get_unaligned_le32(sc->curbssid));
2270 REG_WRITE(ah, AR_BSS_ID1, get_unaligned_le16(ahp->ah_bssid + 4) | 2237 REG_WRITE(ah, AR_BSS_ID1, get_unaligned_le16(sc->curbssid + 4) |
2271 ((ahp->ah_assocId & 0x3fff) << AR_BSS_ID1_AID_S)); 2238 ((sc->curaid & 0x3fff) << AR_BSS_ID1_AID_S));
2272 2239
2273 REG_WRITE(ah, AR_ISR, ~0); 2240 REG_WRITE(ah, AR_ISR, ~0);
2274 2241
@@ -2285,15 +2252,15 @@ int ath9k_hw_reset(struct ath_hal *ah, struct ath9k_channel *chan,
2285 for (i = 0; i < AR_NUM_DCU; i++) 2252 for (i = 0; i < AR_NUM_DCU; i++)
2286 REG_WRITE(ah, AR_DQCUMASK(i), 1 << i); 2253 REG_WRITE(ah, AR_DQCUMASK(i), 1 << i);
2287 2254
2288 ahp->ah_intrTxqs = 0; 2255 ah->intr_txqs = 0;
2289 for (i = 0; i < ah->ah_caps.total_queues; i++) 2256 for (i = 0; i < ah->caps.total_queues; i++)
2290 ath9k_hw_resettxqueue(ah, i); 2257 ath9k_hw_resettxqueue(ah, i);
2291 2258
2292 ath9k_hw_init_interrupt_masks(ah, ah->ah_opmode); 2259 ath9k_hw_init_interrupt_masks(ah, ah->opmode);
2293 ath9k_hw_init_qos(ah); 2260 ath9k_hw_init_qos(ah);
2294 2261
2295#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE) 2262#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
2296 if (ah->ah_caps.hw_caps & ATH9K_HW_CAP_RFSILENT) 2263 if (ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
2297 ath9k_enable_rfkill(ah); 2264 ath9k_enable_rfkill(ah);
2298#endif 2265#endif
2299 ath9k_hw_init_user_settings(ah); 2266 ath9k_hw_init_user_settings(ah);
@@ -2305,7 +2272,7 @@ int ath9k_hw_reset(struct ath_hal *ah, struct ath9k_channel *chan,
2305 2272
2306 REG_WRITE(ah, AR_OBS, 8); 2273 REG_WRITE(ah, AR_OBS, 8);
2307 2274
2308 if (ahp->ah_intrMitigation) { 2275 if (ah->intr_mitigation) {
2309 2276
2310 REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_LAST, 500); 2277 REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_LAST, 500);
2311 REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_FIRST, 2000); 2278 REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_FIRST, 2000);
@@ -2316,7 +2283,7 @@ int ath9k_hw_reset(struct ath_hal *ah, struct ath9k_channel *chan,
2316 if (!ath9k_hw_init_cal(ah, chan)) 2283 if (!ath9k_hw_init_cal(ah, chan))
2317 return -EIO;; 2284 return -EIO;;
2318 2285
2319 rx_chainmask = ahp->ah_rxchainmask; 2286 rx_chainmask = ah->rxchainmask;
2320 if ((rx_chainmask == 0x5) || (rx_chainmask == 0x3)) { 2287 if ((rx_chainmask == 0x5) || (rx_chainmask == 0x3)) {
2321 REG_WRITE(ah, AR_PHY_RX_CHAINMASK, rx_chainmask); 2288 REG_WRITE(ah, AR_PHY_RX_CHAINMASK, rx_chainmask);
2322 REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, rx_chainmask); 2289 REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, rx_chainmask);
@@ -2350,11 +2317,11 @@ int ath9k_hw_reset(struct ath_hal *ah, struct ath9k_channel *chan,
2350/* Key Cache Management */ 2317/* Key Cache Management */
2351/************************/ 2318/************************/
2352 2319
2353bool ath9k_hw_keyreset(struct ath_hal *ah, u16 entry) 2320bool ath9k_hw_keyreset(struct ath_hw *ah, u16 entry)
2354{ 2321{
2355 u32 keyType; 2322 u32 keyType;
2356 2323
2357 if (entry >= ah->ah_caps.keycache_size) { 2324 if (entry >= ah->caps.keycache_size) {
2358 DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE, 2325 DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE,
2359 "entry %u out of range\n", entry); 2326 "entry %u out of range\n", entry);
2360 return false; 2327 return false;
@@ -2381,17 +2348,17 @@ bool ath9k_hw_keyreset(struct ath_hal *ah, u16 entry)
2381 2348
2382 } 2349 }
2383 2350
2384 if (ah->ah_curchan == NULL) 2351 if (ah->curchan == NULL)
2385 return true; 2352 return true;
2386 2353
2387 return true; 2354 return true;
2388} 2355}
2389 2356
2390bool ath9k_hw_keysetmac(struct ath_hal *ah, u16 entry, const u8 *mac) 2357bool ath9k_hw_keysetmac(struct ath_hw *ah, u16 entry, const u8 *mac)
2391{ 2358{
2392 u32 macHi, macLo; 2359 u32 macHi, macLo;
2393 2360
2394 if (entry >= ah->ah_caps.keycache_size) { 2361 if (entry >= ah->caps.keycache_size) {
2395 DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE, 2362 DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE,
2396 "entry %u out of range\n", entry); 2363 "entry %u out of range\n", entry);
2397 return false; 2364 return false;
@@ -2415,17 +2382,16 @@ bool ath9k_hw_keysetmac(struct ath_hal *ah, u16 entry, const u8 *mac)
2415 return true; 2382 return true;
2416} 2383}
2417 2384
2418bool ath9k_hw_set_keycache_entry(struct ath_hal *ah, u16 entry, 2385bool ath9k_hw_set_keycache_entry(struct ath_hw *ah, u16 entry,
2419 const struct ath9k_keyval *k, 2386 const struct ath9k_keyval *k,
2420 const u8 *mac, int xorKey) 2387 const u8 *mac, int xorKey)
2421{ 2388{
2422 const struct ath9k_hw_capabilities *pCap = &ah->ah_caps; 2389 const struct ath9k_hw_capabilities *pCap = &ah->caps;
2423 u32 key0, key1, key2, key3, key4; 2390 u32 key0, key1, key2, key3, key4;
2424 u32 keyType; 2391 u32 keyType;
2425 u32 xorMask = xorKey ? 2392 u32 xorMask = xorKey ?
2426 (ATH9K_KEY_XOR << 24 | ATH9K_KEY_XOR << 16 | ATH9K_KEY_XOR << 8 2393 (ATH9K_KEY_XOR << 24 | ATH9K_KEY_XOR << 16 | ATH9K_KEY_XOR << 8
2427 | ATH9K_KEY_XOR) : 0; 2394 | ATH9K_KEY_XOR) : 0;
2428 struct ath_hal_5416 *ahp = AH5416(ah);
2429 2395
2430 if (entry >= pCap->keycache_size) { 2396 if (entry >= pCap->keycache_size) {
2431 DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE, 2397 DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE,
@@ -2441,7 +2407,7 @@ bool ath9k_hw_set_keycache_entry(struct ath_hal *ah, u16 entry,
2441 if (!(pCap->hw_caps & ATH9K_HW_CAP_CIPHER_AESCCM)) { 2407 if (!(pCap->hw_caps & ATH9K_HW_CAP_CIPHER_AESCCM)) {
2442 DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE, 2408 DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE,
2443 "AES-CCM not supported by mac rev 0x%x\n", 2409 "AES-CCM not supported by mac rev 0x%x\n",
2444 ah->ah_macRev); 2410 ah->hw_version.macRev);
2445 return false; 2411 return false;
2446 } 2412 }
2447 keyType = AR_KEYTABLE_TYPE_CCM; 2413 keyType = AR_KEYTABLE_TYPE_CCM;
@@ -2496,7 +2462,7 @@ bool ath9k_hw_set_keycache_entry(struct ath_hal *ah, u16 entry,
2496 REG_WRITE(ah, AR_KEYTABLE_TYPE(entry), keyType); 2462 REG_WRITE(ah, AR_KEYTABLE_TYPE(entry), keyType);
2497 (void) ath9k_hw_keysetmac(ah, entry, mac); 2463 (void) ath9k_hw_keysetmac(ah, entry, mac);
2498 2464
2499 if (ahp->ah_miscMode & AR_PCU_MIC_NEW_LOC_ENA) { 2465 if (ah->misc_mode & AR_PCU_MIC_NEW_LOC_ENA) {
2500 u32 mic0, mic1, mic2, mic3, mic4; 2466 u32 mic0, mic1, mic2, mic3, mic4;
2501 2467
2502 mic0 = get_unaligned_le32(k->kv_mic + 0); 2468 mic0 = get_unaligned_le32(k->kv_mic + 0);
@@ -2540,15 +2506,15 @@ bool ath9k_hw_set_keycache_entry(struct ath_hal *ah, u16 entry,
2540 (void) ath9k_hw_keysetmac(ah, entry, mac); 2506 (void) ath9k_hw_keysetmac(ah, entry, mac);
2541 } 2507 }
2542 2508
2543 if (ah->ah_curchan == NULL) 2509 if (ah->curchan == NULL)
2544 return true; 2510 return true;
2545 2511
2546 return true; 2512 return true;
2547} 2513}
2548 2514
2549bool ath9k_hw_keyisvalid(struct ath_hal *ah, u16 entry) 2515bool ath9k_hw_keyisvalid(struct ath_hw *ah, u16 entry)
2550{ 2516{
2551 if (entry < ah->ah_caps.keycache_size) { 2517 if (entry < ah->caps.keycache_size) {
2552 u32 val = REG_READ(ah, AR_KEYTABLE_MAC1(entry)); 2518 u32 val = REG_READ(ah, AR_KEYTABLE_MAC1(entry));
2553 if (val & AR_KEYTABLE_VALID) 2519 if (val & AR_KEYTABLE_VALID)
2554 return true; 2520 return true;
@@ -2560,7 +2526,7 @@ bool ath9k_hw_keyisvalid(struct ath_hal *ah, u16 entry)
2560/* Power Management (Chipset) */ 2526/* Power Management (Chipset) */
2561/******************************/ 2527/******************************/
2562 2528
2563static void ath9k_set_power_sleep(struct ath_hal *ah, int setChip) 2529static void ath9k_set_power_sleep(struct ath_hw *ah, int setChip)
2564{ 2530{
2565 REG_SET_BIT(ah, AR_STA_ID1, AR_STA_ID1_PWR_SAV); 2531 REG_SET_BIT(ah, AR_STA_ID1, AR_STA_ID1_PWR_SAV);
2566 if (setChip) { 2532 if (setChip) {
@@ -2574,11 +2540,11 @@ static void ath9k_set_power_sleep(struct ath_hal *ah, int setChip)
2574 } 2540 }
2575} 2541}
2576 2542
2577static void ath9k_set_power_network_sleep(struct ath_hal *ah, int setChip) 2543static void ath9k_set_power_network_sleep(struct ath_hw *ah, int setChip)
2578{ 2544{
2579 REG_SET_BIT(ah, AR_STA_ID1, AR_STA_ID1_PWR_SAV); 2545 REG_SET_BIT(ah, AR_STA_ID1, AR_STA_ID1_PWR_SAV);
2580 if (setChip) { 2546 if (setChip) {
2581 struct ath9k_hw_capabilities *pCap = &ah->ah_caps; 2547 struct ath9k_hw_capabilities *pCap = &ah->caps;
2582 2548
2583 if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) { 2549 if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) {
2584 REG_WRITE(ah, AR_RTC_FORCE_WAKE, 2550 REG_WRITE(ah, AR_RTC_FORCE_WAKE,
@@ -2590,8 +2556,7 @@ static void ath9k_set_power_network_sleep(struct ath_hal *ah, int setChip)
2590 } 2556 }
2591} 2557}
2592 2558
2593static bool ath9k_hw_set_power_awake(struct ath_hal *ah, 2559static bool ath9k_hw_set_power_awake(struct ath_hw *ah, int setChip)
2594 int setChip)
2595{ 2560{
2596 u32 val; 2561 u32 val;
2597 int i; 2562 int i;
@@ -2632,20 +2597,18 @@ static bool ath9k_hw_set_power_awake(struct ath_hal *ah,
2632 return true; 2597 return true;
2633} 2598}
2634 2599
2635bool ath9k_hw_setpower(struct ath_hal *ah, 2600bool ath9k_hw_setpower(struct ath_hw *ah, enum ath9k_power_mode mode)
2636 enum ath9k_power_mode mode)
2637{ 2601{
2638 struct ath_hal_5416 *ahp = AH5416(ah); 2602 int status = true, setChip = true;
2639 static const char *modes[] = { 2603 static const char *modes[] = {
2640 "AWAKE", 2604 "AWAKE",
2641 "FULL-SLEEP", 2605 "FULL-SLEEP",
2642 "NETWORK SLEEP", 2606 "NETWORK SLEEP",
2643 "UNDEFINED" 2607 "UNDEFINED"
2644 }; 2608 };
2645 int status = true, setChip = true;
2646 2609
2647 DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT, "%s -> %s (%s)\n", 2610 DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT, "%s -> %s (%s)\n",
2648 modes[ah->ah_power_mode], modes[mode], 2611 modes[ah->power_mode], modes[mode],
2649 setChip ? "set chip " : ""); 2612 setChip ? "set chip " : "");
2650 2613
2651 switch (mode) { 2614 switch (mode) {
@@ -2654,7 +2617,7 @@ bool ath9k_hw_setpower(struct ath_hal *ah,
2654 break; 2617 break;
2655 case ATH9K_PM_FULL_SLEEP: 2618 case ATH9K_PM_FULL_SLEEP:
2656 ath9k_set_power_sleep(ah, setChip); 2619 ath9k_set_power_sleep(ah, setChip);
2657 ahp->ah_chipFullSleep = true; 2620 ah->chip_fullsleep = true;
2658 break; 2621 break;
2659 case ATH9K_PM_NETWORK_SLEEP: 2622 case ATH9K_PM_NETWORK_SLEEP:
2660 ath9k_set_power_network_sleep(ah, setChip); 2623 ath9k_set_power_network_sleep(ah, setChip);
@@ -2664,41 +2627,57 @@ bool ath9k_hw_setpower(struct ath_hal *ah,
2664 "Unknown power mode %u\n", mode); 2627 "Unknown power mode %u\n", mode);
2665 return false; 2628 return false;
2666 } 2629 }
2667 ah->ah_power_mode = mode; 2630 ah->power_mode = mode;
2668 2631
2669 return status; 2632 return status;
2670} 2633}
2671 2634
2672void ath9k_hw_configpcipowersave(struct ath_hal *ah, int restore) 2635/*
2636 * Helper for ASPM support.
2637 *
2638 * Disable PLL when in L0s as well as receiver clock when in L1.
2639 * This power saving option must be enabled through the SerDes.
2640 *
2641 * Programming the SerDes must go through the same 288 bit serial shift
2642 * register as the other analog registers. Hence the 9 writes.
2643 */
2644void ath9k_hw_configpcipowersave(struct ath_hw *ah, int restore)
2673{ 2645{
2674 struct ath_hal_5416 *ahp = AH5416(ah);
2675 u8 i; 2646 u8 i;
2676 2647
2677 if (ah->ah_isPciExpress != true) 2648 if (ah->is_pciexpress != true)
2678 return; 2649 return;
2679 2650
2680 if (ah->ah_config.pcie_powersave_enable == 2) 2651 /* Do not touch SerDes registers */
2652 if (ah->config.pcie_powersave_enable == 2)
2681 return; 2653 return;
2682 2654
2655 /* Nothing to do on restore for 11N */
2683 if (restore) 2656 if (restore)
2684 return; 2657 return;
2685 2658
2686 if (AR_SREV_9280_20_OR_LATER(ah)) { 2659 if (AR_SREV_9280_20_OR_LATER(ah)) {
2687 for (i = 0; i < ahp->ah_iniPcieSerdes.ia_rows; i++) { 2660 /*
2688 REG_WRITE(ah, INI_RA(&ahp->ah_iniPcieSerdes, i, 0), 2661 * AR9280 2.0 or later chips use SerDes values from the
2689 INI_RA(&ahp->ah_iniPcieSerdes, i, 1)); 2662 * initvals.h initialized depending on chipset during
2663 * ath9k_hw_do_attach()
2664 */
2665 for (i = 0; i < ah->iniPcieSerdes.ia_rows; i++) {
2666 REG_WRITE(ah, INI_RA(&ah->iniPcieSerdes, i, 0),
2667 INI_RA(&ah->iniPcieSerdes, i, 1));
2690 } 2668 }
2691 udelay(1000);
2692 } else if (AR_SREV_9280(ah) && 2669 } else if (AR_SREV_9280(ah) &&
2693 (ah->ah_macRev == AR_SREV_REVISION_9280_10)) { 2670 (ah->hw_version.macRev == AR_SREV_REVISION_9280_10)) {
2694 REG_WRITE(ah, AR_PCIE_SERDES, 0x9248fd00); 2671 REG_WRITE(ah, AR_PCIE_SERDES, 0x9248fd00);
2695 REG_WRITE(ah, AR_PCIE_SERDES, 0x24924924); 2672 REG_WRITE(ah, AR_PCIE_SERDES, 0x24924924);
2696 2673
2674 /* RX shut off when elecidle is asserted */
2697 REG_WRITE(ah, AR_PCIE_SERDES, 0xa8000019); 2675 REG_WRITE(ah, AR_PCIE_SERDES, 0xa8000019);
2698 REG_WRITE(ah, AR_PCIE_SERDES, 0x13160820); 2676 REG_WRITE(ah, AR_PCIE_SERDES, 0x13160820);
2699 REG_WRITE(ah, AR_PCIE_SERDES, 0xe5980560); 2677 REG_WRITE(ah, AR_PCIE_SERDES, 0xe5980560);
2700 2678
2701 if (ah->ah_config.pcie_clock_req) 2679 /* Shut off CLKREQ active in L1 */
2680 if (ah->config.pcie_clock_req)
2702 REG_WRITE(ah, AR_PCIE_SERDES, 0x401deffc); 2681 REG_WRITE(ah, AR_PCIE_SERDES, 0x401deffc);
2703 else 2682 else
2704 REG_WRITE(ah, AR_PCIE_SERDES, 0x401deffd); 2683 REG_WRITE(ah, AR_PCIE_SERDES, 0x401deffd);
@@ -2707,42 +2686,59 @@ void ath9k_hw_configpcipowersave(struct ath_hal *ah, int restore)
2707 REG_WRITE(ah, AR_PCIE_SERDES, 0xbe105554); 2686 REG_WRITE(ah, AR_PCIE_SERDES, 0xbe105554);
2708 REG_WRITE(ah, AR_PCIE_SERDES, 0x00043007); 2687 REG_WRITE(ah, AR_PCIE_SERDES, 0x00043007);
2709 2688
2689 /* Load the new settings */
2710 REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000); 2690 REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000);
2711 2691
2712 udelay(1000);
2713 } else { 2692 } else {
2714 REG_WRITE(ah, AR_PCIE_SERDES, 0x9248fc00); 2693 REG_WRITE(ah, AR_PCIE_SERDES, 0x9248fc00);
2715 REG_WRITE(ah, AR_PCIE_SERDES, 0x24924924); 2694 REG_WRITE(ah, AR_PCIE_SERDES, 0x24924924);
2695
2696 /* RX shut off when elecidle is asserted */
2716 REG_WRITE(ah, AR_PCIE_SERDES, 0x28000039); 2697 REG_WRITE(ah, AR_PCIE_SERDES, 0x28000039);
2717 REG_WRITE(ah, AR_PCIE_SERDES, 0x53160824); 2698 REG_WRITE(ah, AR_PCIE_SERDES, 0x53160824);
2718 REG_WRITE(ah, AR_PCIE_SERDES, 0xe5980579); 2699 REG_WRITE(ah, AR_PCIE_SERDES, 0xe5980579);
2700
2701 /*
2702 * Ignore ah->ah_config.pcie_clock_req setting for
2703 * pre-AR9280 11n
2704 */
2719 REG_WRITE(ah, AR_PCIE_SERDES, 0x001defff); 2705 REG_WRITE(ah, AR_PCIE_SERDES, 0x001defff);
2706
2720 REG_WRITE(ah, AR_PCIE_SERDES, 0x1aaabe40); 2707 REG_WRITE(ah, AR_PCIE_SERDES, 0x1aaabe40);
2721 REG_WRITE(ah, AR_PCIE_SERDES, 0xbe105554); 2708 REG_WRITE(ah, AR_PCIE_SERDES, 0xbe105554);
2722 REG_WRITE(ah, AR_PCIE_SERDES, 0x000e3007); 2709 REG_WRITE(ah, AR_PCIE_SERDES, 0x000e3007);
2710
2711 /* Load the new settings */
2723 REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000); 2712 REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000);
2724 } 2713 }
2725 2714
2715 udelay(1000);
2716
2717 /* set bit 19 to allow forcing of pcie core into L1 state */
2726 REG_SET_BIT(ah, AR_PCIE_PM_CTRL, AR_PCIE_PM_CTRL_ENA); 2718 REG_SET_BIT(ah, AR_PCIE_PM_CTRL, AR_PCIE_PM_CTRL_ENA);
2727 2719
2728 if (ah->ah_config.pcie_waen) { 2720 /* Several PCIe massages to ensure proper behaviour */
2729 REG_WRITE(ah, AR_WA, ah->ah_config.pcie_waen); 2721 if (ah->config.pcie_waen) {
2722 REG_WRITE(ah, AR_WA, ah->config.pcie_waen);
2730 } else { 2723 } else {
2731 if (AR_SREV_9285(ah)) 2724 if (AR_SREV_9285(ah))
2732 REG_WRITE(ah, AR_WA, AR9285_WA_DEFAULT); 2725 REG_WRITE(ah, AR_WA, AR9285_WA_DEFAULT);
2726 /*
2727 * On AR9280 chips bit 22 of 0x4004 needs to be set to
2728 * otherwise card may disappear.
2729 */
2733 else if (AR_SREV_9280(ah)) 2730 else if (AR_SREV_9280(ah))
2734 REG_WRITE(ah, AR_WA, AR9280_WA_DEFAULT); 2731 REG_WRITE(ah, AR_WA, AR9280_WA_DEFAULT);
2735 else 2732 else
2736 REG_WRITE(ah, AR_WA, AR_WA_DEFAULT); 2733 REG_WRITE(ah, AR_WA, AR_WA_DEFAULT);
2737 } 2734 }
2738
2739} 2735}
2740 2736
2741/**********************/ 2737/**********************/
2742/* Interrupt Handling */ 2738/* Interrupt Handling */
2743/**********************/ 2739/**********************/
2744 2740
2745bool ath9k_hw_intrpend(struct ath_hal *ah) 2741bool ath9k_hw_intrpend(struct ath_hw *ah)
2746{ 2742{
2747 u32 host_isr; 2743 u32 host_isr;
2748 2744
@@ -2761,14 +2757,13 @@ bool ath9k_hw_intrpend(struct ath_hal *ah)
2761 return false; 2757 return false;
2762} 2758}
2763 2759
2764bool ath9k_hw_getisr(struct ath_hal *ah, enum ath9k_int *masked) 2760bool ath9k_hw_getisr(struct ath_hw *ah, enum ath9k_int *masked)
2765{ 2761{
2766 u32 isr = 0; 2762 u32 isr = 0;
2767 u32 mask2 = 0; 2763 u32 mask2 = 0;
2768 struct ath9k_hw_capabilities *pCap = &ah->ah_caps; 2764 struct ath9k_hw_capabilities *pCap = &ah->caps;
2769 u32 sync_cause = 0; 2765 u32 sync_cause = 0;
2770 bool fatal_int = false; 2766 bool fatal_int = false;
2771 struct ath_hal_5416 *ahp = AH5416(ah);
2772 2767
2773 if (!AR_SREV_9100(ah)) { 2768 if (!AR_SREV_9100(ah)) {
2774 if (REG_READ(ah, AR_INTR_ASYNC_CAUSE) & AR_INTR_MAC_IRQ) { 2769 if (REG_READ(ah, AR_INTR_ASYNC_CAUSE) & AR_INTR_MAC_IRQ) {
@@ -2816,7 +2811,7 @@ bool ath9k_hw_getisr(struct ath_hal *ah, enum ath9k_int *masked)
2816 2811
2817 *masked = isr & ATH9K_INT_COMMON; 2812 *masked = isr & ATH9K_INT_COMMON;
2818 2813
2819 if (ahp->ah_intrMitigation) { 2814 if (ah->intr_mitigation) {
2820 if (isr & (AR_ISR_RXMINTR | AR_ISR_RXINTM)) 2815 if (isr & (AR_ISR_RXMINTR | AR_ISR_RXINTM))
2821 *masked |= ATH9K_INT_RX; 2816 *masked |= ATH9K_INT_RX;
2822 } 2817 }
@@ -2831,12 +2826,12 @@ bool ath9k_hw_getisr(struct ath_hal *ah, enum ath9k_int *masked)
2831 *masked |= ATH9K_INT_TX; 2826 *masked |= ATH9K_INT_TX;
2832 2827
2833 s0_s = REG_READ(ah, AR_ISR_S0_S); 2828 s0_s = REG_READ(ah, AR_ISR_S0_S);
2834 ahp->ah_intrTxqs |= MS(s0_s, AR_ISR_S0_QCU_TXOK); 2829 ah->intr_txqs |= MS(s0_s, AR_ISR_S0_QCU_TXOK);
2835 ahp->ah_intrTxqs |= MS(s0_s, AR_ISR_S0_QCU_TXDESC); 2830 ah->intr_txqs |= MS(s0_s, AR_ISR_S0_QCU_TXDESC);
2836 2831
2837 s1_s = REG_READ(ah, AR_ISR_S1_S); 2832 s1_s = REG_READ(ah, AR_ISR_S1_S);
2838 ahp->ah_intrTxqs |= MS(s1_s, AR_ISR_S1_QCU_TXERR); 2833 ah->intr_txqs |= MS(s1_s, AR_ISR_S1_QCU_TXERR);
2839 ahp->ah_intrTxqs |= MS(s1_s, AR_ISR_S1_QCU_TXEOL); 2834 ah->intr_txqs |= MS(s1_s, AR_ISR_S1_QCU_TXEOL);
2840 } 2835 }
2841 2836
2842 if (isr & AR_ISR_RXORN) { 2837 if (isr & AR_ISR_RXORN) {
@@ -2893,17 +2888,16 @@ bool ath9k_hw_getisr(struct ath_hal *ah, enum ath9k_int *masked)
2893 return true; 2888 return true;
2894} 2889}
2895 2890
2896enum ath9k_int ath9k_hw_intrget(struct ath_hal *ah) 2891enum ath9k_int ath9k_hw_intrget(struct ath_hw *ah)
2897{ 2892{
2898 return AH5416(ah)->ah_maskReg; 2893 return ah->mask_reg;
2899} 2894}
2900 2895
2901enum ath9k_int ath9k_hw_set_interrupts(struct ath_hal *ah, enum ath9k_int ints) 2896enum ath9k_int ath9k_hw_set_interrupts(struct ath_hw *ah, enum ath9k_int ints)
2902{ 2897{
2903 struct ath_hal_5416 *ahp = AH5416(ah); 2898 u32 omask = ah->mask_reg;
2904 u32 omask = ahp->ah_maskReg;
2905 u32 mask, mask2; 2899 u32 mask, mask2;
2906 struct ath9k_hw_capabilities *pCap = &ah->ah_caps; 2900 struct ath9k_hw_capabilities *pCap = &ah->caps;
2907 2901
2908 DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT, "0x%x => 0x%x\n", omask, ints); 2902 DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT, "0x%x => 0x%x\n", omask, ints);
2909 2903
@@ -2924,18 +2918,18 @@ enum ath9k_int ath9k_hw_set_interrupts(struct ath_hal *ah, enum ath9k_int ints)
2924 mask2 = 0; 2918 mask2 = 0;
2925 2919
2926 if (ints & ATH9K_INT_TX) { 2920 if (ints & ATH9K_INT_TX) {
2927 if (ahp->ah_txOkInterruptMask) 2921 if (ah->txok_interrupt_mask)
2928 mask |= AR_IMR_TXOK; 2922 mask |= AR_IMR_TXOK;
2929 if (ahp->ah_txDescInterruptMask) 2923 if (ah->txdesc_interrupt_mask)
2930 mask |= AR_IMR_TXDESC; 2924 mask |= AR_IMR_TXDESC;
2931 if (ahp->ah_txErrInterruptMask) 2925 if (ah->txerr_interrupt_mask)
2932 mask |= AR_IMR_TXERR; 2926 mask |= AR_IMR_TXERR;
2933 if (ahp->ah_txEolInterruptMask) 2927 if (ah->txeol_interrupt_mask)
2934 mask |= AR_IMR_TXEOL; 2928 mask |= AR_IMR_TXEOL;
2935 } 2929 }
2936 if (ints & ATH9K_INT_RX) { 2930 if (ints & ATH9K_INT_RX) {
2937 mask |= AR_IMR_RXERR; 2931 mask |= AR_IMR_RXERR;
2938 if (ahp->ah_intrMitigation) 2932 if (ah->intr_mitigation)
2939 mask |= AR_IMR_RXMINTR | AR_IMR_RXINTM; 2933 mask |= AR_IMR_RXMINTR | AR_IMR_RXINTM;
2940 else 2934 else
2941 mask |= AR_IMR_RXOK | AR_IMR_RXDESC; 2935 mask |= AR_IMR_RXOK | AR_IMR_RXDESC;
@@ -2973,7 +2967,7 @@ enum ath9k_int ath9k_hw_set_interrupts(struct ath_hal *ah, enum ath9k_int ints)
2973 AR_IMR_S2_TSFOOR | 2967 AR_IMR_S2_TSFOOR |
2974 AR_IMR_S2_GTT | AR_IMR_S2_CST); 2968 AR_IMR_S2_GTT | AR_IMR_S2_CST);
2975 REG_WRITE(ah, AR_IMR_S2, mask | mask2); 2969 REG_WRITE(ah, AR_IMR_S2, mask | mask2);
2976 ahp->ah_maskReg = ints; 2970 ah->mask_reg = ints;
2977 2971
2978 if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) { 2972 if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) {
2979 if (ints & ATH9K_INT_TIM_TIMER) 2973 if (ints & ATH9K_INT_TIM_TIMER)
@@ -3007,14 +3001,13 @@ enum ath9k_int ath9k_hw_set_interrupts(struct ath_hal *ah, enum ath9k_int ints)
3007/* Beacon Handling */ 3001/* Beacon Handling */
3008/*******************/ 3002/*******************/
3009 3003
3010void ath9k_hw_beaconinit(struct ath_hal *ah, u32 next_beacon, u32 beacon_period) 3004void ath9k_hw_beaconinit(struct ath_hw *ah, u32 next_beacon, u32 beacon_period)
3011{ 3005{
3012 struct ath_hal_5416 *ahp = AH5416(ah);
3013 int flags = 0; 3006 int flags = 0;
3014 3007
3015 ahp->ah_beaconInterval = beacon_period; 3008 ah->beacon_interval = beacon_period;
3016 3009
3017 switch (ah->ah_opmode) { 3010 switch (ah->opmode) {
3018 case NL80211_IFTYPE_STATION: 3011 case NL80211_IFTYPE_STATION:
3019 case NL80211_IFTYPE_MONITOR: 3012 case NL80211_IFTYPE_MONITOR:
3020 REG_WRITE(ah, AR_NEXT_TBTT_TIMER, TU_TO_USEC(next_beacon)); 3013 REG_WRITE(ah, AR_NEXT_TBTT_TIMER, TU_TO_USEC(next_beacon));
@@ -3027,18 +3020,18 @@ void ath9k_hw_beaconinit(struct ath_hal *ah, u32 next_beacon, u32 beacon_period)
3027 AR_TXCFG_ADHOC_BEACON_ATIM_TX_POLICY); 3020 AR_TXCFG_ADHOC_BEACON_ATIM_TX_POLICY);
3028 REG_WRITE(ah, AR_NEXT_NDP_TIMER, 3021 REG_WRITE(ah, AR_NEXT_NDP_TIMER,
3029 TU_TO_USEC(next_beacon + 3022 TU_TO_USEC(next_beacon +
3030 (ahp->ah_atimWindow ? ahp-> 3023 (ah->atim_window ? ah->
3031 ah_atimWindow : 1))); 3024 atim_window : 1)));
3032 flags |= AR_NDP_TIMER_EN; 3025 flags |= AR_NDP_TIMER_EN;
3033 case NL80211_IFTYPE_AP: 3026 case NL80211_IFTYPE_AP:
3034 REG_WRITE(ah, AR_NEXT_TBTT_TIMER, TU_TO_USEC(next_beacon)); 3027 REG_WRITE(ah, AR_NEXT_TBTT_TIMER, TU_TO_USEC(next_beacon));
3035 REG_WRITE(ah, AR_NEXT_DMA_BEACON_ALERT, 3028 REG_WRITE(ah, AR_NEXT_DMA_BEACON_ALERT,
3036 TU_TO_USEC(next_beacon - 3029 TU_TO_USEC(next_beacon -
3037 ah->ah_config. 3030 ah->config.
3038 dma_beacon_response_time)); 3031 dma_beacon_response_time));
3039 REG_WRITE(ah, AR_NEXT_SWBA, 3032 REG_WRITE(ah, AR_NEXT_SWBA,
3040 TU_TO_USEC(next_beacon - 3033 TU_TO_USEC(next_beacon -
3041 ah->ah_config. 3034 ah->config.
3042 sw_beacon_response_time)); 3035 sw_beacon_response_time));
3043 flags |= 3036 flags |=
3044 AR_TBTT_TIMER_EN | AR_DBA_TIMER_EN | AR_SWBA_TIMER_EN; 3037 AR_TBTT_TIMER_EN | AR_DBA_TIMER_EN | AR_SWBA_TIMER_EN;
@@ -3046,7 +3039,7 @@ void ath9k_hw_beaconinit(struct ath_hal *ah, u32 next_beacon, u32 beacon_period)
3046 default: 3039 default:
3047 DPRINTF(ah->ah_sc, ATH_DBG_BEACON, 3040 DPRINTF(ah->ah_sc, ATH_DBG_BEACON,
3048 "%s: unsupported opmode: %d\n", 3041 "%s: unsupported opmode: %d\n",
3049 __func__, ah->ah_opmode); 3042 __func__, ah->opmode);
3050 return; 3043 return;
3051 break; 3044 break;
3052 } 3045 }
@@ -3065,11 +3058,11 @@ void ath9k_hw_beaconinit(struct ath_hal *ah, u32 next_beacon, u32 beacon_period)
3065 REG_SET_BIT(ah, AR_TIMER_MODE, flags); 3058 REG_SET_BIT(ah, AR_TIMER_MODE, flags);
3066} 3059}
3067 3060
3068void ath9k_hw_set_sta_beacon_timers(struct ath_hal *ah, 3061void ath9k_hw_set_sta_beacon_timers(struct ath_hw *ah,
3069 const struct ath9k_beacon_state *bs) 3062 const struct ath9k_beacon_state *bs)
3070{ 3063{
3071 u32 nextTbtt, beaconintval, dtimperiod, beacontimeout; 3064 u32 nextTbtt, beaconintval, dtimperiod, beacontimeout;
3072 struct ath9k_hw_capabilities *pCap = &ah->ah_caps; 3065 struct ath9k_hw_capabilities *pCap = &ah->caps;
3073 3066
3074 REG_WRITE(ah, AR_NEXT_TBTT_TIMER, TU_TO_USEC(bs->bs_nexttbtt)); 3067 REG_WRITE(ah, AR_NEXT_TBTT_TIMER, TU_TO_USEC(bs->bs_nexttbtt));
3075 3068
@@ -3129,37 +3122,37 @@ void ath9k_hw_set_sta_beacon_timers(struct ath_hal *ah,
3129/* HW Capabilities */ 3122/* HW Capabilities */
3130/*******************/ 3123/*******************/
3131 3124
3132bool ath9k_hw_fill_cap_info(struct ath_hal *ah) 3125bool ath9k_hw_fill_cap_info(struct ath_hw *ah)
3133{ 3126{
3134 struct ath_hal_5416 *ahp = AH5416(ah); 3127 struct ath9k_hw_capabilities *pCap = &ah->caps;
3135 struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
3136 u16 capField = 0, eeval; 3128 u16 capField = 0, eeval;
3137 3129
3138 eeval = ath9k_hw_get_eeprom(ah, EEP_REG_0); 3130 eeval = ah->eep_ops->get_eeprom(ah, EEP_REG_0);
3139 3131
3140 ah->ah_currentRD = eeval; 3132 ah->regulatory.current_rd = eeval;
3141 3133
3142 eeval = ath9k_hw_get_eeprom(ah, EEP_REG_1); 3134 eeval = ah->eep_ops->get_eeprom(ah, EEP_REG_1);
3143 ah->ah_currentRDExt = eeval; 3135 ah->regulatory.current_rd_ext = eeval;
3144 3136
3145 capField = ath9k_hw_get_eeprom(ah, EEP_OP_CAP); 3137 capField = ah->eep_ops->get_eeprom(ah, EEP_OP_CAP);
3146 3138
3147 if (ah->ah_opmode != NL80211_IFTYPE_AP && 3139 if (ah->opmode != NL80211_IFTYPE_AP &&
3148 ah->ah_subvendorid == AR_SUBVENDOR_ID_NEW_A) { 3140 ah->hw_version.subvendorid == AR_SUBVENDOR_ID_NEW_A) {
3149 if (ah->ah_currentRD == 0x64 || ah->ah_currentRD == 0x65) 3141 if (ah->regulatory.current_rd == 0x64 ||
3150 ah->ah_currentRD += 5; 3142 ah->regulatory.current_rd == 0x65)
3151 else if (ah->ah_currentRD == 0x41) 3143 ah->regulatory.current_rd += 5;
3152 ah->ah_currentRD = 0x43; 3144 else if (ah->regulatory.current_rd == 0x41)
3145 ah->regulatory.current_rd = 0x43;
3153 DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, 3146 DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
3154 "regdomain mapped to 0x%x\n", ah->ah_currentRD); 3147 "regdomain mapped to 0x%x\n", ah->regulatory.current_rd);
3155 } 3148 }
3156 3149
3157 eeval = ath9k_hw_get_eeprom(ah, EEP_OP_MODE); 3150 eeval = ah->eep_ops->get_eeprom(ah, EEP_OP_MODE);
3158 bitmap_zero(pCap->wireless_modes, ATH9K_MODE_MAX); 3151 bitmap_zero(pCap->wireless_modes, ATH9K_MODE_MAX);
3159 3152
3160 if (eeval & AR5416_OPFLAGS_11A) { 3153 if (eeval & AR5416_OPFLAGS_11A) {
3161 set_bit(ATH9K_MODE_11A, pCap->wireless_modes); 3154 set_bit(ATH9K_MODE_11A, pCap->wireless_modes);
3162 if (ah->ah_config.ht_enable) { 3155 if (ah->config.ht_enable) {
3163 if (!(eeval & AR5416_OPFLAGS_N_5G_HT20)) 3156 if (!(eeval & AR5416_OPFLAGS_N_5G_HT20))
3164 set_bit(ATH9K_MODE_11NA_HT20, 3157 set_bit(ATH9K_MODE_11NA_HT20,
3165 pCap->wireless_modes); 3158 pCap->wireless_modes);
@@ -3175,7 +3168,7 @@ bool ath9k_hw_fill_cap_info(struct ath_hal *ah)
3175 if (eeval & AR5416_OPFLAGS_11G) { 3168 if (eeval & AR5416_OPFLAGS_11G) {
3176 set_bit(ATH9K_MODE_11B, pCap->wireless_modes); 3169 set_bit(ATH9K_MODE_11B, pCap->wireless_modes);
3177 set_bit(ATH9K_MODE_11G, pCap->wireless_modes); 3170 set_bit(ATH9K_MODE_11G, pCap->wireless_modes);
3178 if (ah->ah_config.ht_enable) { 3171 if (ah->config.ht_enable) {
3179 if (!(eeval & AR5416_OPFLAGS_N_2G_HT20)) 3172 if (!(eeval & AR5416_OPFLAGS_N_2G_HT20))
3180 set_bit(ATH9K_MODE_11NG_HT20, 3173 set_bit(ATH9K_MODE_11NG_HT20,
3181 pCap->wireless_modes); 3174 pCap->wireless_modes);
@@ -3188,18 +3181,18 @@ bool ath9k_hw_fill_cap_info(struct ath_hal *ah)
3188 } 3181 }
3189 } 3182 }
3190 3183
3191 pCap->tx_chainmask = ath9k_hw_get_eeprom(ah, EEP_TX_MASK); 3184 pCap->tx_chainmask = ah->eep_ops->get_eeprom(ah, EEP_TX_MASK);
3192 if ((ah->ah_isPciExpress) 3185 if ((ah->is_pciexpress)
3193 || (eeval & AR5416_OPFLAGS_11A)) { 3186 || (eeval & AR5416_OPFLAGS_11A)) {
3194 pCap->rx_chainmask = 3187 pCap->rx_chainmask =
3195 ath9k_hw_get_eeprom(ah, EEP_RX_MASK); 3188 ah->eep_ops->get_eeprom(ah, EEP_RX_MASK);
3196 } else { 3189 } else {
3197 pCap->rx_chainmask = 3190 pCap->rx_chainmask =
3198 (ath9k_hw_gpio_get(ah, 0)) ? 0x5 : 0x7; 3191 (ath9k_hw_gpio_get(ah, 0)) ? 0x5 : 0x7;
3199 } 3192 }
3200 3193
3201 if (!(AR_SREV_9280(ah) && (ah->ah_macRev == 0))) 3194 if (!(AR_SREV_9280(ah) && (ah->hw_version.macRev == 0)))
3202 ahp->ah_miscMode |= AR_PCU_MIC_NEW_LOC_ENA; 3195 ah->misc_mode |= AR_PCU_MIC_NEW_LOC_ENA;
3203 3196
3204 pCap->low_2ghz_chan = 2312; 3197 pCap->low_2ghz_chan = 2312;
3205 pCap->high_2ghz_chan = 2732; 3198 pCap->high_2ghz_chan = 2732;
@@ -3217,7 +3210,7 @@ bool ath9k_hw_fill_cap_info(struct ath_hal *ah)
3217 3210
3218 pCap->hw_caps |= ATH9K_HW_CAP_CHAN_SPREAD; 3211 pCap->hw_caps |= ATH9K_HW_CAP_CHAN_SPREAD;
3219 3212
3220 if (ah->ah_config.ht_enable) 3213 if (ah->config.ht_enable)
3221 pCap->hw_caps |= ATH9K_HW_CAP_HT; 3214 pCap->hw_caps |= ATH9K_HW_CAP_HT;
3222 else 3215 else
3223 pCap->hw_caps &= ~ATH9K_HW_CAP_HT; 3216 pCap->hw_caps &= ~ATH9K_HW_CAP_HT;
@@ -3268,22 +3261,22 @@ bool ath9k_hw_fill_cap_info(struct ath_hal *ah)
3268 pCap->hw_caps |= ATH9K_HW_CAP_ENHANCEDPM; 3261 pCap->hw_caps |= ATH9K_HW_CAP_ENHANCEDPM;
3269 3262
3270#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE) 3263#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
3271 ah->ah_rfsilent = ath9k_hw_get_eeprom(ah, EEP_RF_SILENT); 3264 ah->rfsilent = ah->eep_ops->get_eeprom(ah, EEP_RF_SILENT);
3272 if (ah->ah_rfsilent & EEP_RFSILENT_ENABLED) { 3265 if (ah->rfsilent & EEP_RFSILENT_ENABLED) {
3273 ah->ah_rfkill_gpio = 3266 ah->rfkill_gpio =
3274 MS(ah->ah_rfsilent, EEP_RFSILENT_GPIO_SEL); 3267 MS(ah->rfsilent, EEP_RFSILENT_GPIO_SEL);
3275 ah->ah_rfkill_polarity = 3268 ah->rfkill_polarity =
3276 MS(ah->ah_rfsilent, EEP_RFSILENT_POLARITY); 3269 MS(ah->rfsilent, EEP_RFSILENT_POLARITY);
3277 3270
3278 pCap->hw_caps |= ATH9K_HW_CAP_RFSILENT; 3271 pCap->hw_caps |= ATH9K_HW_CAP_RFSILENT;
3279 } 3272 }
3280#endif 3273#endif
3281 3274
3282 if ((ah->ah_macVersion == AR_SREV_VERSION_5416_PCI) || 3275 if ((ah->hw_version.macVersion == AR_SREV_VERSION_5416_PCI) ||
3283 (ah->ah_macVersion == AR_SREV_VERSION_5416_PCIE) || 3276 (ah->hw_version.macVersion == AR_SREV_VERSION_5416_PCIE) ||
3284 (ah->ah_macVersion == AR_SREV_VERSION_9160) || 3277 (ah->hw_version.macVersion == AR_SREV_VERSION_9160) ||
3285 (ah->ah_macVersion == AR_SREV_VERSION_9100) || 3278 (ah->hw_version.macVersion == AR_SREV_VERSION_9100) ||
3286 (ah->ah_macVersion == AR_SREV_VERSION_9280)) 3279 (ah->hw_version.macVersion == AR_SREV_VERSION_9280))
3287 pCap->hw_caps &= ~ATH9K_HW_CAP_AUTOSLEEP; 3280 pCap->hw_caps &= ~ATH9K_HW_CAP_AUTOSLEEP;
3288 else 3281 else
3289 pCap->hw_caps |= ATH9K_HW_CAP_AUTOSLEEP; 3282 pCap->hw_caps |= ATH9K_HW_CAP_AUTOSLEEP;
@@ -3293,7 +3286,7 @@ bool ath9k_hw_fill_cap_info(struct ath_hal *ah)
3293 else 3286 else
3294 pCap->hw_caps |= ATH9K_HW_CAP_4KB_SPLITTRANS; 3287 pCap->hw_caps |= ATH9K_HW_CAP_4KB_SPLITTRANS;
3295 3288
3296 if (ah->ah_currentRDExt & (1 << REG_EXT_JAPAN_MIDBAND)) { 3289 if (ah->regulatory.current_rd_ext & (1 << REG_EXT_JAPAN_MIDBAND)) {
3297 pCap->reg_cap = 3290 pCap->reg_cap =
3298 AR_EEPROM_EEREGCAP_EN_KK_NEW_11A | 3291 AR_EEPROM_EEREGCAP_EN_KK_NEW_11A |
3299 AR_EEPROM_EEREGCAP_EN_KK_U1_EVEN | 3292 AR_EEPROM_EEREGCAP_EN_KK_U1_EVEN |
@@ -3308,24 +3301,23 @@ bool ath9k_hw_fill_cap_info(struct ath_hal *ah)
3308 pCap->reg_cap |= AR_EEPROM_EEREGCAP_EN_FCC_MIDBAND; 3301 pCap->reg_cap |= AR_EEPROM_EEREGCAP_EN_FCC_MIDBAND;
3309 3302
3310 pCap->num_antcfg_5ghz = 3303 pCap->num_antcfg_5ghz =
3311 ath9k_hw_get_num_ant_config(ah, ATH9K_HAL_FREQ_BAND_5GHZ); 3304 ah->eep_ops->get_num_ant_config(ah, ATH9K_HAL_FREQ_BAND_5GHZ);
3312 pCap->num_antcfg_2ghz = 3305 pCap->num_antcfg_2ghz =
3313 ath9k_hw_get_num_ant_config(ah, ATH9K_HAL_FREQ_BAND_2GHZ); 3306 ah->eep_ops->get_num_ant_config(ah, ATH9K_HAL_FREQ_BAND_2GHZ);
3314 3307
3315 if (AR_SREV_9280_10_OR_LATER(ah) && btcoex_enable) { 3308 if (AR_SREV_9280_10_OR_LATER(ah) && btcoex_enable) {
3316 pCap->hw_caps |= ATH9K_HW_CAP_BT_COEX; 3309 pCap->hw_caps |= ATH9K_HW_CAP_BT_COEX;
3317 ah->ah_btactive_gpio = 6; 3310 ah->btactive_gpio = 6;
3318 ah->ah_wlanactive_gpio = 5; 3311 ah->wlanactive_gpio = 5;
3319 } 3312 }
3320 3313
3321 return true; 3314 return true;
3322} 3315}
3323 3316
3324bool ath9k_hw_getcapability(struct ath_hal *ah, enum ath9k_capability_type type, 3317bool ath9k_hw_getcapability(struct ath_hw *ah, enum ath9k_capability_type type,
3325 u32 capability, u32 *result) 3318 u32 capability, u32 *result)
3326{ 3319{
3327 struct ath_hal_5416 *ahp = AH5416(ah); 3320 const struct ath9k_hw_capabilities *pCap = &ah->caps;
3328 const struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
3329 3321
3330 switch (type) { 3322 switch (type) {
3331 case ATH9K_CAP_CIPHER: 3323 case ATH9K_CAP_CIPHER:
@@ -3345,17 +3337,17 @@ bool ath9k_hw_getcapability(struct ath_hal *ah, enum ath9k_capability_type type,
3345 case 0: 3337 case 0:
3346 return true; 3338 return true;
3347 case 1: 3339 case 1:
3348 return (ahp->ah_staId1Defaults & 3340 return (ah->sta_id1_defaults &
3349 AR_STA_ID1_CRPT_MIC_ENABLE) ? true : 3341 AR_STA_ID1_CRPT_MIC_ENABLE) ? true :
3350 false; 3342 false;
3351 } 3343 }
3352 case ATH9K_CAP_TKIP_SPLIT: 3344 case ATH9K_CAP_TKIP_SPLIT:
3353 return (ahp->ah_miscMode & AR_PCU_MIC_NEW_LOC_ENA) ? 3345 return (ah->misc_mode & AR_PCU_MIC_NEW_LOC_ENA) ?
3354 false : true; 3346 false : true;
3355 case ATH9K_CAP_WME_TKIPMIC: 3347 case ATH9K_CAP_WME_TKIPMIC:
3356 return 0; 3348 return 0;
3357 case ATH9K_CAP_PHYCOUNTERS: 3349 case ATH9K_CAP_PHYCOUNTERS:
3358 return ahp->ah_hasHwPhyCounters ? 0 : -ENXIO; 3350 return ah->has_hw_phycounters ? 0 : -ENXIO;
3359 case ATH9K_CAP_DIVERSITY: 3351 case ATH9K_CAP_DIVERSITY:
3360 return (REG_READ(ah, AR_PHY_CCK_DETECT) & 3352 return (REG_READ(ah, AR_PHY_CCK_DETECT) &
3361 AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV) ? 3353 AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV) ?
@@ -3370,14 +3362,14 @@ bool ath9k_hw_getcapability(struct ath_hal *ah, enum ath9k_capability_type type,
3370 if (REG_READ(ah, AR_STA_ID1) & AR_STA_ID1_ADHOC) { 3362 if (REG_READ(ah, AR_STA_ID1) & AR_STA_ID1_ADHOC) {
3371 return false; 3363 return false;
3372 } else { 3364 } else {
3373 return (ahp->ah_staId1Defaults & 3365 return (ah->sta_id1_defaults &
3374 AR_STA_ID1_MCAST_KSRCH) ? true : 3366 AR_STA_ID1_MCAST_KSRCH) ? true :
3375 false; 3367 false;
3376 } 3368 }
3377 } 3369 }
3378 return false; 3370 return false;
3379 case ATH9K_CAP_TSF_ADJUST: 3371 case ATH9K_CAP_TSF_ADJUST:
3380 return (ahp->ah_miscMode & AR_PCU_TX_ADD_TSF) ? 3372 return (ah->misc_mode & AR_PCU_TX_ADD_TSF) ?
3381 true : false; 3373 true : false;
3382 case ATH9K_CAP_RFSILENT: 3374 case ATH9K_CAP_RFSILENT:
3383 if (capability == 3) 3375 if (capability == 3)
@@ -3393,13 +3385,13 @@ bool ath9k_hw_getcapability(struct ath_hal *ah, enum ath9k_capability_type type,
3393 case 0: 3385 case 0:
3394 return 0; 3386 return 0;
3395 case 1: 3387 case 1:
3396 *result = ah->ah_powerLimit; 3388 *result = ah->regulatory.power_limit;
3397 return 0; 3389 return 0;
3398 case 2: 3390 case 2:
3399 *result = ah->ah_maxPowerLevel; 3391 *result = ah->regulatory.max_power_level;
3400 return 0; 3392 return 0;
3401 case 3: 3393 case 3:
3402 *result = ah->ah_tpScale; 3394 *result = ah->regulatory.tp_scale;
3403 return 0; 3395 return 0;
3404 } 3396 }
3405 return false; 3397 return false;
@@ -3408,19 +3400,18 @@ bool ath9k_hw_getcapability(struct ath_hal *ah, enum ath9k_capability_type type,
3408 } 3400 }
3409} 3401}
3410 3402
3411bool ath9k_hw_setcapability(struct ath_hal *ah, enum ath9k_capability_type type, 3403bool ath9k_hw_setcapability(struct ath_hw *ah, enum ath9k_capability_type type,
3412 u32 capability, u32 setting, int *status) 3404 u32 capability, u32 setting, int *status)
3413{ 3405{
3414 struct ath_hal_5416 *ahp = AH5416(ah);
3415 u32 v; 3406 u32 v;
3416 3407
3417 switch (type) { 3408 switch (type) {
3418 case ATH9K_CAP_TKIP_MIC: 3409 case ATH9K_CAP_TKIP_MIC:
3419 if (setting) 3410 if (setting)
3420 ahp->ah_staId1Defaults |= 3411 ah->sta_id1_defaults |=
3421 AR_STA_ID1_CRPT_MIC_ENABLE; 3412 AR_STA_ID1_CRPT_MIC_ENABLE;
3422 else 3413 else
3423 ahp->ah_staId1Defaults &= 3414 ah->sta_id1_defaults &=
3424 ~AR_STA_ID1_CRPT_MIC_ENABLE; 3415 ~AR_STA_ID1_CRPT_MIC_ENABLE;
3425 return true; 3416 return true;
3426 case ATH9K_CAP_DIVERSITY: 3417 case ATH9K_CAP_DIVERSITY:
@@ -3433,15 +3424,15 @@ bool ath9k_hw_setcapability(struct ath_hal *ah, enum ath9k_capability_type type,
3433 return true; 3424 return true;
3434 case ATH9K_CAP_MCAST_KEYSRCH: 3425 case ATH9K_CAP_MCAST_KEYSRCH:
3435 if (setting) 3426 if (setting)
3436 ahp->ah_staId1Defaults |= AR_STA_ID1_MCAST_KSRCH; 3427 ah->sta_id1_defaults |= AR_STA_ID1_MCAST_KSRCH;
3437 else 3428 else
3438 ahp->ah_staId1Defaults &= ~AR_STA_ID1_MCAST_KSRCH; 3429 ah->sta_id1_defaults &= ~AR_STA_ID1_MCAST_KSRCH;
3439 return true; 3430 return true;
3440 case ATH9K_CAP_TSF_ADJUST: 3431 case ATH9K_CAP_TSF_ADJUST:
3441 if (setting) 3432 if (setting)
3442 ahp->ah_miscMode |= AR_PCU_TX_ADD_TSF; 3433 ah->misc_mode |= AR_PCU_TX_ADD_TSF;
3443 else 3434 else
3444 ahp->ah_miscMode &= ~AR_PCU_TX_ADD_TSF; 3435 ah->misc_mode &= ~AR_PCU_TX_ADD_TSF;
3445 return true; 3436 return true;
3446 default: 3437 default:
3447 return false; 3438 return false;
@@ -3452,7 +3443,7 @@ bool ath9k_hw_setcapability(struct ath_hal *ah, enum ath9k_capability_type type,
3452/* GPIO / RFKILL / Antennae */ 3443/* GPIO / RFKILL / Antennae */
3453/****************************/ 3444/****************************/
3454 3445
3455static void ath9k_hw_gpio_cfg_output_mux(struct ath_hal *ah, 3446static void ath9k_hw_gpio_cfg_output_mux(struct ath_hw *ah,
3456 u32 gpio, u32 type) 3447 u32 gpio, u32 type)
3457{ 3448{
3458 int addr; 3449 int addr;
@@ -3480,11 +3471,11 @@ static void ath9k_hw_gpio_cfg_output_mux(struct ath_hal *ah,
3480 } 3471 }
3481} 3472}
3482 3473
3483void ath9k_hw_cfg_gpio_input(struct ath_hal *ah, u32 gpio) 3474void ath9k_hw_cfg_gpio_input(struct ath_hw *ah, u32 gpio)
3484{ 3475{
3485 u32 gpio_shift; 3476 u32 gpio_shift;
3486 3477
3487 ASSERT(gpio < ah->ah_caps.num_gpio_pins); 3478 ASSERT(gpio < ah->caps.num_gpio_pins);
3488 3479
3489 gpio_shift = gpio << 1; 3480 gpio_shift = gpio << 1;
3490 3481
@@ -3494,12 +3485,12 @@ void ath9k_hw_cfg_gpio_input(struct ath_hal *ah, u32 gpio)
3494 (AR_GPIO_OE_OUT_DRV << gpio_shift)); 3485 (AR_GPIO_OE_OUT_DRV << gpio_shift));
3495} 3486}
3496 3487
3497u32 ath9k_hw_gpio_get(struct ath_hal *ah, u32 gpio) 3488u32 ath9k_hw_gpio_get(struct ath_hw *ah, u32 gpio)
3498{ 3489{
3499#define MS_REG_READ(x, y) \ 3490#define MS_REG_READ(x, y) \
3500 (MS(REG_READ(ah, AR_GPIO_IN_OUT), x##_GPIO_IN_VAL) & (AR_GPIO_BIT(y))) 3491 (MS(REG_READ(ah, AR_GPIO_IN_OUT), x##_GPIO_IN_VAL) & (AR_GPIO_BIT(y)))
3501 3492
3502 if (gpio >= ah->ah_caps.num_gpio_pins) 3493 if (gpio >= ah->caps.num_gpio_pins)
3503 return 0xffffffff; 3494 return 0xffffffff;
3504 3495
3505 if (AR_SREV_9285_10_OR_LATER(ah)) 3496 if (AR_SREV_9285_10_OR_LATER(ah))
@@ -3510,7 +3501,7 @@ u32 ath9k_hw_gpio_get(struct ath_hal *ah, u32 gpio)
3510 return MS_REG_READ(AR, gpio) != 0; 3501 return MS_REG_READ(AR, gpio) != 0;
3511} 3502}
3512 3503
3513void ath9k_hw_cfg_output(struct ath_hal *ah, u32 gpio, 3504void ath9k_hw_cfg_output(struct ath_hw *ah, u32 gpio,
3514 u32 ah_signal_type) 3505 u32 ah_signal_type)
3515{ 3506{
3516 u32 gpio_shift; 3507 u32 gpio_shift;
@@ -3525,14 +3516,14 @@ void ath9k_hw_cfg_output(struct ath_hal *ah, u32 gpio,
3525 (AR_GPIO_OE_OUT_DRV << gpio_shift)); 3516 (AR_GPIO_OE_OUT_DRV << gpio_shift));
3526} 3517}
3527 3518
3528void ath9k_hw_set_gpio(struct ath_hal *ah, u32 gpio, u32 val) 3519void ath9k_hw_set_gpio(struct ath_hw *ah, u32 gpio, u32 val)
3529{ 3520{
3530 REG_RMW(ah, AR_GPIO_IN_OUT, ((val & 1) << gpio), 3521 REG_RMW(ah, AR_GPIO_IN_OUT, ((val & 1) << gpio),
3531 AR_GPIO_BIT(gpio)); 3522 AR_GPIO_BIT(gpio));
3532} 3523}
3533 3524
3534#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE) 3525#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
3535void ath9k_enable_rfkill(struct ath_hal *ah) 3526void ath9k_enable_rfkill(struct ath_hw *ah)
3536{ 3527{
3537 REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL, 3528 REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL,
3538 AR_GPIO_INPUT_EN_VAL_RFSILENT_BB); 3529 AR_GPIO_INPUT_EN_VAL_RFSILENT_BB);
@@ -3540,29 +3531,28 @@ void ath9k_enable_rfkill(struct ath_hal *ah)
3540 REG_CLR_BIT(ah, AR_GPIO_INPUT_MUX2, 3531 REG_CLR_BIT(ah, AR_GPIO_INPUT_MUX2,
3541 AR_GPIO_INPUT_MUX2_RFSILENT); 3532 AR_GPIO_INPUT_MUX2_RFSILENT);
3542 3533
3543 ath9k_hw_cfg_gpio_input(ah, ah->ah_rfkill_gpio); 3534 ath9k_hw_cfg_gpio_input(ah, ah->rfkill_gpio);
3544 REG_SET_BIT(ah, AR_PHY_TEST, RFSILENT_BB); 3535 REG_SET_BIT(ah, AR_PHY_TEST, RFSILENT_BB);
3545} 3536}
3546#endif 3537#endif
3547 3538
3548u32 ath9k_hw_getdefantenna(struct ath_hal *ah) 3539u32 ath9k_hw_getdefantenna(struct ath_hw *ah)
3549{ 3540{
3550 return REG_READ(ah, AR_DEF_ANTENNA) & 0x7; 3541 return REG_READ(ah, AR_DEF_ANTENNA) & 0x7;
3551} 3542}
3552 3543
3553void ath9k_hw_setantenna(struct ath_hal *ah, u32 antenna) 3544void ath9k_hw_setantenna(struct ath_hw *ah, u32 antenna)
3554{ 3545{
3555 REG_WRITE(ah, AR_DEF_ANTENNA, (antenna & 0x7)); 3546 REG_WRITE(ah, AR_DEF_ANTENNA, (antenna & 0x7));
3556} 3547}
3557 3548
3558bool ath9k_hw_setantennaswitch(struct ath_hal *ah, 3549bool ath9k_hw_setantennaswitch(struct ath_hw *ah,
3559 enum ath9k_ant_setting settings, 3550 enum ath9k_ant_setting settings,
3560 struct ath9k_channel *chan, 3551 struct ath9k_channel *chan,
3561 u8 *tx_chainmask, 3552 u8 *tx_chainmask,
3562 u8 *rx_chainmask, 3553 u8 *rx_chainmask,
3563 u8 *antenna_cfgd) 3554 u8 *antenna_cfgd)
3564{ 3555{
3565 struct ath_hal_5416 *ahp = AH5416(ah);
3566 static u8 tx_chainmask_cfg, rx_chainmask_cfg; 3556 static u8 tx_chainmask_cfg, rx_chainmask_cfg;
3567 3557
3568 if (AR_SREV_9280(ah)) { 3558 if (AR_SREV_9280(ah)) {
@@ -3579,7 +3569,7 @@ bool ath9k_hw_setantennaswitch(struct ath_hal *ah,
3579 *antenna_cfgd = true; 3569 *antenna_cfgd = true;
3580 break; 3570 break;
3581 case ATH9K_ANT_FIXED_B: 3571 case ATH9K_ANT_FIXED_B:
3582 if (ah->ah_caps.tx_chainmask > 3572 if (ah->caps.tx_chainmask >
3583 ATH9K_ANTENNA1_CHAINMASK) { 3573 ATH9K_ANTENNA1_CHAINMASK) {
3584 *tx_chainmask = ATH9K_ANTENNA1_CHAINMASK; 3574 *tx_chainmask = ATH9K_ANTENNA1_CHAINMASK;
3585 } 3575 }
@@ -3595,7 +3585,7 @@ bool ath9k_hw_setantennaswitch(struct ath_hal *ah,
3595 break; 3585 break;
3596 } 3586 }
3597 } else { 3587 } else {
3598 ahp->ah_diversityControl = settings; 3588 ah->diversity_control = settings;
3599 } 3589 }
3600 3590
3601 return true; 3591 return true;
@@ -3605,7 +3595,7 @@ bool ath9k_hw_setantennaswitch(struct ath_hal *ah,
3605/* General Operation */ 3595/* General Operation */
3606/*********************/ 3596/*********************/
3607 3597
3608u32 ath9k_hw_getrxfilter(struct ath_hal *ah) 3598u32 ath9k_hw_getrxfilter(struct ath_hw *ah)
3609{ 3599{
3610 u32 bits = REG_READ(ah, AR_RX_FILTER); 3600 u32 bits = REG_READ(ah, AR_RX_FILTER);
3611 u32 phybits = REG_READ(ah, AR_PHY_ERR); 3601 u32 phybits = REG_READ(ah, AR_PHY_ERR);
@@ -3618,7 +3608,7 @@ u32 ath9k_hw_getrxfilter(struct ath_hal *ah)
3618 return bits; 3608 return bits;
3619} 3609}
3620 3610
3621void ath9k_hw_setrxfilter(struct ath_hal *ah, u32 bits) 3611void ath9k_hw_setrxfilter(struct ath_hw *ah, u32 bits)
3622{ 3612{
3623 u32 phybits; 3613 u32 phybits;
3624 3614
@@ -3638,12 +3628,12 @@ void ath9k_hw_setrxfilter(struct ath_hal *ah, u32 bits)
3638 REG_READ(ah, AR_RXCFG) & ~AR_RXCFG_ZLFDMA); 3628 REG_READ(ah, AR_RXCFG) & ~AR_RXCFG_ZLFDMA);
3639} 3629}
3640 3630
3641bool ath9k_hw_phy_disable(struct ath_hal *ah) 3631bool ath9k_hw_phy_disable(struct ath_hw *ah)
3642{ 3632{
3643 return ath9k_hw_set_reset_reg(ah, ATH9K_RESET_WARM); 3633 return ath9k_hw_set_reset_reg(ah, ATH9K_RESET_WARM);
3644} 3634}
3645 3635
3646bool ath9k_hw_disable(struct ath_hal *ah) 3636bool ath9k_hw_disable(struct ath_hw *ah)
3647{ 3637{
3648 if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE)) 3638 if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE))
3649 return false; 3639 return false;
@@ -3651,83 +3641,54 @@ bool ath9k_hw_disable(struct ath_hal *ah)
3651 return ath9k_hw_set_reset_reg(ah, ATH9K_RESET_COLD); 3641 return ath9k_hw_set_reset_reg(ah, ATH9K_RESET_COLD);
3652} 3642}
3653 3643
3654bool ath9k_hw_set_txpowerlimit(struct ath_hal *ah, u32 limit) 3644bool ath9k_hw_set_txpowerlimit(struct ath_hw *ah, u32 limit)
3655{ 3645{
3656 struct ath9k_channel *chan = ah->ah_curchan; 3646 struct ath9k_channel *chan = ah->curchan;
3657 struct ieee80211_channel *channel = chan->chan; 3647 struct ieee80211_channel *channel = chan->chan;
3658 3648
3659 ah->ah_powerLimit = min(limit, (u32) MAX_RATE_POWER); 3649 ah->regulatory.power_limit = min(limit, (u32) MAX_RATE_POWER);
3660 3650
3661 if (ath9k_hw_set_txpower(ah, chan, 3651 if (ah->eep_ops->set_txpower(ah, chan,
3662 ath9k_regd_get_ctl(ah, chan), 3652 ath9k_regd_get_ctl(ah, chan),
3663 channel->max_antenna_gain * 2, 3653 channel->max_antenna_gain * 2,
3664 channel->max_power * 2, 3654 channel->max_power * 2,
3665 min((u32) MAX_RATE_POWER, 3655 min((u32) MAX_RATE_POWER,
3666 (u32) ah->ah_powerLimit)) != 0) 3656 (u32) ah->regulatory.power_limit)) != 0)
3667 return false; 3657 return false;
3668 3658
3669 return true; 3659 return true;
3670} 3660}
3671 3661
3672void ath9k_hw_getmac(struct ath_hal *ah, u8 *mac) 3662void ath9k_hw_setmac(struct ath_hw *ah, const u8 *mac)
3673{
3674 struct ath_hal_5416 *ahp = AH5416(ah);
3675
3676 memcpy(mac, ahp->ah_macaddr, ETH_ALEN);
3677}
3678
3679bool ath9k_hw_setmac(struct ath_hal *ah, const u8 *mac)
3680{ 3663{
3681 struct ath_hal_5416 *ahp = AH5416(ah); 3664 memcpy(ah->macaddr, mac, ETH_ALEN);
3682
3683 memcpy(ahp->ah_macaddr, mac, ETH_ALEN);
3684
3685 return true;
3686} 3665}
3687 3666
3688void ath9k_hw_setopmode(struct ath_hal *ah) 3667void ath9k_hw_setopmode(struct ath_hw *ah)
3689{ 3668{
3690 ath9k_hw_set_operating_mode(ah, ah->ah_opmode); 3669 ath9k_hw_set_operating_mode(ah, ah->opmode);
3691} 3670}
3692 3671
3693void ath9k_hw_setmcastfilter(struct ath_hal *ah, u32 filter0, u32 filter1) 3672void ath9k_hw_setmcastfilter(struct ath_hw *ah, u32 filter0, u32 filter1)
3694{ 3673{
3695 REG_WRITE(ah, AR_MCAST_FIL0, filter0); 3674 REG_WRITE(ah, AR_MCAST_FIL0, filter0);
3696 REG_WRITE(ah, AR_MCAST_FIL1, filter1); 3675 REG_WRITE(ah, AR_MCAST_FIL1, filter1);
3697} 3676}
3698 3677
3699void ath9k_hw_getbssidmask(struct ath_hal *ah, u8 *mask) 3678void ath9k_hw_setbssidmask(struct ath_softc *sc)
3700{ 3679{
3701 struct ath_hal_5416 *ahp = AH5416(ah); 3680 REG_WRITE(sc->sc_ah, AR_BSSMSKL, get_unaligned_le32(sc->bssidmask));
3702 3681 REG_WRITE(sc->sc_ah, AR_BSSMSKU, get_unaligned_le16(sc->bssidmask + 4));
3703 memcpy(mask, ahp->ah_bssidmask, ETH_ALEN);
3704} 3682}
3705 3683
3706bool ath9k_hw_setbssidmask(struct ath_hal *ah, const u8 *mask) 3684void ath9k_hw_write_associd(struct ath_softc *sc)
3707{ 3685{
3708 struct ath_hal_5416 *ahp = AH5416(ah); 3686 REG_WRITE(sc->sc_ah, AR_BSS_ID0, get_unaligned_le32(sc->curbssid));
3709 3687 REG_WRITE(sc->sc_ah, AR_BSS_ID1, get_unaligned_le16(sc->curbssid + 4) |
3710 memcpy(ahp->ah_bssidmask, mask, ETH_ALEN); 3688 ((sc->curaid & 0x3fff) << AR_BSS_ID1_AID_S));
3711
3712 REG_WRITE(ah, AR_BSSMSKL, get_unaligned_le32(ahp->ah_bssidmask));
3713 REG_WRITE(ah, AR_BSSMSKU, get_unaligned_le16(ahp->ah_bssidmask + 4));
3714
3715 return true;
3716} 3689}
3717 3690
3718void ath9k_hw_write_associd(struct ath_hal *ah, const u8 *bssid, u16 assocId) 3691u64 ath9k_hw_gettsf64(struct ath_hw *ah)
3719{
3720 struct ath_hal_5416 *ahp = AH5416(ah);
3721
3722 memcpy(ahp->ah_bssid, bssid, ETH_ALEN);
3723 ahp->ah_assocId = assocId;
3724
3725 REG_WRITE(ah, AR_BSS_ID0, get_unaligned_le32(ahp->ah_bssid));
3726 REG_WRITE(ah, AR_BSS_ID1, get_unaligned_le16(ahp->ah_bssid + 4) |
3727 ((assocId & 0x3fff) << AR_BSS_ID1_AID_S));
3728}
3729
3730u64 ath9k_hw_gettsf64(struct ath_hal *ah)
3731{ 3692{
3732 u64 tsf; 3693 u64 tsf;
3733 3694
@@ -3737,14 +3698,14 @@ u64 ath9k_hw_gettsf64(struct ath_hal *ah)
3737 return tsf; 3698 return tsf;
3738} 3699}
3739 3700
3740void ath9k_hw_settsf64(struct ath_hal *ah, u64 tsf64) 3701void ath9k_hw_settsf64(struct ath_hw *ah, u64 tsf64)
3741{ 3702{
3742 REG_WRITE(ah, AR_TSF_L32, 0x00000000); 3703 REG_WRITE(ah, AR_TSF_L32, 0x00000000);
3743 REG_WRITE(ah, AR_TSF_U32, (tsf64 >> 32) & 0xffffffff); 3704 REG_WRITE(ah, AR_TSF_U32, (tsf64 >> 32) & 0xffffffff);
3744 REG_WRITE(ah, AR_TSF_L32, tsf64 & 0xffffffff); 3705 REG_WRITE(ah, AR_TSF_L32, tsf64 & 0xffffffff);
3745} 3706}
3746 3707
3747void ath9k_hw_reset_tsf(struct ath_hal *ah) 3708void ath9k_hw_reset_tsf(struct ath_hw *ah)
3748{ 3709{
3749 int count; 3710 int count;
3750 3711
@@ -3761,39 +3722,35 @@ void ath9k_hw_reset_tsf(struct ath_hal *ah)
3761 REG_WRITE(ah, AR_RESET_TSF, AR_RESET_TSF_ONCE); 3722 REG_WRITE(ah, AR_RESET_TSF, AR_RESET_TSF_ONCE);
3762} 3723}
3763 3724
3764bool ath9k_hw_set_tsfadjust(struct ath_hal *ah, u32 setting) 3725bool ath9k_hw_set_tsfadjust(struct ath_hw *ah, u32 setting)
3765{ 3726{
3766 struct ath_hal_5416 *ahp = AH5416(ah);
3767
3768 if (setting) 3727 if (setting)
3769 ahp->ah_miscMode |= AR_PCU_TX_ADD_TSF; 3728 ah->misc_mode |= AR_PCU_TX_ADD_TSF;
3770 else 3729 else
3771 ahp->ah_miscMode &= ~AR_PCU_TX_ADD_TSF; 3730 ah->misc_mode &= ~AR_PCU_TX_ADD_TSF;
3772 3731
3773 return true; 3732 return true;
3774} 3733}
3775 3734
3776bool ath9k_hw_setslottime(struct ath_hal *ah, u32 us) 3735bool ath9k_hw_setslottime(struct ath_hw *ah, u32 us)
3777{ 3736{
3778 struct ath_hal_5416 *ahp = AH5416(ah);
3779
3780 if (us < ATH9K_SLOT_TIME_9 || us > ath9k_hw_mac_to_usec(ah, 0xffff)) { 3737 if (us < ATH9K_SLOT_TIME_9 || us > ath9k_hw_mac_to_usec(ah, 0xffff)) {
3781 DPRINTF(ah->ah_sc, ATH_DBG_RESET, "bad slot time %u\n", us); 3738 DPRINTF(ah->ah_sc, ATH_DBG_RESET, "bad slot time %u\n", us);
3782 ahp->ah_slottime = (u32) -1; 3739 ah->slottime = (u32) -1;
3783 return false; 3740 return false;
3784 } else { 3741 } else {
3785 REG_WRITE(ah, AR_D_GBL_IFS_SLOT, ath9k_hw_mac_to_clks(ah, us)); 3742 REG_WRITE(ah, AR_D_GBL_IFS_SLOT, ath9k_hw_mac_to_clks(ah, us));
3786 ahp->ah_slottime = us; 3743 ah->slottime = us;
3787 return true; 3744 return true;
3788 } 3745 }
3789} 3746}
3790 3747
3791void ath9k_hw_set11nmac2040(struct ath_hal *ah, enum ath9k_ht_macmode mode) 3748void ath9k_hw_set11nmac2040(struct ath_hw *ah, enum ath9k_ht_macmode mode)
3792{ 3749{
3793 u32 macmode; 3750 u32 macmode;
3794 3751
3795 if (mode == ATH9K_HT_MACMODE_2040 && 3752 if (mode == ATH9K_HT_MACMODE_2040 &&
3796 !ah->ah_config.cwm_ignore_extcca) 3753 !ah->config.cwm_ignore_extcca)
3797 macmode = AR_2040_JOINED_RX_CLEAR; 3754 macmode = AR_2040_JOINED_RX_CLEAR;
3798 else 3755 else
3799 macmode = 0; 3756 macmode = 0;
@@ -3805,7 +3762,7 @@ void ath9k_hw_set11nmac2040(struct ath_hal *ah, enum ath9k_ht_macmode mode)
3805/* Bluetooth Coexistence */ 3762/* Bluetooth Coexistence */
3806/***************************/ 3763/***************************/
3807 3764
3808void ath9k_hw_btcoex_enable(struct ath_hal *ah) 3765void ath9k_hw_btcoex_enable(struct ath_hw *ah)
3809{ 3766{
3810 /* connect bt_active to baseband */ 3767 /* connect bt_active to baseband */
3811 REG_CLR_BIT(ah, AR_GPIO_INPUT_EN_VAL, 3768 REG_CLR_BIT(ah, AR_GPIO_INPUT_EN_VAL,
@@ -3818,12 +3775,12 @@ void ath9k_hw_btcoex_enable(struct ath_hal *ah)
3818 /* Set input mux for bt_active to gpio pin */ 3775 /* Set input mux for bt_active to gpio pin */
3819 REG_RMW_FIELD(ah, AR_GPIO_INPUT_MUX1, 3776 REG_RMW_FIELD(ah, AR_GPIO_INPUT_MUX1,
3820 AR_GPIO_INPUT_MUX1_BT_ACTIVE, 3777 AR_GPIO_INPUT_MUX1_BT_ACTIVE,
3821 ah->ah_btactive_gpio); 3778 ah->btactive_gpio);
3822 3779
3823 /* Configure the desired gpio port for input */ 3780 /* Configure the desired gpio port for input */
3824 ath9k_hw_cfg_gpio_input(ah, ah->ah_btactive_gpio); 3781 ath9k_hw_cfg_gpio_input(ah, ah->btactive_gpio);
3825 3782
3826 /* Configure the desired GPIO port for TX_FRAME output */ 3783 /* Configure the desired GPIO port for TX_FRAME output */
3827 ath9k_hw_cfg_output(ah, ah->ah_wlanactive_gpio, 3784 ath9k_hw_cfg_output(ah, ah->wlanactive_gpio,
3828 AR_GPIO_OUTPUT_MUX_AS_TX_FRAME); 3785 AR_GPIO_OUTPUT_MUX_AS_TX_FRAME);
3829} 3786}
diff --git a/drivers/net/wireless/ath9k/hw.h b/drivers/net/wireless/ath9k/hw.h
index 087c5718707b..82111636c693 100644
--- a/drivers/net/wireless/ath9k/hw.h
+++ b/drivers/net/wireless/ath9k/hw.h
@@ -19,1075 +19,627 @@
19 19
20#include <linux/if_ether.h> 20#include <linux/if_ether.h>
21#include <linux/delay.h> 21#include <linux/delay.h>
22#include <linux/io.h>
23
24#include "mac.h"
25#include "ani.h"
26#include "eeprom.h"
27#include "calib.h"
28#include "regd.h"
29#include "reg.h"
30#include "phy.h"
31
32#define ATHEROS_VENDOR_ID 0x168c
33#define AR5416_DEVID_PCI 0x0023
34#define AR5416_DEVID_PCIE 0x0024
35#define AR9160_DEVID_PCI 0x0027
36#define AR9280_DEVID_PCI 0x0029
37#define AR9280_DEVID_PCIE 0x002a
38#define AR9285_DEVID_PCIE 0x002b
39#define AR5416_AR9100_DEVID 0x000b
40#define AR_SUBVENDOR_ID_NOG 0x0e11
41#define AR_SUBVENDOR_ID_NEW_A 0x7065
42#define AR5416_MAGIC 0x19641014
43
44/* Register read/write primitives */
45#define REG_WRITE(_ah, _reg, _val) iowrite32(_val, _ah->ah_sc->mem + _reg)
46#define REG_READ(_ah, _reg) ioread32(_ah->ah_sc->mem + _reg)
47
48#define SM(_v, _f) (((_v) << _f##_S) & _f)
49#define MS(_v, _f) (((_v) & _f) >> _f##_S)
50#define REG_RMW(_a, _r, _set, _clr) \
51 REG_WRITE(_a, _r, (REG_READ(_a, _r) & ~(_clr)) | (_set))
52#define REG_RMW_FIELD(_a, _r, _f, _v) \
53 REG_WRITE(_a, _r, \
54 (REG_READ(_a, _r) & ~_f) | (((_v) << _f##_S) & _f))
55#define REG_SET_BIT(_a, _r, _f) \
56 REG_WRITE(_a, _r, REG_READ(_a, _r) | _f)
57#define REG_CLR_BIT(_a, _r, _f) \
58 REG_WRITE(_a, _r, REG_READ(_a, _r) & ~_f)
22 59
23extern const struct hal_percal_data iq_cal_multi_sample; 60#define DO_DELAY(x) do { \
24extern const struct hal_percal_data iq_cal_single_sample; 61 if ((++(x) % 64) == 0) \
25extern const struct hal_percal_data adc_gain_cal_multi_sample; 62 udelay(1); \
26extern const struct hal_percal_data adc_gain_cal_single_sample; 63 } while (0)
27extern const struct hal_percal_data adc_dc_cal_multi_sample;
28extern const struct hal_percal_data adc_dc_cal_single_sample;
29extern const struct hal_percal_data adc_init_dc_cal;
30
31struct ar5416_desc {
32 u32 ds_link;
33 u32 ds_data;
34 u32 ds_ctl0;
35 u32 ds_ctl1;
36 union {
37 struct {
38 u32 ctl2;
39 u32 ctl3;
40 u32 ctl4;
41 u32 ctl5;
42 u32 ctl6;
43 u32 ctl7;
44 u32 ctl8;
45 u32 ctl9;
46 u32 ctl10;
47 u32 ctl11;
48 u32 status0;
49 u32 status1;
50 u32 status2;
51 u32 status3;
52 u32 status4;
53 u32 status5;
54 u32 status6;
55 u32 status7;
56 u32 status8;
57 u32 status9;
58 } tx;
59 struct {
60 u32 status0;
61 u32 status1;
62 u32 status2;
63 u32 status3;
64 u32 status4;
65 u32 status5;
66 u32 status6;
67 u32 status7;
68 u32 status8;
69 } rx;
70 } u;
71} __packed;
72
73#define AR5416DESC(_ds) ((struct ar5416_desc *)(_ds))
74#define AR5416DESC_CONST(_ds) ((const struct ar5416_desc *)(_ds))
75
76#define ds_ctl2 u.tx.ctl2
77#define ds_ctl3 u.tx.ctl3
78#define ds_ctl4 u.tx.ctl4
79#define ds_ctl5 u.tx.ctl5
80#define ds_ctl6 u.tx.ctl6
81#define ds_ctl7 u.tx.ctl7
82#define ds_ctl8 u.tx.ctl8
83#define ds_ctl9 u.tx.ctl9
84#define ds_ctl10 u.tx.ctl10
85#define ds_ctl11 u.tx.ctl11
86
87#define ds_txstatus0 u.tx.status0
88#define ds_txstatus1 u.tx.status1
89#define ds_txstatus2 u.tx.status2
90#define ds_txstatus3 u.tx.status3
91#define ds_txstatus4 u.tx.status4
92#define ds_txstatus5 u.tx.status5
93#define ds_txstatus6 u.tx.status6
94#define ds_txstatus7 u.tx.status7
95#define ds_txstatus8 u.tx.status8
96#define ds_txstatus9 u.tx.status9
97
98#define ds_rxstatus0 u.rx.status0
99#define ds_rxstatus1 u.rx.status1
100#define ds_rxstatus2 u.rx.status2
101#define ds_rxstatus3 u.rx.status3
102#define ds_rxstatus4 u.rx.status4
103#define ds_rxstatus5 u.rx.status5
104#define ds_rxstatus6 u.rx.status6
105#define ds_rxstatus7 u.rx.status7
106#define ds_rxstatus8 u.rx.status8
107
108#define AR_FrameLen 0x00000fff
109#define AR_VirtMoreFrag 0x00001000
110#define AR_TxCtlRsvd00 0x0000e000
111#define AR_XmitPower 0x003f0000
112#define AR_XmitPower_S 16
113#define AR_RTSEnable 0x00400000
114#define AR_VEOL 0x00800000
115#define AR_ClrDestMask 0x01000000
116#define AR_TxCtlRsvd01 0x1e000000
117#define AR_TxIntrReq 0x20000000
118#define AR_DestIdxValid 0x40000000
119#define AR_CTSEnable 0x80000000
120
121#define AR_BufLen 0x00000fff
122#define AR_TxMore 0x00001000
123#define AR_DestIdx 0x000fe000
124#define AR_DestIdx_S 13
125#define AR_FrameType 0x00f00000
126#define AR_FrameType_S 20
127#define AR_NoAck 0x01000000
128#define AR_InsertTS 0x02000000
129#define AR_CorruptFCS 0x04000000
130#define AR_ExtOnly 0x08000000
131#define AR_ExtAndCtl 0x10000000
132#define AR_MoreAggr 0x20000000
133#define AR_IsAggr 0x40000000
134
135#define AR_BurstDur 0x00007fff
136#define AR_BurstDur_S 0
137#define AR_DurUpdateEna 0x00008000
138#define AR_XmitDataTries0 0x000f0000
139#define AR_XmitDataTries0_S 16
140#define AR_XmitDataTries1 0x00f00000
141#define AR_XmitDataTries1_S 20
142#define AR_XmitDataTries2 0x0f000000
143#define AR_XmitDataTries2_S 24
144#define AR_XmitDataTries3 0xf0000000
145#define AR_XmitDataTries3_S 28
146
147#define AR_XmitRate0 0x000000ff
148#define AR_XmitRate0_S 0
149#define AR_XmitRate1 0x0000ff00
150#define AR_XmitRate1_S 8
151#define AR_XmitRate2 0x00ff0000
152#define AR_XmitRate2_S 16
153#define AR_XmitRate3 0xff000000
154#define AR_XmitRate3_S 24
155
156#define AR_PacketDur0 0x00007fff
157#define AR_PacketDur0_S 0
158#define AR_RTSCTSQual0 0x00008000
159#define AR_PacketDur1 0x7fff0000
160#define AR_PacketDur1_S 16
161#define AR_RTSCTSQual1 0x80000000
162
163#define AR_PacketDur2 0x00007fff
164#define AR_PacketDur2_S 0
165#define AR_RTSCTSQual2 0x00008000
166#define AR_PacketDur3 0x7fff0000
167#define AR_PacketDur3_S 16
168#define AR_RTSCTSQual3 0x80000000
169
170#define AR_AggrLen 0x0000ffff
171#define AR_AggrLen_S 0
172#define AR_TxCtlRsvd60 0x00030000
173#define AR_PadDelim 0x03fc0000
174#define AR_PadDelim_S 18
175#define AR_EncrType 0x0c000000
176#define AR_EncrType_S 26
177#define AR_TxCtlRsvd61 0xf0000000
178
179#define AR_2040_0 0x00000001
180#define AR_GI0 0x00000002
181#define AR_ChainSel0 0x0000001c
182#define AR_ChainSel0_S 2
183#define AR_2040_1 0x00000020
184#define AR_GI1 0x00000040
185#define AR_ChainSel1 0x00000380
186#define AR_ChainSel1_S 7
187#define AR_2040_2 0x00000400
188#define AR_GI2 0x00000800
189#define AR_ChainSel2 0x00007000
190#define AR_ChainSel2_S 12
191#define AR_2040_3 0x00008000
192#define AR_GI3 0x00010000
193#define AR_ChainSel3 0x000e0000
194#define AR_ChainSel3_S 17
195#define AR_RTSCTSRate 0x0ff00000
196#define AR_RTSCTSRate_S 20
197#define AR_TxCtlRsvd70 0xf0000000
198
199#define AR_TxRSSIAnt00 0x000000ff
200#define AR_TxRSSIAnt00_S 0
201#define AR_TxRSSIAnt01 0x0000ff00
202#define AR_TxRSSIAnt01_S 8
203#define AR_TxRSSIAnt02 0x00ff0000
204#define AR_TxRSSIAnt02_S 16
205#define AR_TxStatusRsvd00 0x3f000000
206#define AR_TxBaStatus 0x40000000
207#define AR_TxStatusRsvd01 0x80000000
208
209#define AR_FrmXmitOK 0x00000001
210#define AR_ExcessiveRetries 0x00000002
211#define AR_FIFOUnderrun 0x00000004
212#define AR_Filtered 0x00000008
213#define AR_RTSFailCnt 0x000000f0
214#define AR_RTSFailCnt_S 4
215#define AR_DataFailCnt 0x00000f00
216#define AR_DataFailCnt_S 8
217#define AR_VirtRetryCnt 0x0000f000
218#define AR_VirtRetryCnt_S 12
219#define AR_TxDelimUnderrun 0x00010000
220#define AR_TxDataUnderrun 0x00020000
221#define AR_DescCfgErr 0x00040000
222#define AR_TxTimerExpired 0x00080000
223#define AR_TxStatusRsvd10 0xfff00000
224
225#define AR_SendTimestamp ds_txstatus2
226#define AR_BaBitmapLow ds_txstatus3
227#define AR_BaBitmapHigh ds_txstatus4
228
229#define AR_TxRSSIAnt10 0x000000ff
230#define AR_TxRSSIAnt10_S 0
231#define AR_TxRSSIAnt11 0x0000ff00
232#define AR_TxRSSIAnt11_S 8
233#define AR_TxRSSIAnt12 0x00ff0000
234#define AR_TxRSSIAnt12_S 16
235#define AR_TxRSSICombined 0xff000000
236#define AR_TxRSSICombined_S 24
237
238#define AR_TxEVM0 ds_txstatus5
239#define AR_TxEVM1 ds_txstatus6
240#define AR_TxEVM2 ds_txstatus7
241
242#define AR_TxDone 0x00000001
243#define AR_SeqNum 0x00001ffe
244#define AR_SeqNum_S 1
245#define AR_TxStatusRsvd80 0x0001e000
246#define AR_TxOpExceeded 0x00020000
247#define AR_TxStatusRsvd81 0x001c0000
248#define AR_FinalTxIdx 0x00600000
249#define AR_FinalTxIdx_S 21
250#define AR_TxStatusRsvd82 0x01800000
251#define AR_PowerMgmt 0x02000000
252#define AR_TxStatusRsvd83 0xfc000000
253
254#define AR_RxCTLRsvd00 0xffffffff
255
256#define AR_BufLen 0x00000fff
257#define AR_RxCtlRsvd00 0x00001000
258#define AR_RxIntrReq 0x00002000
259#define AR_RxCtlRsvd01 0xffffc000
260
261#define AR_RxRSSIAnt00 0x000000ff
262#define AR_RxRSSIAnt00_S 0
263#define AR_RxRSSIAnt01 0x0000ff00
264#define AR_RxRSSIAnt01_S 8
265#define AR_RxRSSIAnt02 0x00ff0000
266#define AR_RxRSSIAnt02_S 16
267#define AR_RxRate 0xff000000
268#define AR_RxRate_S 24
269#define AR_RxStatusRsvd00 0xff000000
270
271#define AR_DataLen 0x00000fff
272#define AR_RxMore 0x00001000
273#define AR_NumDelim 0x003fc000
274#define AR_NumDelim_S 14
275#define AR_RxStatusRsvd10 0xff800000
276
277#define AR_RcvTimestamp ds_rxstatus2
278
279#define AR_GI 0x00000001
280#define AR_2040 0x00000002
281#define AR_Parallel40 0x00000004
282#define AR_Parallel40_S 2
283#define AR_RxStatusRsvd30 0x000000f8
284#define AR_RxAntenna 0xffffff00
285#define AR_RxAntenna_S 8
286
287#define AR_RxRSSIAnt10 0x000000ff
288#define AR_RxRSSIAnt10_S 0
289#define AR_RxRSSIAnt11 0x0000ff00
290#define AR_RxRSSIAnt11_S 8
291#define AR_RxRSSIAnt12 0x00ff0000
292#define AR_RxRSSIAnt12_S 16
293#define AR_RxRSSICombined 0xff000000
294#define AR_RxRSSICombined_S 24
295
296#define AR_RxEVM0 ds_rxstatus4
297#define AR_RxEVM1 ds_rxstatus5
298#define AR_RxEVM2 ds_rxstatus6
299
300#define AR_RxDone 0x00000001
301#define AR_RxFrameOK 0x00000002
302#define AR_CRCErr 0x00000004
303#define AR_DecryptCRCErr 0x00000008
304#define AR_PHYErr 0x00000010
305#define AR_MichaelErr 0x00000020
306#define AR_PreDelimCRCErr 0x00000040
307#define AR_RxStatusRsvd70 0x00000080
308#define AR_RxKeyIdxValid 0x00000100
309#define AR_KeyIdx 0x0000fe00
310#define AR_KeyIdx_S 9
311#define AR_PHYErrCode 0x0000ff00
312#define AR_PHYErrCode_S 8
313#define AR_RxMoreAggr 0x00010000
314#define AR_RxAggr 0x00020000
315#define AR_PostDelimCRCErr 0x00040000
316#define AR_RxStatusRsvd71 0x3ff80000
317#define AR_DecryptBusyErr 0x40000000
318#define AR_KeyMiss 0x80000000
319
320#define AR5416_MAGIC 0x19641014
321
322#define RXSTATUS_RATE(ah, ads) (AR_SREV_5416_V20_OR_LATER(ah) ? \
323 MS(ads->ds_rxstatus0, AR_RxRate) : \
324 (ads->ds_rxstatus3 >> 2) & 0xFF)
325
326#define set11nTries(_series, _index) \
327 (SM((_series)[_index].Tries, AR_XmitDataTries##_index))
328
329#define set11nRate(_series, _index) \
330 (SM((_series)[_index].Rate, AR_XmitRate##_index))
331
332#define set11nPktDurRTSCTS(_series, _index) \
333 (SM((_series)[_index].PktDuration, AR_PacketDur##_index) | \
334 ((_series)[_index].RateFlags & ATH9K_RATESERIES_RTS_CTS ? \
335 AR_RTSCTSQual##_index : 0))
336 64
337#define set11nRateFlags(_series, _index) \ 65#define REG_WRITE_ARRAY(iniarray, column, regWr) do { \
338 (((_series)[_index].RateFlags & ATH9K_RATESERIES_2040 ? \ 66 int r; \
339 AR_2040_##_index : 0) \ 67 for (r = 0; r < ((iniarray)->ia_rows); r++) { \
340 |((_series)[_index].RateFlags & ATH9K_RATESERIES_HALFGI ? \ 68 REG_WRITE(ah, INI_RA((iniarray), (r), 0), \
341 AR_GI##_index : 0) \ 69 INI_RA((iniarray), r, (column))); \
342 |SM((_series)[_index].ChSel, AR_ChainSel##_index)) 70 DO_DELAY(regWr); \
71 } \
72 } while (0)
343 73
344#define AR_SREV_9100(ah) ((ah->ah_macVersion) == AR_SREV_VERSION_9100) 74#define AR_GPIO_OUTPUT_MUX_AS_OUTPUT 0
75#define AR_GPIO_OUTPUT_MUX_AS_PCIE_ATTENTION_LED 1
76#define AR_GPIO_OUTPUT_MUX_AS_PCIE_POWER_LED 2
77#define AR_GPIO_OUTPUT_MUX_AS_TX_FRAME 3
78#define AR_GPIO_OUTPUT_MUX_AS_MAC_NETWORK_LED 5
79#define AR_GPIO_OUTPUT_MUX_AS_MAC_POWER_LED 6
345 80
346#define INIT_CONFIG_STATUS 0x00000000 81#define AR_GPIOD_MASK 0x00001FFF
347#define INIT_RSSI_THR 0x00000700 82#define AR_GPIO_BIT(_gpio) (1 << (_gpio))
348#define INIT_BCON_CNTRL_REG 0x00000000
349 83
350#define MIN_TX_FIFO_THRESHOLD 0x1 84#define BASE_ACTIVATE_DELAY 100
351#define MAX_TX_FIFO_THRESHOLD ((4096 / 64) - 1) 85#define RTC_PLL_SETTLE_DELAY 1000
352#define INIT_TX_FIFO_THRESHOLD MIN_TX_FIFO_THRESHOLD 86#define COEF_SCALE_S 24
87#define HT40_CHANNEL_CENTER_SHIFT 10
353 88
354struct ar5416AniState { 89#define ATH9K_ANTENNA0_CHAINMASK 0x1
355 struct ath9k_channel c; 90#define ATH9K_ANTENNA1_CHAINMASK 0x2
356 u8 noiseImmunityLevel; 91
357 u8 spurImmunityLevel; 92#define ATH9K_NUM_DMA_DEBUG_REGS 8
358 u8 firstepLevel; 93#define ATH9K_NUM_QUEUES 10
359 u8 ofdmWeakSigDetectOff; 94
360 u8 cckWeakSigThreshold; 95#define MAX_RATE_POWER 63
361 u32 listenTime; 96#define AH_TIMEOUT 100000
362 u32 ofdmTrigHigh; 97#define AH_TIME_QUANTUM 10
363 u32 ofdmTrigLow; 98#define AR_KEYTABLE_SIZE 128
364 int32_t cckTrigHigh; 99#define POWER_UP_TIME 200000
365 int32_t cckTrigLow; 100#define SPUR_RSSI_THRESH 40
366 int32_t rssiThrLow; 101
367 int32_t rssiThrHigh; 102#define CAB_TIMEOUT_VAL 10
368 u32 noiseFloor; 103#define BEACON_TIMEOUT_VAL 10
369 u32 txFrameCount; 104#define MIN_BEACON_TIMEOUT_VAL 1
370 u32 rxFrameCount; 105#define SLEEP_SLOP 3
371 u32 cycleCount; 106
372 u32 ofdmPhyErrCount; 107#define INIT_CONFIG_STATUS 0x00000000
373 u32 cckPhyErrCount; 108#define INIT_RSSI_THR 0x00000700
374 u32 ofdmPhyErrBase; 109#define INIT_BCON_CNTRL_REG 0x00000000
375 u32 cckPhyErrBase; 110
376 int16_t pktRssi[2]; 111#define TU_TO_USEC(_tu) ((_tu) << 10)
377 int16_t ofdmErrRssi[2]; 112
378 int16_t cckErrRssi[2]; 113enum wireless_mode {
114 ATH9K_MODE_11A = 0,
115 ATH9K_MODE_11B = 2,
116 ATH9K_MODE_11G = 3,
117 ATH9K_MODE_11NA_HT20 = 6,
118 ATH9K_MODE_11NG_HT20 = 7,
119 ATH9K_MODE_11NA_HT40PLUS = 8,
120 ATH9K_MODE_11NA_HT40MINUS = 9,
121 ATH9K_MODE_11NG_HT40PLUS = 10,
122 ATH9K_MODE_11NG_HT40MINUS = 11,
123 ATH9K_MODE_MAX
379}; 124};
380 125
381#define HAL_PROCESS_ANI 0x00000001 126enum ath9k_hw_caps {
382#define DO_ANI(ah) \ 127 ATH9K_HW_CAP_CHAN_SPREAD = BIT(0),
383 ((AH5416(ah)->ah_procPhyErr & HAL_PROCESS_ANI)) 128 ATH9K_HW_CAP_MIC_AESCCM = BIT(1),
384 129 ATH9K_HW_CAP_MIC_CKIP = BIT(2),
385struct ar5416Stats { 130 ATH9K_HW_CAP_MIC_TKIP = BIT(3),
386 u32 ast_ani_niup; 131 ATH9K_HW_CAP_CIPHER_AESCCM = BIT(4),
387 u32 ast_ani_nidown; 132 ATH9K_HW_CAP_CIPHER_CKIP = BIT(5),
388 u32 ast_ani_spurup; 133 ATH9K_HW_CAP_CIPHER_TKIP = BIT(6),
389 u32 ast_ani_spurdown; 134 ATH9K_HW_CAP_VEOL = BIT(7),
390 u32 ast_ani_ofdmon; 135 ATH9K_HW_CAP_BSSIDMASK = BIT(8),
391 u32 ast_ani_ofdmoff; 136 ATH9K_HW_CAP_MCAST_KEYSEARCH = BIT(9),
392 u32 ast_ani_cckhigh; 137 ATH9K_HW_CAP_CHAN_HALFRATE = BIT(10),
393 u32 ast_ani_ccklow; 138 ATH9K_HW_CAP_CHAN_QUARTERRATE = BIT(11),
394 u32 ast_ani_stepup; 139 ATH9K_HW_CAP_HT = BIT(12),
395 u32 ast_ani_stepdown; 140 ATH9K_HW_CAP_GTT = BIT(13),
396 u32 ast_ani_ofdmerrs; 141 ATH9K_HW_CAP_FASTCC = BIT(14),
397 u32 ast_ani_cckerrs; 142 ATH9K_HW_CAP_RFSILENT = BIT(15),
398 u32 ast_ani_reset; 143 ATH9K_HW_CAP_WOW = BIT(16),
399 u32 ast_ani_lzero; 144 ATH9K_HW_CAP_CST = BIT(17),
400 u32 ast_ani_lneg; 145 ATH9K_HW_CAP_ENHANCEDPM = BIT(18),
401 struct ath9k_mib_stats ast_mibstats; 146 ATH9K_HW_CAP_AUTOSLEEP = BIT(19),
402 struct ath9k_node_stats ast_nodestats; 147 ATH9K_HW_CAP_4KB_SPLITTRANS = BIT(20),
148 ATH9K_HW_CAP_WOW_MATCHPATTERN_EXACT = BIT(21),
149 ATH9K_HW_CAP_BT_COEX = BIT(22)
403}; 150};
404 151
405#define AR5416_OPFLAGS_11A 0x01 152enum ath9k_capability_type {
406#define AR5416_OPFLAGS_11G 0x02 153 ATH9K_CAP_CIPHER = 0,
407#define AR5416_OPFLAGS_N_5G_HT40 0x04 154 ATH9K_CAP_TKIP_MIC,
408#define AR5416_OPFLAGS_N_2G_HT40 0x08 155 ATH9K_CAP_TKIP_SPLIT,
409#define AR5416_OPFLAGS_N_5G_HT20 0x10 156 ATH9K_CAP_PHYCOUNTERS,
410#define AR5416_OPFLAGS_N_2G_HT20 0x20 157 ATH9K_CAP_DIVERSITY,
411 158 ATH9K_CAP_TXPOW,
412#define EEP_RFSILENT_ENABLED 0x0001 159 ATH9K_CAP_PHYDIAG,
413#define EEP_RFSILENT_ENABLED_S 0 160 ATH9K_CAP_MCAST_KEYSRCH,
414#define EEP_RFSILENT_POLARITY 0x0002 161 ATH9K_CAP_TSF_ADJUST,
415#define EEP_RFSILENT_POLARITY_S 1 162 ATH9K_CAP_WME_TKIPMIC,
416#define EEP_RFSILENT_GPIO_SEL 0x001c 163 ATH9K_CAP_RFSILENT,
417#define EEP_RFSILENT_GPIO_SEL_S 2 164 ATH9K_CAP_ANT_CFG_2GHZ,
418 165 ATH9K_CAP_ANT_CFG_5GHZ
419#define AR5416_EEP_NO_BACK_VER 0x1
420#define AR5416_EEP_VER 0xE
421#define AR5416_EEP_VER_MINOR_MASK 0x0FFF
422#define AR5416_EEP_MINOR_VER_2 0x2
423#define AR5416_EEP_MINOR_VER_3 0x3
424#define AR5416_EEP_MINOR_VER_7 0x7
425#define AR5416_EEP_MINOR_VER_9 0x9
426#define AR5416_EEP_MINOR_VER_16 0x10
427#define AR5416_EEP_MINOR_VER_17 0x11
428#define AR5416_EEP_MINOR_VER_19 0x13
429#define AR5416_EEP_MINOR_VER_20 0x14
430
431#define AR5416_NUM_5G_CAL_PIERS 8
432#define AR5416_NUM_2G_CAL_PIERS 4
433#define AR5416_NUM_5G_20_TARGET_POWERS 8
434#define AR5416_NUM_5G_40_TARGET_POWERS 8
435#define AR5416_NUM_2G_CCK_TARGET_POWERS 3
436#define AR5416_NUM_2G_20_TARGET_POWERS 4
437#define AR5416_NUM_2G_40_TARGET_POWERS 4
438#define AR5416_NUM_CTLS 24
439#define AR5416_NUM_BAND_EDGES 8
440#define AR5416_NUM_PD_GAINS 4
441#define AR5416_PD_GAINS_IN_MASK 4
442#define AR5416_PD_GAIN_ICEPTS 5
443#define AR5416_EEPROM_MODAL_SPURS 5
444#define AR5416_MAX_RATE_POWER 63
445#define AR5416_NUM_PDADC_VALUES 128
446#define AR5416_BCHAN_UNUSED 0xFF
447#define AR5416_MAX_PWR_RANGE_IN_HALF_DB 64
448#define AR5416_MAX_CHAINS 3
449#define AR5416_PWR_TABLE_OFFSET -5
450
451/* Rx gain type values */
452#define AR5416_EEP_RXGAIN_23DB_BACKOFF 0
453#define AR5416_EEP_RXGAIN_13DB_BACKOFF 1
454#define AR5416_EEP_RXGAIN_ORIG 2
455
456/* Tx gain type values */
457#define AR5416_EEP_TXGAIN_ORIGINAL 0
458#define AR5416_EEP_TXGAIN_HIGH_POWER 1
459
460#define AR5416_EEP4K_START_LOC 64
461#define AR5416_EEP4K_NUM_2G_CAL_PIERS 3
462#define AR5416_EEP4K_NUM_2G_CCK_TARGET_POWERS 3
463#define AR5416_EEP4K_NUM_2G_20_TARGET_POWERS 3
464#define AR5416_EEP4K_NUM_2G_40_TARGET_POWERS 3
465#define AR5416_EEP4K_NUM_CTLS 12
466#define AR5416_EEP4K_NUM_BAND_EDGES 4
467#define AR5416_EEP4K_NUM_PD_GAINS 2
468#define AR5416_EEP4K_PD_GAINS_IN_MASK 4
469#define AR5416_EEP4K_PD_GAIN_ICEPTS 5
470#define AR5416_EEP4K_MAX_CHAINS 1
471
472enum eeprom_param {
473 EEP_NFTHRESH_5,
474 EEP_NFTHRESH_2,
475 EEP_MAC_MSW,
476 EEP_MAC_MID,
477 EEP_MAC_LSW,
478 EEP_REG_0,
479 EEP_REG_1,
480 EEP_OP_CAP,
481 EEP_OP_MODE,
482 EEP_RF_SILENT,
483 EEP_OB_5,
484 EEP_DB_5,
485 EEP_OB_2,
486 EEP_DB_2,
487 EEP_MINOR_REV,
488 EEP_TX_MASK,
489 EEP_RX_MASK,
490 EEP_RXGAIN_TYPE,
491 EEP_TXGAIN_TYPE,
492 EEP_DAC_HPWR_5G,
493}; 166};
494 167
495enum ar5416_rates { 168struct ath9k_hw_capabilities {
496 rate6mb, rate9mb, rate12mb, rate18mb, 169 u32 hw_caps; /* ATH9K_HW_CAP_* from ath9k_hw_caps */
497 rate24mb, rate36mb, rate48mb, rate54mb, 170 DECLARE_BITMAP(wireless_modes, ATH9K_MODE_MAX); /* ATH9K_MODE_* */
498 rate1l, rate2l, rate2s, rate5_5l, 171 u16 total_queues;
499 rate5_5s, rate11l, rate11s, rateXr, 172 u16 keycache_size;
500 rateHt20_0, rateHt20_1, rateHt20_2, rateHt20_3, 173 u16 low_5ghz_chan, high_5ghz_chan;
501 rateHt20_4, rateHt20_5, rateHt20_6, rateHt20_7, 174 u16 low_2ghz_chan, high_2ghz_chan;
502 rateHt40_0, rateHt40_1, rateHt40_2, rateHt40_3, 175 u16 num_mr_retries;
503 rateHt40_4, rateHt40_5, rateHt40_6, rateHt40_7, 176 u16 rts_aggr_limit;
504 rateDupCck, rateDupOfdm, rateExtCck, rateExtOfdm, 177 u8 tx_chainmask;
505 Ar5416RateSize 178 u8 rx_chainmask;
179 u16 tx_triglevel_max;
180 u16 reg_cap;
181 u8 num_gpio_pins;
182 u8 num_antcfg_2ghz;
183 u8 num_antcfg_5ghz;
506}; 184};
507 185
508enum ath9k_hal_freq_band { 186struct ath9k_ops_config {
509 ATH9K_HAL_FREQ_BAND_5GHZ = 0, 187 int dma_beacon_response_time;
510 ATH9K_HAL_FREQ_BAND_2GHZ = 1 188 int sw_beacon_response_time;
189 int additional_swba_backoff;
190 int ack_6mb;
191 int cwm_ignore_extcca;
192 u8 pcie_powersave_enable;
193 u8 pcie_l1skp_enable;
194 u8 pcie_clock_req;
195 u32 pcie_waen;
196 int pcie_power_reset;
197 u8 pcie_restore;
198 u8 analog_shiftreg;
199 u8 ht_enable;
200 u32 ofdm_trig_low;
201 u32 ofdm_trig_high;
202 u32 cck_trig_high;
203 u32 cck_trig_low;
204 u32 enable_ani;
205 u8 noise_immunity_level;
206 u32 ofdm_weaksignal_det;
207 u32 cck_weaksignal_thr;
208 u8 spur_immunity_level;
209 u8 firstep_level;
210 int8_t rssi_thr_high;
211 int8_t rssi_thr_low;
212 u16 diversity_control;
213 u16 antenna_switch_swap;
214 int serialize_regmode;
215 int intr_mitigation;
216#define SPUR_DISABLE 0
217#define SPUR_ENABLE_IOCTL 1
218#define SPUR_ENABLE_EEPROM 2
219#define AR_EEPROM_MODAL_SPURS 5
220#define AR_SPUR_5413_1 1640
221#define AR_SPUR_5413_2 1200
222#define AR_NO_SPUR 0x8000
223#define AR_BASE_FREQ_2GHZ 2300
224#define AR_BASE_FREQ_5GHZ 4900
225#define AR_SPUR_FEEQ_BOUND_HT40 19
226#define AR_SPUR_FEEQ_BOUND_HT20 10
227 int spurmode;
228 u16 spurchans[AR_EEPROM_MODAL_SPURS][2];
511}; 229};
512 230
513struct base_eep_header { 231enum ath9k_int {
514 u16 length; 232 ATH9K_INT_RX = 0x00000001,
515 u16 checksum; 233 ATH9K_INT_RXDESC = 0x00000002,
516 u16 version; 234 ATH9K_INT_RXNOFRM = 0x00000008,
517 u8 opCapFlags; 235 ATH9K_INT_RXEOL = 0x00000010,
518 u8 eepMisc; 236 ATH9K_INT_RXORN = 0x00000020,
519 u16 regDmn[2]; 237 ATH9K_INT_TX = 0x00000040,
520 u8 macAddr[6]; 238 ATH9K_INT_TXDESC = 0x00000080,
521 u8 rxMask; 239 ATH9K_INT_TIM_TIMER = 0x00000100,
522 u8 txMask; 240 ATH9K_INT_TXURN = 0x00000800,
523 u16 rfSilent; 241 ATH9K_INT_MIB = 0x00001000,
524 u16 blueToothOptions; 242 ATH9K_INT_RXPHY = 0x00004000,
525 u16 deviceCap; 243 ATH9K_INT_RXKCM = 0x00008000,
526 u32 binBuildNumber; 244 ATH9K_INT_SWBA = 0x00010000,
527 u8 deviceType; 245 ATH9K_INT_BMISS = 0x00040000,
528 u8 pwdclkind; 246 ATH9K_INT_BNR = 0x00100000,
529 u8 futureBase_1[2]; 247 ATH9K_INT_TIM = 0x00200000,
530 u8 rxGainType; 248 ATH9K_INT_DTIM = 0x00400000,
531 u8 dacHiPwrMode_5G; 249 ATH9K_INT_DTIMSYNC = 0x00800000,
532 u8 futureBase_2; 250 ATH9K_INT_GPIO = 0x01000000,
533 u8 dacLpMode; 251 ATH9K_INT_CABEND = 0x02000000,
534 u8 txGainType; 252 ATH9K_INT_CST = 0x10000000,
535 u8 rcChainMask; 253 ATH9K_INT_GTT = 0x20000000,
536 u8 desiredScaleCCK; 254 ATH9K_INT_FATAL = 0x40000000,
537 u8 futureBase_3[23]; 255 ATH9K_INT_GLOBAL = 0x80000000,
538} __packed; 256 ATH9K_INT_BMISC = ATH9K_INT_TIM |
539 257 ATH9K_INT_DTIM |
540struct base_eep_header_4k { 258 ATH9K_INT_DTIMSYNC |
541 u16 length; 259 ATH9K_INT_CABEND,
542 u16 checksum; 260 ATH9K_INT_COMMON = ATH9K_INT_RXNOFRM |
543 u16 version; 261 ATH9K_INT_RXDESC |
544 u8 opCapFlags; 262 ATH9K_INT_RXEOL |
545 u8 eepMisc; 263 ATH9K_INT_RXORN |
546 u16 regDmn[2]; 264 ATH9K_INT_TXURN |
547 u8 macAddr[6]; 265 ATH9K_INT_TXDESC |
548 u8 rxMask; 266 ATH9K_INT_MIB |
549 u8 txMask; 267 ATH9K_INT_RXPHY |
550 u16 rfSilent; 268 ATH9K_INT_RXKCM |
551 u16 blueToothOptions; 269 ATH9K_INT_SWBA |
552 u16 deviceCap; 270 ATH9K_INT_BMISS |
553 u32 binBuildNumber; 271 ATH9K_INT_GPIO,
554 u8 deviceType; 272 ATH9K_INT_NOCARD = 0xffffffff
555 u8 futureBase[1];
556} __packed;
557
558
559struct spur_chan {
560 u16 spurChan;
561 u8 spurRangeLow;
562 u8 spurRangeHigh;
563} __packed;
564
565struct modal_eep_header {
566 u32 antCtrlChain[AR5416_MAX_CHAINS];
567 u32 antCtrlCommon;
568 u8 antennaGainCh[AR5416_MAX_CHAINS];
569 u8 switchSettling;
570 u8 txRxAttenCh[AR5416_MAX_CHAINS];
571 u8 rxTxMarginCh[AR5416_MAX_CHAINS];
572 u8 adcDesiredSize;
573 u8 pgaDesiredSize;
574 u8 xlnaGainCh[AR5416_MAX_CHAINS];
575 u8 txEndToXpaOff;
576 u8 txEndToRxOn;
577 u8 txFrameToXpaOn;
578 u8 thresh62;
579 u8 noiseFloorThreshCh[AR5416_MAX_CHAINS];
580 u8 xpdGain;
581 u8 xpd;
582 u8 iqCalICh[AR5416_MAX_CHAINS];
583 u8 iqCalQCh[AR5416_MAX_CHAINS];
584 u8 pdGainOverlap;
585 u8 ob;
586 u8 db;
587 u8 xpaBiasLvl;
588 u8 pwrDecreaseFor2Chain;
589 u8 pwrDecreaseFor3Chain;
590 u8 txFrameToDataStart;
591 u8 txFrameToPaOn;
592 u8 ht40PowerIncForPdadc;
593 u8 bswAtten[AR5416_MAX_CHAINS];
594 u8 bswMargin[AR5416_MAX_CHAINS];
595 u8 swSettleHt40;
596 u8 xatten2Db[AR5416_MAX_CHAINS];
597 u8 xatten2Margin[AR5416_MAX_CHAINS];
598 u8 ob_ch1;
599 u8 db_ch1;
600 u8 useAnt1:1,
601 force_xpaon:1,
602 local_bias:1,
603 femBandSelectUsed:1, xlnabufin:1, xlnaisel:2, xlnabufmode:1;
604 u8 miscBits;
605 u16 xpaBiasLvlFreq[3];
606 u8 futureModal[6];
607
608 struct spur_chan spurChans[AR5416_EEPROM_MODAL_SPURS];
609} __packed;
610
611struct modal_eep_4k_header {
612 u32 antCtrlChain[AR5416_EEP4K_MAX_CHAINS];
613 u32 antCtrlCommon;
614 u8 antennaGainCh[AR5416_EEP4K_MAX_CHAINS];
615 u8 switchSettling;
616 u8 txRxAttenCh[AR5416_EEP4K_MAX_CHAINS];
617 u8 rxTxMarginCh[AR5416_EEP4K_MAX_CHAINS];
618 u8 adcDesiredSize;
619 u8 pgaDesiredSize;
620 u8 xlnaGainCh[AR5416_EEP4K_MAX_CHAINS];
621 u8 txEndToXpaOff;
622 u8 txEndToRxOn;
623 u8 txFrameToXpaOn;
624 u8 thresh62;
625 u8 noiseFloorThreshCh[AR5416_EEP4K_MAX_CHAINS];
626 u8 xpdGain;
627 u8 xpd;
628 u8 iqCalICh[AR5416_EEP4K_MAX_CHAINS];
629 u8 iqCalQCh[AR5416_EEP4K_MAX_CHAINS];
630 u8 pdGainOverlap;
631 u8 ob_01;
632 u8 db1_01;
633 u8 xpaBiasLvl;
634 u8 txFrameToDataStart;
635 u8 txFrameToPaOn;
636 u8 ht40PowerIncForPdadc;
637 u8 bswAtten[AR5416_EEP4K_MAX_CHAINS];
638 u8 bswMargin[AR5416_EEP4K_MAX_CHAINS];
639 u8 swSettleHt40;
640 u8 xatten2Db[AR5416_EEP4K_MAX_CHAINS];
641 u8 xatten2Margin[AR5416_EEP4K_MAX_CHAINS];
642 u8 db2_01;
643 u8 version;
644 u16 ob_234;
645 u16 db1_234;
646 u16 db2_234;
647 u8 futureModal[4];
648
649 struct spur_chan spurChans[AR5416_EEPROM_MODAL_SPURS];
650} __packed;
651
652
653struct cal_data_per_freq {
654 u8 pwrPdg[AR5416_NUM_PD_GAINS][AR5416_PD_GAIN_ICEPTS];
655 u8 vpdPdg[AR5416_NUM_PD_GAINS][AR5416_PD_GAIN_ICEPTS];
656} __packed;
657
658struct cal_data_per_freq_4k {
659 u8 pwrPdg[AR5416_EEP4K_NUM_PD_GAINS][AR5416_EEP4K_PD_GAIN_ICEPTS];
660 u8 vpdPdg[AR5416_EEP4K_NUM_PD_GAINS][AR5416_EEP4K_PD_GAIN_ICEPTS];
661} __packed;
662
663struct cal_target_power_leg {
664 u8 bChannel;
665 u8 tPow2x[4];
666} __packed;
667
668struct cal_target_power_ht {
669 u8 bChannel;
670 u8 tPow2x[8];
671} __packed;
672
673
674#ifdef __BIG_ENDIAN_BITFIELD
675struct cal_ctl_edges {
676 u8 bChannel;
677 u8 flag:2, tPower:6;
678} __packed;
679#else
680struct cal_ctl_edges {
681 u8 bChannel;
682 u8 tPower:6, flag:2;
683} __packed;
684#endif
685
686struct cal_ctl_data {
687 struct cal_ctl_edges
688 ctlEdges[AR5416_MAX_CHAINS][AR5416_NUM_BAND_EDGES];
689} __packed;
690
691struct cal_ctl_data_4k {
692 struct cal_ctl_edges
693 ctlEdges[AR5416_EEP4K_MAX_CHAINS][AR5416_EEP4K_NUM_BAND_EDGES];
694} __packed;
695
696struct ar5416_eeprom_def {
697 struct base_eep_header baseEepHeader;
698 u8 custData[64];
699 struct modal_eep_header modalHeader[2];
700 u8 calFreqPier5G[AR5416_NUM_5G_CAL_PIERS];
701 u8 calFreqPier2G[AR5416_NUM_2G_CAL_PIERS];
702 struct cal_data_per_freq
703 calPierData5G[AR5416_MAX_CHAINS][AR5416_NUM_5G_CAL_PIERS];
704 struct cal_data_per_freq
705 calPierData2G[AR5416_MAX_CHAINS][AR5416_NUM_2G_CAL_PIERS];
706 struct cal_target_power_leg
707 calTargetPower5G[AR5416_NUM_5G_20_TARGET_POWERS];
708 struct cal_target_power_ht
709 calTargetPower5GHT20[AR5416_NUM_5G_20_TARGET_POWERS];
710 struct cal_target_power_ht
711 calTargetPower5GHT40[AR5416_NUM_5G_40_TARGET_POWERS];
712 struct cal_target_power_leg
713 calTargetPowerCck[AR5416_NUM_2G_CCK_TARGET_POWERS];
714 struct cal_target_power_leg
715 calTargetPower2G[AR5416_NUM_2G_20_TARGET_POWERS];
716 struct cal_target_power_ht
717 calTargetPower2GHT20[AR5416_NUM_2G_20_TARGET_POWERS];
718 struct cal_target_power_ht
719 calTargetPower2GHT40[AR5416_NUM_2G_40_TARGET_POWERS];
720 u8 ctlIndex[AR5416_NUM_CTLS];
721 struct cal_ctl_data ctlData[AR5416_NUM_CTLS];
722 u8 padding;
723} __packed;
724
725struct ar5416_eeprom_4k {
726 struct base_eep_header_4k baseEepHeader;
727 u8 custData[20];
728 struct modal_eep_4k_header modalHeader;
729 u8 calFreqPier2G[AR5416_EEP4K_NUM_2G_CAL_PIERS];
730 struct cal_data_per_freq_4k
731 calPierData2G[AR5416_EEP4K_MAX_CHAINS][AR5416_EEP4K_NUM_2G_CAL_PIERS];
732 struct cal_target_power_leg
733 calTargetPowerCck[AR5416_EEP4K_NUM_2G_CCK_TARGET_POWERS];
734 struct cal_target_power_leg
735 calTargetPower2G[AR5416_EEP4K_NUM_2G_20_TARGET_POWERS];
736 struct cal_target_power_ht
737 calTargetPower2GHT20[AR5416_EEP4K_NUM_2G_20_TARGET_POWERS];
738 struct cal_target_power_ht
739 calTargetPower2GHT40[AR5416_EEP4K_NUM_2G_40_TARGET_POWERS];
740 u8 ctlIndex[AR5416_EEP4K_NUM_CTLS];
741 struct cal_ctl_data_4k ctlData[AR5416_EEP4K_NUM_CTLS];
742 u8 padding;
743} __packed;
744
745struct ar5416IniArray {
746 u32 *ia_array;
747 u32 ia_rows;
748 u32 ia_columns;
749}; 273};
750 274
751#define INIT_INI_ARRAY(iniarray, array, rows, columns) do { \ 275#define CHANNEL_CW_INT 0x00002
752 (iniarray)->ia_array = (u32 *)(array); \ 276#define CHANNEL_CCK 0x00020
753 (iniarray)->ia_rows = (rows); \ 277#define CHANNEL_OFDM 0x00040
754 (iniarray)->ia_columns = (columns); \ 278#define CHANNEL_2GHZ 0x00080
755 } while (0) 279#define CHANNEL_5GHZ 0x00100
756 280#define CHANNEL_PASSIVE 0x00200
757#define INI_RA(iniarray, row, column) \ 281#define CHANNEL_DYN 0x00400
758 (((iniarray)->ia_array)[(row) * ((iniarray)->ia_columns) + (column)]) 282#define CHANNEL_HALF 0x04000
283#define CHANNEL_QUARTER 0x08000
284#define CHANNEL_HT20 0x10000
285#define CHANNEL_HT40PLUS 0x20000
286#define CHANNEL_HT40MINUS 0x40000
287
288#define CHANNEL_INTERFERENCE 0x01
289#define CHANNEL_DFS 0x02
290#define CHANNEL_4MS_LIMIT 0x04
291#define CHANNEL_DFS_CLEAR 0x08
292#define CHANNEL_DISALLOW_ADHOC 0x10
293#define CHANNEL_PER_11D_ADHOC 0x20
294
295#define CHANNEL_A (CHANNEL_5GHZ|CHANNEL_OFDM)
296#define CHANNEL_B (CHANNEL_2GHZ|CHANNEL_CCK)
297#define CHANNEL_G (CHANNEL_2GHZ|CHANNEL_OFDM)
298#define CHANNEL_G_HT20 (CHANNEL_2GHZ|CHANNEL_HT20)
299#define CHANNEL_A_HT20 (CHANNEL_5GHZ|CHANNEL_HT20)
300#define CHANNEL_G_HT40PLUS (CHANNEL_2GHZ|CHANNEL_HT40PLUS)
301#define CHANNEL_G_HT40MINUS (CHANNEL_2GHZ|CHANNEL_HT40MINUS)
302#define CHANNEL_A_HT40PLUS (CHANNEL_5GHZ|CHANNEL_HT40PLUS)
303#define CHANNEL_A_HT40MINUS (CHANNEL_5GHZ|CHANNEL_HT40MINUS)
304#define CHANNEL_ALL \
305 (CHANNEL_OFDM| \
306 CHANNEL_CCK| \
307 CHANNEL_2GHZ | \
308 CHANNEL_5GHZ | \
309 CHANNEL_HT20 | \
310 CHANNEL_HT40PLUS | \
311 CHANNEL_HT40MINUS)
312
313struct ath9k_channel {
314 struct ieee80211_channel *chan;
315 u16 channel;
316 u32 channelFlags;
317 u32 chanmode;
318 int32_t CalValid;
319 bool oneTimeCalsDone;
320 int8_t iCoff;
321 int8_t qCoff;
322 int16_t rawNoiseFloor;
323};
759 324
760#define INIT_CAL(_perCal) do { \ 325#define IS_CHAN_A(_c) ((((_c)->channelFlags & CHANNEL_A) == CHANNEL_A) || \
761 (_perCal)->calState = CAL_WAITING; \ 326 (((_c)->channelFlags & CHANNEL_A_HT20) == CHANNEL_A_HT20) || \
762 (_perCal)->calNext = NULL; \ 327 (((_c)->channelFlags & CHANNEL_A_HT40PLUS) == CHANNEL_A_HT40PLUS) || \
763 } while (0) 328 (((_c)->channelFlags & CHANNEL_A_HT40MINUS) == CHANNEL_A_HT40MINUS))
329#define IS_CHAN_G(_c) ((((_c)->channelFlags & (CHANNEL_G)) == CHANNEL_G) || \
330 (((_c)->channelFlags & CHANNEL_G_HT20) == CHANNEL_G_HT20) || \
331 (((_c)->channelFlags & CHANNEL_G_HT40PLUS) == CHANNEL_G_HT40PLUS) || \
332 (((_c)->channelFlags & CHANNEL_G_HT40MINUS) == CHANNEL_G_HT40MINUS))
333#define IS_CHAN_OFDM(_c) (((_c)->channelFlags & CHANNEL_OFDM) != 0)
334#define IS_CHAN_5GHZ(_c) (((_c)->channelFlags & CHANNEL_5GHZ) != 0)
335#define IS_CHAN_2GHZ(_c) (((_c)->channelFlags & CHANNEL_2GHZ) != 0)
336#define IS_CHAN_PASSIVE(_c) (((_c)->channelFlags & CHANNEL_PASSIVE) != 0)
337#define IS_CHAN_HALF_RATE(_c) (((_c)->channelFlags & CHANNEL_HALF) != 0)
338#define IS_CHAN_QUARTER_RATE(_c) (((_c)->channelFlags & CHANNEL_QUARTER) != 0)
339#define IS_CHAN_A_5MHZ_SPACED(_c) \
340 ((((_c)->channelFlags & CHANNEL_5GHZ) != 0) && \
341 (((_c)->channel % 20) != 0) && \
342 (((_c)->channel % 10) != 0))
343
344/* These macros check chanmode and not channelFlags */
345#define IS_CHAN_B(_c) ((_c)->chanmode == CHANNEL_B)
346#define IS_CHAN_HT20(_c) (((_c)->chanmode == CHANNEL_A_HT20) || \
347 ((_c)->chanmode == CHANNEL_G_HT20))
348#define IS_CHAN_HT40(_c) (((_c)->chanmode == CHANNEL_A_HT40PLUS) || \
349 ((_c)->chanmode == CHANNEL_A_HT40MINUS) || \
350 ((_c)->chanmode == CHANNEL_G_HT40PLUS) || \
351 ((_c)->chanmode == CHANNEL_G_HT40MINUS))
352#define IS_CHAN_HT(_c) (IS_CHAN_HT20((_c)) || IS_CHAN_HT40((_c)))
353
354enum ath9k_power_mode {
355 ATH9K_PM_AWAKE = 0,
356 ATH9K_PM_FULL_SLEEP,
357 ATH9K_PM_NETWORK_SLEEP,
358 ATH9K_PM_UNDEFINED
359};
764 360
765#define INSERT_CAL(_ahp, _perCal) \ 361enum ath9k_ant_setting {
766 do { \ 362 ATH9K_ANT_VARIABLE = 0,
767 if ((_ahp)->ah_cal_list_last == NULL) { \ 363 ATH9K_ANT_FIXED_A,
768 (_ahp)->ah_cal_list = \ 364 ATH9K_ANT_FIXED_B
769 (_ahp)->ah_cal_list_last = (_perCal); \ 365};
770 ((_ahp)->ah_cal_list_last)->calNext = (_perCal); \
771 } else { \
772 ((_ahp)->ah_cal_list_last)->calNext = (_perCal); \
773 (_ahp)->ah_cal_list_last = (_perCal); \
774 (_perCal)->calNext = (_ahp)->ah_cal_list; \
775 } \
776 } while (0)
777 366
778enum hal_cal_types { 367enum ath9k_tp_scale {
779 ADC_DC_INIT_CAL = 0x1, 368 ATH9K_TP_SCALE_MAX = 0,
780 ADC_GAIN_CAL = 0x2, 369 ATH9K_TP_SCALE_50,
781 ADC_DC_CAL = 0x4, 370 ATH9K_TP_SCALE_25,
782 IQ_MISMATCH_CAL = 0x8 371 ATH9K_TP_SCALE_12,
372 ATH9K_TP_SCALE_MIN
783}; 373};
784 374
785enum hal_cal_state { 375enum ser_reg_mode {
786 CAL_INACTIVE, 376 SER_REG_MODE_OFF = 0,
787 CAL_WAITING, 377 SER_REG_MODE_ON = 1,
788 CAL_RUNNING, 378 SER_REG_MODE_AUTO = 2,
789 CAL_DONE
790}; 379};
791 380
792#define MIN_CAL_SAMPLES 1 381struct ath9k_beacon_state {
793#define MAX_CAL_SAMPLES 64 382 u32 bs_nexttbtt;
794#define INIT_LOG_COUNT 5 383 u32 bs_nextdtim;
795#define PER_MIN_LOG_COUNT 2 384 u32 bs_intval;
796#define PER_MAX_LOG_COUNT 10 385#define ATH9K_BEACON_PERIOD 0x0000ffff
386#define ATH9K_BEACON_ENA 0x00800000
387#define ATH9K_BEACON_RESET_TSF 0x01000000
388 u32 bs_dtimperiod;
389 u16 bs_cfpperiod;
390 u16 bs_cfpmaxduration;
391 u32 bs_cfpnext;
392 u16 bs_timoffset;
393 u16 bs_bmissthreshold;
394 u32 bs_sleepduration;
395};
797 396
798struct hal_percal_data { 397struct chan_centers {
799 enum hal_cal_types calType; 398 u16 synth_center;
800 u32 calNumSamples; 399 u16 ctl_center;
801 u32 calCountMax; 400 u16 ext_center;
802 void (*calCollect) (struct ath_hal *);
803 void (*calPostProc) (struct ath_hal *, u8);
804}; 401};
805 402
806struct hal_cal_list { 403enum {
807 const struct hal_percal_data *calData; 404 ATH9K_RESET_POWER_ON,
808 enum hal_cal_state calState; 405 ATH9K_RESET_WARM,
809 struct hal_cal_list *calNext; 406 ATH9K_RESET_COLD,
810}; 407};
811 408
812/* 409struct ath9k_hw_version {
813 * Enum to indentify the eeprom mappings 410 u32 magic;
814 */ 411 u16 devid;
815enum hal_eep_map { 412 u16 subvendorid;
816 EEP_MAP_DEFAULT = 0x0, 413 u32 macVersion;
817 EEP_MAP_4KBITS, 414 u16 macRev;
818 EEP_MAP_MAX 415 u16 phyRev;
416 u16 analog5GhzRev;
417 u16 analog2GhzRev;
819}; 418};
820 419
420struct ath_hw {
421 struct ath_softc *ah_sc;
422 struct ath9k_hw_version hw_version;
423 struct ath9k_ops_config config;
424 struct ath9k_hw_capabilities caps;
425 struct ath9k_regulatory regulatory;
426 struct ath9k_channel channels[38];
427 struct ath9k_channel *curchan;
821 428
822struct ath_hal_5416 {
823 struct ath_hal ah;
824 union { 429 union {
825 struct ar5416_eeprom_def def; 430 struct ar5416_eeprom_def def;
826 struct ar5416_eeprom_4k map4k; 431 struct ar5416_eeprom_4k map4k;
827 } ah_eeprom; 432 } eeprom;
828 struct ar5416Stats ah_stats; 433 const struct eeprom_ops *eep_ops;
829 struct ath9k_tx_queue_info ah_txq[ATH9K_NUM_TX_QUEUES]; 434 enum ath9k_eep_map eep_map;
830 void __iomem *ah_cal_mem; 435
831 436 bool sw_mgmt_crypto;
832 u8 ah_macaddr[ETH_ALEN]; 437 bool is_pciexpress;
833 u8 ah_bssid[ETH_ALEN]; 438 u8 macaddr[ETH_ALEN];
834 u8 ah_bssidmask[ETH_ALEN]; 439 u16 tx_trig_level;
835 u16 ah_assocId; 440 u16 rfsilent;
836 441 u32 rfkill_gpio;
837 int16_t ah_curchanRadIndex; 442 u32 rfkill_polarity;
838 u32 ah_maskReg; 443 u32 btactive_gpio;
839 u32 ah_txOkInterruptMask; 444 u32 wlanactive_gpio;
840 u32 ah_txErrInterruptMask; 445 u32 ah_flags;
841 u32 ah_txDescInterruptMask; 446
842 u32 ah_txEolInterruptMask; 447 enum nl80211_iftype opmode;
843 u32 ah_txUrnInterruptMask; 448 enum ath9k_power_mode power_mode;
844 bool ah_chipFullSleep; 449 enum ath9k_power_mode restore_mode;
845 u32 ah_atimWindow; 450
846 u16 ah_antennaSwitchSwap; 451 struct ath9k_nfcal_hist nfCalHist[NUM_NF_READINGS];
847 enum ath9k_ant_setting ah_diversityControl; 452 struct ar5416Stats stats;
453 struct ath9k_tx_queue_info txq[ATH9K_NUM_TX_QUEUES];
454
455 int16_t curchan_rad_index;
456 u32 mask_reg;
457 u32 txok_interrupt_mask;
458 u32 txerr_interrupt_mask;
459 u32 txdesc_interrupt_mask;
460 u32 txeol_interrupt_mask;
461 u32 txurn_interrupt_mask;
462 bool chip_fullsleep;
463 u32 atim_window;
464 u16 antenna_switch_swap;
465 enum ath9k_ant_setting diversity_control;
848 466
849 /* Calibration */ 467 /* Calibration */
850 enum hal_cal_types ah_suppCals; 468 enum hal_cal_types supp_cals;
851 struct hal_cal_list ah_iqCalData; 469 struct hal_cal_list iq_caldata;
852 struct hal_cal_list ah_adcGainCalData; 470 struct hal_cal_list adcgain_caldata;
853 struct hal_cal_list ah_adcDcCalInitData; 471 struct hal_cal_list adcdc_calinitdata;
854 struct hal_cal_list ah_adcDcCalData; 472 struct hal_cal_list adcdc_caldata;
855 struct hal_cal_list *ah_cal_list; 473 struct hal_cal_list *cal_list;
856 struct hal_cal_list *ah_cal_list_last; 474 struct hal_cal_list *cal_list_last;
857 struct hal_cal_list *ah_cal_list_curr; 475 struct hal_cal_list *cal_list_curr;
858#define ah_totalPowerMeasI ah_Meas0.unsign 476#define totalPowerMeasI meas0.unsign
859#define ah_totalPowerMeasQ ah_Meas1.unsign 477#define totalPowerMeasQ meas1.unsign
860#define ah_totalIqCorrMeas ah_Meas2.sign 478#define totalIqCorrMeas meas2.sign
861#define ah_totalAdcIOddPhase ah_Meas0.unsign 479#define totalAdcIOddPhase meas0.unsign
862#define ah_totalAdcIEvenPhase ah_Meas1.unsign 480#define totalAdcIEvenPhase meas1.unsign
863#define ah_totalAdcQOddPhase ah_Meas2.unsign 481#define totalAdcQOddPhase meas2.unsign
864#define ah_totalAdcQEvenPhase ah_Meas3.unsign 482#define totalAdcQEvenPhase meas3.unsign
865#define ah_totalAdcDcOffsetIOddPhase ah_Meas0.sign 483#define totalAdcDcOffsetIOddPhase meas0.sign
866#define ah_totalAdcDcOffsetIEvenPhase ah_Meas1.sign 484#define totalAdcDcOffsetIEvenPhase meas1.sign
867#define ah_totalAdcDcOffsetQOddPhase ah_Meas2.sign 485#define totalAdcDcOffsetQOddPhase meas2.sign
868#define ah_totalAdcDcOffsetQEvenPhase ah_Meas3.sign 486#define totalAdcDcOffsetQEvenPhase meas3.sign
869 union { 487 union {
870 u32 unsign[AR5416_MAX_CHAINS]; 488 u32 unsign[AR5416_MAX_CHAINS];
871 int32_t sign[AR5416_MAX_CHAINS]; 489 int32_t sign[AR5416_MAX_CHAINS];
872 } ah_Meas0; 490 } meas0;
873 union { 491 union {
874 u32 unsign[AR5416_MAX_CHAINS]; 492 u32 unsign[AR5416_MAX_CHAINS];
875 int32_t sign[AR5416_MAX_CHAINS]; 493 int32_t sign[AR5416_MAX_CHAINS];
876 } ah_Meas1; 494 } meas1;
877 union { 495 union {
878 u32 unsign[AR5416_MAX_CHAINS]; 496 u32 unsign[AR5416_MAX_CHAINS];
879 int32_t sign[AR5416_MAX_CHAINS]; 497 int32_t sign[AR5416_MAX_CHAINS];
880 } ah_Meas2; 498 } meas2;
881 union { 499 union {
882 u32 unsign[AR5416_MAX_CHAINS]; 500 u32 unsign[AR5416_MAX_CHAINS];
883 int32_t sign[AR5416_MAX_CHAINS]; 501 int32_t sign[AR5416_MAX_CHAINS];
884 } ah_Meas3; 502 } meas3;
885 u16 ah_CalSamples; 503 u16 cal_samples;
886 504
887 u32 ah_staId1Defaults; 505 u32 sta_id1_defaults;
888 u32 ah_miscMode; 506 u32 misc_mode;
889 enum { 507 enum {
890 AUTO_32KHZ, 508 AUTO_32KHZ,
891 USE_32KHZ, 509 USE_32KHZ,
892 DONT_USE_32KHZ, 510 DONT_USE_32KHZ,
893 } ah_enable32kHzClock; 511 } enable_32kHz_clock;
894 512
895 /* RF */ 513 /* RF */
896 u32 *ah_analogBank0Data; 514 u32 *analogBank0Data;
897 u32 *ah_analogBank1Data; 515 u32 *analogBank1Data;
898 u32 *ah_analogBank2Data; 516 u32 *analogBank2Data;
899 u32 *ah_analogBank3Data; 517 u32 *analogBank3Data;
900 u32 *ah_analogBank6Data; 518 u32 *analogBank6Data;
901 u32 *ah_analogBank6TPCData; 519 u32 *analogBank6TPCData;
902 u32 *ah_analogBank7Data; 520 u32 *analogBank7Data;
903 u32 *ah_addac5416_21; 521 u32 *addac5416_21;
904 u32 *ah_bank6Temp; 522 u32 *bank6Temp;
905 523
906 int16_t ah_txPowerIndexOffset; 524 int16_t txpower_indexoffset;
907 u32 ah_beaconInterval; 525 u32 beacon_interval;
908 u32 ah_slottime; 526 u32 slottime;
909 u32 ah_acktimeout; 527 u32 acktimeout;
910 u32 ah_ctstimeout; 528 u32 ctstimeout;
911 u32 ah_globaltxtimeout; 529 u32 globaltxtimeout;
912 u8 ah_gBeaconRate; 530 u8 gbeacon_rate;
913 u32 ah_gpioSelect;
914 u32 ah_polarity;
915 u32 ah_gpioBit;
916 531
917 /* ANI */ 532 /* ANI */
918 u32 ah_procPhyErr; 533 u32 proc_phyerr;
919 bool ah_hasHwPhyCounters; 534 bool has_hw_phycounters;
920 u32 ah_aniPeriod; 535 u32 aniperiod;
921 struct ar5416AniState *ah_curani; 536 struct ar5416AniState *curani;
922 struct ar5416AniState ah_ani[255]; 537 struct ar5416AniState ani[255];
923 int ah_totalSizeDesired[5]; 538 int totalSizeDesired[5];
924 int ah_coarseHigh[5]; 539 int coarse_high[5];
925 int ah_coarseLow[5]; 540 int coarse_low[5];
926 int ah_firpwr[5]; 541 int firpwr[5];
927 enum ath9k_ani_cmd ah_ani_function; 542 enum ath9k_ani_cmd ani_function;
928 543
929 u32 ah_intrTxqs; 544 u32 intr_txqs;
930 bool ah_intrMitigation; 545 bool intr_mitigation;
931 enum ath9k_ht_extprotspacing ah_extprotspacing; 546 enum ath9k_ht_extprotspacing extprotspacing;
932 u8 ah_txchainmask; 547 u8 txchainmask;
933 u8 ah_rxchainmask; 548 u8 rxchainmask;
934 549
935 struct ar5416IniArray ah_iniModes; 550 struct ar5416IniArray iniModes;
936 struct ar5416IniArray ah_iniCommon; 551 struct ar5416IniArray iniCommon;
937 struct ar5416IniArray ah_iniBank0; 552 struct ar5416IniArray iniBank0;
938 struct ar5416IniArray ah_iniBB_RfGain; 553 struct ar5416IniArray iniBB_RfGain;
939 struct ar5416IniArray ah_iniBank1; 554 struct ar5416IniArray iniBank1;
940 struct ar5416IniArray ah_iniBank2; 555 struct ar5416IniArray iniBank2;
941 struct ar5416IniArray ah_iniBank3; 556 struct ar5416IniArray iniBank3;
942 struct ar5416IniArray ah_iniBank6; 557 struct ar5416IniArray iniBank6;
943 struct ar5416IniArray ah_iniBank6TPC; 558 struct ar5416IniArray iniBank6TPC;
944 struct ar5416IniArray ah_iniBank7; 559 struct ar5416IniArray iniBank7;
945 struct ar5416IniArray ah_iniAddac; 560 struct ar5416IniArray iniAddac;
946 struct ar5416IniArray ah_iniPcieSerdes; 561 struct ar5416IniArray iniPcieSerdes;
947 struct ar5416IniArray ah_iniModesAdditional; 562 struct ar5416IniArray iniModesAdditional;
948 struct ar5416IniArray ah_iniModesRxGain; 563 struct ar5416IniArray iniModesRxGain;
949 struct ar5416IniArray ah_iniModesTxGain; 564 struct ar5416IniArray iniModesTxGain;
950 /* To indicate EEPROM mapping used */
951 enum hal_eep_map ah_eep_map;
952}; 565};
953#define AH5416(_ah) ((struct ath_hal_5416 *)(_ah))
954
955#define FREQ2FBIN(x, y) ((y) ? ((x) - 2300) : (((x) - 4800) / 5))
956
957#define ar5416RfDetach(ah) do { \
958 if (AH5416(ah)->ah_rfHal.rfDetach != NULL) \
959 AH5416(ah)->ah_rfHal.rfDetach(ah); \
960 } while (0)
961
962#define ath9k_hw_use_flash(_ah) \
963 (!(_ah->ah_flags & AH_USE_EEPROM))
964
965
966#define DO_DELAY(x) do { \
967 if ((++(x) % 64) == 0) \
968 udelay(1); \
969 } while (0)
970
971#define REG_WRITE_ARRAY(iniarray, column, regWr) do { \
972 int r; \
973 for (r = 0; r < ((iniarray)->ia_rows); r++) { \
974 REG_WRITE(ah, INI_RA((iniarray), (r), 0), \
975 INI_RA((iniarray), r, (column))); \
976 DO_DELAY(regWr); \
977 } \
978 } while (0)
979
980#define BASE_ACTIVATE_DELAY 100
981#define RTC_PLL_SETTLE_DELAY 1000
982#define COEF_SCALE_S 24
983#define HT40_CHANNEL_CENTER_SHIFT 10
984
985#define AR5416_EEPROM_MAGIC_OFFSET 0x0
986
987#define AR5416_EEPROM_S 2
988#define AR5416_EEPROM_OFFSET 0x2000
989#define AR5416_EEPROM_START_ADDR \
990 (AR_SREV_9100(ah)) ? 0x1fff1000 : 0x503f1200
991#define AR5416_EEPROM_MAX 0xae0
992#define ar5416_get_eep_ver(_ahp) \
993 (((_ahp)->ah_eeprom.def.baseEepHeader.version >> 12) & 0xF)
994#define ar5416_get_eep_rev(_ahp) \
995 (((_ahp)->ah_eeprom.def.baseEepHeader.version) & 0xFFF)
996#define ar5416_get_ntxchains(_txchainmask) \
997 (((_txchainmask >> 2) & 1) + \
998 ((_txchainmask >> 1) & 1) + (_txchainmask & 1))
999 566
1000/* EEPROM 4K bit map definations */ 567/* Attach, Detach, Reset */
1001#define ar5416_get_eep4k_ver(_ahp) \ 568const char *ath9k_hw_probe(u16 vendorid, u16 devid);
1002 (((_ahp)->ah_eeprom.map4k.baseEepHeader.version >> 12) & 0xF) 569void ath9k_hw_detach(struct ath_hw *ah);
1003#define ar5416_get_eep4k_rev(_ahp) \ 570struct ath_hw *ath9k_hw_attach(u16 devid, struct ath_softc *sc, int *error);
1004 (((_ahp)->ah_eeprom.map4k.baseEepHeader.version) & 0xFFF) 571void ath9k_hw_rfdetach(struct ath_hw *ah);
1005 572int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
1006 573 bool bChannelChange);
1007#ifdef __BIG_ENDIAN 574bool ath9k_hw_fill_cap_info(struct ath_hw *ah);
1008#define AR5416_EEPROM_MAGIC 0x5aa5 575bool ath9k_hw_getcapability(struct ath_hw *ah, enum ath9k_capability_type type,
1009#else 576 u32 capability, u32 *result);
1010#define AR5416_EEPROM_MAGIC 0xa55a 577bool ath9k_hw_setcapability(struct ath_hw *ah, enum ath9k_capability_type type,
578 u32 capability, u32 setting, int *status);
579
580/* Key Cache Management */
581bool ath9k_hw_keyreset(struct ath_hw *ah, u16 entry);
582bool ath9k_hw_keysetmac(struct ath_hw *ah, u16 entry, const u8 *mac);
583bool ath9k_hw_set_keycache_entry(struct ath_hw *ah, u16 entry,
584 const struct ath9k_keyval *k,
585 const u8 *mac, int xorKey);
586bool ath9k_hw_keyisvalid(struct ath_hw *ah, u16 entry);
587
588/* GPIO / RFKILL / Antennae */
589void ath9k_hw_cfg_gpio_input(struct ath_hw *ah, u32 gpio);
590u32 ath9k_hw_gpio_get(struct ath_hw *ah, u32 gpio);
591void ath9k_hw_cfg_output(struct ath_hw *ah, u32 gpio,
592 u32 ah_signal_type);
593void ath9k_hw_set_gpio(struct ath_hw *ah, u32 gpio, u32 val);
594#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
595void ath9k_enable_rfkill(struct ath_hw *ah);
1011#endif 596#endif
1012 597u32 ath9k_hw_getdefantenna(struct ath_hw *ah);
1013#define ATH9K_POW_SM(_r, _s) (((_r) & 0x3f) << (_s)) 598void ath9k_hw_setantenna(struct ath_hw *ah, u32 antenna);
1014 599bool ath9k_hw_setantennaswitch(struct ath_hw *ah,
1015#define ATH9K_ANTENNA0_CHAINMASK 0x1 600 enum ath9k_ant_setting settings,
1016#define ATH9K_ANTENNA1_CHAINMASK 0x2 601 struct ath9k_channel *chan,
1017 602 u8 *tx_chainmask, u8 *rx_chainmask,
1018#define ATH9K_NUM_DMA_DEBUG_REGS 8 603 u8 *antenna_cfgd);
1019#define ATH9K_NUM_QUEUES 10 604
1020 605/* General Operation */
1021#define HAL_NOISE_IMMUNE_MAX 4 606bool ath9k_hw_wait(struct ath_hw *ah, u32 reg, u32 mask, u32 val);
1022#define HAL_SPUR_IMMUNE_MAX 7 607u32 ath9k_hw_reverse_bits(u32 val, u32 n);
1023#define HAL_FIRST_STEP_MAX 2 608bool ath9k_get_channel_edges(struct ath_hw *ah, u16 flags, u16 *low, u16 *high);
1024 609u16 ath9k_hw_computetxtime(struct ath_hw *ah, struct ath_rate_table *rates,
1025#define ATH9K_ANI_OFDM_TRIG_HIGH 500 610 u32 frameLen, u16 rateix, bool shortPreamble);
1026#define ATH9K_ANI_OFDM_TRIG_LOW 200 611void ath9k_hw_get_channel_centers(struct ath_hw *ah,
1027#define ATH9K_ANI_CCK_TRIG_HIGH 200 612 struct ath9k_channel *chan,
1028#define ATH9K_ANI_CCK_TRIG_LOW 100 613 struct chan_centers *centers);
1029#define ATH9K_ANI_NOISE_IMMUNE_LVL 4 614u32 ath9k_hw_getrxfilter(struct ath_hw *ah);
1030#define ATH9K_ANI_USE_OFDM_WEAK_SIG true 615void ath9k_hw_setrxfilter(struct ath_hw *ah, u32 bits);
1031#define ATH9K_ANI_CCK_WEAK_SIG_THR false 616bool ath9k_hw_phy_disable(struct ath_hw *ah);
1032#define ATH9K_ANI_SPUR_IMMUNE_LVL 7 617bool ath9k_hw_disable(struct ath_hw *ah);
1033#define ATH9K_ANI_FIRSTEP_LVL 0 618bool ath9k_hw_set_txpowerlimit(struct ath_hw *ah, u32 limit);
1034#define ATH9K_ANI_RSSI_THR_HIGH 40 619void ath9k_hw_setmac(struct ath_hw *ah, const u8 *mac);
1035#define ATH9K_ANI_RSSI_THR_LOW 7 620void ath9k_hw_setopmode(struct ath_hw *ah);
1036#define ATH9K_ANI_PERIOD 100 621void ath9k_hw_setmcastfilter(struct ath_hw *ah, u32 filter0, u32 filter1);
1037 622void ath9k_hw_setbssidmask(struct ath_softc *sc);
1038#define AR_GPIOD_MASK 0x00001FFF 623void ath9k_hw_write_associd(struct ath_softc *sc);
1039#define AR_GPIO_BIT(_gpio) (1 << (_gpio)) 624u64 ath9k_hw_gettsf64(struct ath_hw *ah);
1040 625void ath9k_hw_settsf64(struct ath_hw *ah, u64 tsf64);
1041#define HAL_EP_RND(x, mul) \ 626void ath9k_hw_reset_tsf(struct ath_hw *ah);
1042 ((((x)%(mul)) >= ((mul)/2)) ? ((x) + ((mul) - 1)) / (mul) : (x)/(mul)) 627bool ath9k_hw_set_tsfadjust(struct ath_hw *ah, u32 setting);
1043#define BEACON_RSSI(ahp) \ 628bool ath9k_hw_setslottime(struct ath_hw *ah, u32 us);
1044 HAL_EP_RND(ahp->ah_stats.ast_nodestats.ns_avgbrssi, \ 629void ath9k_hw_set11nmac2040(struct ath_hw *ah, enum ath9k_ht_macmode mode);
1045 ATH9K_RSSI_EP_MULTIPLIER) 630void ath9k_hw_beaconinit(struct ath_hw *ah, u32 next_beacon, u32 beacon_period);
1046 631void ath9k_hw_set_sta_beacon_timers(struct ath_hw *ah,
1047#define ah_mibStats ah_stats.ast_mibstats 632 const struct ath9k_beacon_state *bs);
1048 633bool ath9k_hw_setpower(struct ath_hw *ah,
1049#define AH_TIMEOUT 100000 634 enum ath9k_power_mode mode);
1050#define AH_TIME_QUANTUM 10 635void ath9k_hw_configpcipowersave(struct ath_hw *ah, int restore);
1051 636
1052#define AR_KEYTABLE_SIZE 128 637/* Interrupt Handling */
1053#define POWER_UP_TIME 200000 638bool ath9k_hw_intrpend(struct ath_hw *ah);
1054 639bool ath9k_hw_getisr(struct ath_hw *ah, enum ath9k_int *masked);
1055#define EXT_ADDITIVE (0x8000) 640enum ath9k_int ath9k_hw_intrget(struct ath_hw *ah);
1056#define CTL_11A_EXT (CTL_11A | EXT_ADDITIVE) 641enum ath9k_int ath9k_hw_set_interrupts(struct ath_hw *ah, enum ath9k_int ints);
1057#define CTL_11G_EXT (CTL_11G | EXT_ADDITIVE) 642
1058#define CTL_11B_EXT (CTL_11B | EXT_ADDITIVE) 643void ath9k_hw_btcoex_enable(struct ath_hw *ah);
1059
1060#define SUB_NUM_CTL_MODES_AT_5G_40 2
1061#define SUB_NUM_CTL_MODES_AT_2G_40 3
1062#define SPUR_RSSI_THRESH 40
1063
1064#define TU_TO_USEC(_tu) ((_tu) << 10)
1065
1066#define CAB_TIMEOUT_VAL 10
1067#define BEACON_TIMEOUT_VAL 10
1068#define MIN_BEACON_TIMEOUT_VAL 1
1069#define SLEEP_SLOP 3
1070
1071#define CCK_SIFS_TIME 10
1072#define CCK_PREAMBLE_BITS 144
1073#define CCK_PLCP_BITS 48
1074
1075#define OFDM_SIFS_TIME 16
1076#define OFDM_PREAMBLE_TIME 20
1077#define OFDM_PLCP_BITS 22
1078#define OFDM_SYMBOL_TIME 4
1079
1080#define OFDM_SIFS_TIME_HALF 32
1081#define OFDM_PREAMBLE_TIME_HALF 40
1082#define OFDM_PLCP_BITS_HALF 22
1083#define OFDM_SYMBOL_TIME_HALF 8
1084
1085#define OFDM_SIFS_TIME_QUARTER 64
1086#define OFDM_PREAMBLE_TIME_QUARTER 80
1087#define OFDM_PLCP_BITS_QUARTER 22
1088#define OFDM_SYMBOL_TIME_QUARTER 16
1089
1090u32 ath9k_hw_get_eeprom(struct ath_hal *ah,
1091 enum eeprom_param param);
1092 644
1093#endif 645#endif
diff --git a/drivers/net/wireless/ath9k/mac.c b/drivers/net/wireless/ath9k/mac.c
index 2427c44a8c35..f32c622db6e7 100644
--- a/drivers/net/wireless/ath9k/mac.c
+++ b/drivers/net/wireless/ath9k/mac.c
@@ -14,45 +14,40 @@
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */ 15 */
16 16
17#include "core.h" 17#include "ath9k.h"
18#include "hw.h"
19#include "reg.h"
20#include "phy.h"
21 18
22static void ath9k_hw_set_txq_interrupts(struct ath_hal *ah, 19static void ath9k_hw_set_txq_interrupts(struct ath_hw *ah,
23 struct ath9k_tx_queue_info *qi) 20 struct ath9k_tx_queue_info *qi)
24{ 21{
25 struct ath_hal_5416 *ahp = AH5416(ah);
26
27 DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT, 22 DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT,
28 "tx ok 0x%x err 0x%x desc 0x%x eol 0x%x urn 0x%x\n", 23 "tx ok 0x%x err 0x%x desc 0x%x eol 0x%x urn 0x%x\n",
29 ahp->ah_txOkInterruptMask, ahp->ah_txErrInterruptMask, 24 ah->txok_interrupt_mask, ah->txerr_interrupt_mask,
30 ahp->ah_txDescInterruptMask, ahp->ah_txEolInterruptMask, 25 ah->txdesc_interrupt_mask, ah->txeol_interrupt_mask,
31 ahp->ah_txUrnInterruptMask); 26 ah->txurn_interrupt_mask);
32 27
33 REG_WRITE(ah, AR_IMR_S0, 28 REG_WRITE(ah, AR_IMR_S0,
34 SM(ahp->ah_txOkInterruptMask, AR_IMR_S0_QCU_TXOK) 29 SM(ah->txok_interrupt_mask, AR_IMR_S0_QCU_TXOK)
35 | SM(ahp->ah_txDescInterruptMask, AR_IMR_S0_QCU_TXDESC)); 30 | SM(ah->txdesc_interrupt_mask, AR_IMR_S0_QCU_TXDESC));
36 REG_WRITE(ah, AR_IMR_S1, 31 REG_WRITE(ah, AR_IMR_S1,
37 SM(ahp->ah_txErrInterruptMask, AR_IMR_S1_QCU_TXERR) 32 SM(ah->txerr_interrupt_mask, AR_IMR_S1_QCU_TXERR)
38 | SM(ahp->ah_txEolInterruptMask, AR_IMR_S1_QCU_TXEOL)); 33 | SM(ah->txeol_interrupt_mask, AR_IMR_S1_QCU_TXEOL));
39 REG_RMW_FIELD(ah, AR_IMR_S2, 34 REG_RMW_FIELD(ah, AR_IMR_S2,
40 AR_IMR_S2_QCU_TXURN, ahp->ah_txUrnInterruptMask); 35 AR_IMR_S2_QCU_TXURN, ah->txurn_interrupt_mask);
41} 36}
42 37
43u32 ath9k_hw_gettxbuf(struct ath_hal *ah, u32 q) 38u32 ath9k_hw_gettxbuf(struct ath_hw *ah, u32 q)
44{ 39{
45 return REG_READ(ah, AR_QTXDP(q)); 40 return REG_READ(ah, AR_QTXDP(q));
46} 41}
47 42
48bool ath9k_hw_puttxbuf(struct ath_hal *ah, u32 q, u32 txdp) 43bool ath9k_hw_puttxbuf(struct ath_hw *ah, u32 q, u32 txdp)
49{ 44{
50 REG_WRITE(ah, AR_QTXDP(q), txdp); 45 REG_WRITE(ah, AR_QTXDP(q), txdp);
51 46
52 return true; 47 return true;
53} 48}
54 49
55bool ath9k_hw_txstart(struct ath_hal *ah, u32 q) 50bool ath9k_hw_txstart(struct ath_hw *ah, u32 q)
56{ 51{
57 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "queue %u\n", q); 52 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "queue %u\n", q);
58 53
@@ -61,7 +56,7 @@ bool ath9k_hw_txstart(struct ath_hal *ah, u32 q)
61 return true; 56 return true;
62} 57}
63 58
64u32 ath9k_hw_numtxpending(struct ath_hal *ah, u32 q) 59u32 ath9k_hw_numtxpending(struct ath_hw *ah, u32 q)
65{ 60{
66 u32 npend; 61 u32 npend;
67 62
@@ -75,16 +70,15 @@ u32 ath9k_hw_numtxpending(struct ath_hal *ah, u32 q)
75 return npend; 70 return npend;
76} 71}
77 72
78bool ath9k_hw_updatetxtriglevel(struct ath_hal *ah, bool bIncTrigLevel) 73bool ath9k_hw_updatetxtriglevel(struct ath_hw *ah, bool bIncTrigLevel)
79{ 74{
80 struct ath_hal_5416 *ahp = AH5416(ah);
81 u32 txcfg, curLevel, newLevel; 75 u32 txcfg, curLevel, newLevel;
82 enum ath9k_int omask; 76 enum ath9k_int omask;
83 77
84 if (ah->ah_txTrigLevel >= MAX_TX_FIFO_THRESHOLD) 78 if (ah->tx_trig_level >= MAX_TX_FIFO_THRESHOLD)
85 return false; 79 return false;
86 80
87 omask = ath9k_hw_set_interrupts(ah, ahp->ah_maskReg & ~ATH9K_INT_GLOBAL); 81 omask = ath9k_hw_set_interrupts(ah, ah->mask_reg & ~ATH9K_INT_GLOBAL);
88 82
89 txcfg = REG_READ(ah, AR_TXCFG); 83 txcfg = REG_READ(ah, AR_TXCFG);
90 curLevel = MS(txcfg, AR_FTRIG); 84 curLevel = MS(txcfg, AR_FTRIG);
@@ -100,18 +94,17 @@ bool ath9k_hw_updatetxtriglevel(struct ath_hal *ah, bool bIncTrigLevel)
100 94
101 ath9k_hw_set_interrupts(ah, omask); 95 ath9k_hw_set_interrupts(ah, omask);
102 96
103 ah->ah_txTrigLevel = newLevel; 97 ah->tx_trig_level = newLevel;
104 98
105 return newLevel != curLevel; 99 return newLevel != curLevel;
106} 100}
107 101
108bool ath9k_hw_stoptxdma(struct ath_hal *ah, u32 q) 102bool ath9k_hw_stoptxdma(struct ath_hw *ah, u32 q)
109{ 103{
110#define ATH9K_TX_STOP_DMA_TIMEOUT 4000 /* usec */ 104#define ATH9K_TX_STOP_DMA_TIMEOUT 4000 /* usec */
111#define ATH9K_TIME_QUANTUM 100 /* usec */ 105#define ATH9K_TIME_QUANTUM 100 /* usec */
112 106
113 struct ath_hal_5416 *ahp = AH5416(ah); 107 struct ath9k_hw_capabilities *pCap = &ah->caps;
114 struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
115 struct ath9k_tx_queue_info *qi; 108 struct ath9k_tx_queue_info *qi;
116 u32 tsfLow, j, wait; 109 u32 tsfLow, j, wait;
117 u32 wait_time = ATH9K_TX_STOP_DMA_TIMEOUT / ATH9K_TIME_QUANTUM; 110 u32 wait_time = ATH9K_TX_STOP_DMA_TIMEOUT / ATH9K_TIME_QUANTUM;
@@ -121,7 +114,7 @@ bool ath9k_hw_stoptxdma(struct ath_hal *ah, u32 q)
121 return false; 114 return false;
122 } 115 }
123 116
124 qi = &ahp->ah_txq[q]; 117 qi = &ah->txq[q];
125 if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) { 118 if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
126 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "inactive queue\n"); 119 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "inactive queue\n");
127 return false; 120 return false;
@@ -183,7 +176,7 @@ bool ath9k_hw_stoptxdma(struct ath_hal *ah, u32 q)
183#undef ATH9K_TIME_QUANTUM 176#undef ATH9K_TIME_QUANTUM
184} 177}
185 178
186bool ath9k_hw_filltxdesc(struct ath_hal *ah, struct ath_desc *ds, 179bool ath9k_hw_filltxdesc(struct ath_hw *ah, struct ath_desc *ds,
187 u32 segLen, bool firstSeg, 180 u32 segLen, bool firstSeg,
188 bool lastSeg, const struct ath_desc *ds0) 181 bool lastSeg, const struct ath_desc *ds0)
189{ 182{
@@ -211,7 +204,7 @@ bool ath9k_hw_filltxdesc(struct ath_hal *ah, struct ath_desc *ds,
211 return true; 204 return true;
212} 205}
213 206
214void ath9k_hw_cleartxdesc(struct ath_hal *ah, struct ath_desc *ds) 207void ath9k_hw_cleartxdesc(struct ath_hw *ah, struct ath_desc *ds)
215{ 208{
216 struct ar5416_desc *ads = AR5416DESC(ds); 209 struct ar5416_desc *ads = AR5416DESC(ds);
217 210
@@ -222,7 +215,7 @@ void ath9k_hw_cleartxdesc(struct ath_hal *ah, struct ath_desc *ds)
222 ads->ds_txstatus8 = ads->ds_txstatus9 = 0; 215 ads->ds_txstatus8 = ads->ds_txstatus9 = 0;
223} 216}
224 217
225int ath9k_hw_txprocdesc(struct ath_hal *ah, struct ath_desc *ds) 218int ath9k_hw_txprocdesc(struct ath_hw *ah, struct ath_desc *ds)
226{ 219{
227 struct ar5416_desc *ads = AR5416DESC(ds); 220 struct ar5416_desc *ads = AR5416DESC(ds);
228 221
@@ -297,14 +290,13 @@ int ath9k_hw_txprocdesc(struct ath_hal *ah, struct ath_desc *ds)
297 return 0; 290 return 0;
298} 291}
299 292
300void ath9k_hw_set11n_txdesc(struct ath_hal *ah, struct ath_desc *ds, 293void ath9k_hw_set11n_txdesc(struct ath_hw *ah, struct ath_desc *ds,
301 u32 pktLen, enum ath9k_pkt_type type, u32 txPower, 294 u32 pktLen, enum ath9k_pkt_type type, u32 txPower,
302 u32 keyIx, enum ath9k_key_type keyType, u32 flags) 295 u32 keyIx, enum ath9k_key_type keyType, u32 flags)
303{ 296{
304 struct ar5416_desc *ads = AR5416DESC(ds); 297 struct ar5416_desc *ads = AR5416DESC(ds);
305 struct ath_hal_5416 *ahp = AH5416(ah);
306 298
307 txPower += ahp->ah_txPowerIndexOffset; 299 txPower += ah->txpower_indexoffset;
308 if (txPower > 63) 300 if (txPower > 63)
309 txPower = 63; 301 txPower = 63;
310 302
@@ -333,7 +325,7 @@ void ath9k_hw_set11n_txdesc(struct ath_hal *ah, struct ath_desc *ds,
333 } 325 }
334} 326}
335 327
336void ath9k_hw_set11n_ratescenario(struct ath_hal *ah, struct ath_desc *ds, 328void ath9k_hw_set11n_ratescenario(struct ath_hw *ah, struct ath_desc *ds,
337 struct ath_desc *lastds, 329 struct ath_desc *lastds,
338 u32 durUpdateEn, u32 rtsctsRate, 330 u32 durUpdateEn, u32 rtsctsRate,
339 u32 rtsctsDuration, 331 u32 rtsctsDuration,
@@ -388,7 +380,7 @@ void ath9k_hw_set11n_ratescenario(struct ath_hal *ah, struct ath_desc *ds,
388 last_ads->ds_ctl3 = ads->ds_ctl3; 380 last_ads->ds_ctl3 = ads->ds_ctl3;
389} 381}
390 382
391void ath9k_hw_set11n_aggr_first(struct ath_hal *ah, struct ath_desc *ds, 383void ath9k_hw_set11n_aggr_first(struct ath_hw *ah, struct ath_desc *ds,
392 u32 aggrLen) 384 u32 aggrLen)
393{ 385{
394 struct ar5416_desc *ads = AR5416DESC(ds); 386 struct ar5416_desc *ads = AR5416DESC(ds);
@@ -398,7 +390,7 @@ void ath9k_hw_set11n_aggr_first(struct ath_hal *ah, struct ath_desc *ds,
398 ads->ds_ctl6 |= SM(aggrLen, AR_AggrLen); 390 ads->ds_ctl6 |= SM(aggrLen, AR_AggrLen);
399} 391}
400 392
401void ath9k_hw_set11n_aggr_middle(struct ath_hal *ah, struct ath_desc *ds, 393void ath9k_hw_set11n_aggr_middle(struct ath_hw *ah, struct ath_desc *ds,
402 u32 numDelims) 394 u32 numDelims)
403{ 395{
404 struct ar5416_desc *ads = AR5416DESC(ds); 396 struct ar5416_desc *ads = AR5416DESC(ds);
@@ -412,7 +404,7 @@ void ath9k_hw_set11n_aggr_middle(struct ath_hal *ah, struct ath_desc *ds,
412 ads->ds_ctl6 = ctl6; 404 ads->ds_ctl6 = ctl6;
413} 405}
414 406
415void ath9k_hw_set11n_aggr_last(struct ath_hal *ah, struct ath_desc *ds) 407void ath9k_hw_set11n_aggr_last(struct ath_hw *ah, struct ath_desc *ds)
416{ 408{
417 struct ar5416_desc *ads = AR5416DESC(ds); 409 struct ar5416_desc *ads = AR5416DESC(ds);
418 410
@@ -421,14 +413,14 @@ void ath9k_hw_set11n_aggr_last(struct ath_hal *ah, struct ath_desc *ds)
421 ads->ds_ctl6 &= ~AR_PadDelim; 413 ads->ds_ctl6 &= ~AR_PadDelim;
422} 414}
423 415
424void ath9k_hw_clr11n_aggr(struct ath_hal *ah, struct ath_desc *ds) 416void ath9k_hw_clr11n_aggr(struct ath_hw *ah, struct ath_desc *ds)
425{ 417{
426 struct ar5416_desc *ads = AR5416DESC(ds); 418 struct ar5416_desc *ads = AR5416DESC(ds);
427 419
428 ads->ds_ctl1 &= (~AR_IsAggr & ~AR_MoreAggr); 420 ads->ds_ctl1 &= (~AR_IsAggr & ~AR_MoreAggr);
429} 421}
430 422
431void ath9k_hw_set11n_burstduration(struct ath_hal *ah, struct ath_desc *ds, 423void ath9k_hw_set11n_burstduration(struct ath_hw *ah, struct ath_desc *ds,
432 u32 burstDuration) 424 u32 burstDuration)
433{ 425{
434 struct ar5416_desc *ads = AR5416DESC(ds); 426 struct ar5416_desc *ads = AR5416DESC(ds);
@@ -437,7 +429,7 @@ void ath9k_hw_set11n_burstduration(struct ath_hal *ah, struct ath_desc *ds,
437 ads->ds_ctl2 |= SM(burstDuration, AR_BurstDur); 429 ads->ds_ctl2 |= SM(burstDuration, AR_BurstDur);
438} 430}
439 431
440void ath9k_hw_set11n_virtualmorefrag(struct ath_hal *ah, struct ath_desc *ds, 432void ath9k_hw_set11n_virtualmorefrag(struct ath_hw *ah, struct ath_desc *ds,
441 u32 vmf) 433 u32 vmf)
442{ 434{
443 struct ar5416_desc *ads = AR5416DESC(ds); 435 struct ar5416_desc *ads = AR5416DESC(ds);
@@ -448,20 +440,17 @@ void ath9k_hw_set11n_virtualmorefrag(struct ath_hal *ah, struct ath_desc *ds,
448 ads->ds_ctl0 &= ~AR_VirtMoreFrag; 440 ads->ds_ctl0 &= ~AR_VirtMoreFrag;
449} 441}
450 442
451void ath9k_hw_gettxintrtxqs(struct ath_hal *ah, u32 *txqs) 443void ath9k_hw_gettxintrtxqs(struct ath_hw *ah, u32 *txqs)
452{ 444{
453 struct ath_hal_5416 *ahp = AH5416(ah); 445 *txqs &= ah->intr_txqs;
454 446 ah->intr_txqs &= ~(*txqs);
455 *txqs &= ahp->ah_intrTxqs;
456 ahp->ah_intrTxqs &= ~(*txqs);
457} 447}
458 448
459bool ath9k_hw_set_txq_props(struct ath_hal *ah, int q, 449bool ath9k_hw_set_txq_props(struct ath_hw *ah, int q,
460 const struct ath9k_tx_queue_info *qinfo) 450 const struct ath9k_tx_queue_info *qinfo)
461{ 451{
462 u32 cw; 452 u32 cw;
463 struct ath_hal_5416 *ahp = AH5416(ah); 453 struct ath9k_hw_capabilities *pCap = &ah->caps;
464 struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
465 struct ath9k_tx_queue_info *qi; 454 struct ath9k_tx_queue_info *qi;
466 455
467 if (q >= pCap->total_queues) { 456 if (q >= pCap->total_queues) {
@@ -469,7 +458,7 @@ bool ath9k_hw_set_txq_props(struct ath_hal *ah, int q,
469 return false; 458 return false;
470 } 459 }
471 460
472 qi = &ahp->ah_txq[q]; 461 qi = &ah->txq[q];
473 if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) { 462 if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
474 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "inactive queue\n"); 463 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "inactive queue\n");
475 return false; 464 return false;
@@ -525,11 +514,10 @@ bool ath9k_hw_set_txq_props(struct ath_hal *ah, int q,
525 return true; 514 return true;
526} 515}
527 516
528bool ath9k_hw_get_txq_props(struct ath_hal *ah, int q, 517bool ath9k_hw_get_txq_props(struct ath_hw *ah, int q,
529 struct ath9k_tx_queue_info *qinfo) 518 struct ath9k_tx_queue_info *qinfo)
530{ 519{
531 struct ath_hal_5416 *ahp = AH5416(ah); 520 struct ath9k_hw_capabilities *pCap = &ah->caps;
532 struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
533 struct ath9k_tx_queue_info *qi; 521 struct ath9k_tx_queue_info *qi;
534 522
535 if (q >= pCap->total_queues) { 523 if (q >= pCap->total_queues) {
@@ -537,7 +525,7 @@ bool ath9k_hw_get_txq_props(struct ath_hal *ah, int q,
537 return false; 525 return false;
538 } 526 }
539 527
540 qi = &ahp->ah_txq[q]; 528 qi = &ah->txq[q];
541 if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) { 529 if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
542 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "inactive queue\n"); 530 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "inactive queue\n");
543 return false; 531 return false;
@@ -561,12 +549,11 @@ bool ath9k_hw_get_txq_props(struct ath_hal *ah, int q,
561 return true; 549 return true;
562} 550}
563 551
564int ath9k_hw_setuptxqueue(struct ath_hal *ah, enum ath9k_tx_queue type, 552int ath9k_hw_setuptxqueue(struct ath_hw *ah, enum ath9k_tx_queue type,
565 const struct ath9k_tx_queue_info *qinfo) 553 const struct ath9k_tx_queue_info *qinfo)
566{ 554{
567 struct ath_hal_5416 *ahp = AH5416(ah);
568 struct ath9k_tx_queue_info *qi; 555 struct ath9k_tx_queue_info *qi;
569 struct ath9k_hw_capabilities *pCap = &ah->ah_caps; 556 struct ath9k_hw_capabilities *pCap = &ah->caps;
570 int q; 557 int q;
571 558
572 switch (type) { 559 switch (type) {
@@ -584,7 +571,7 @@ int ath9k_hw_setuptxqueue(struct ath_hal *ah, enum ath9k_tx_queue type,
584 break; 571 break;
585 case ATH9K_TX_QUEUE_DATA: 572 case ATH9K_TX_QUEUE_DATA:
586 for (q = 0; q < pCap->total_queues; q++) 573 for (q = 0; q < pCap->total_queues; q++)
587 if (ahp->ah_txq[q].tqi_type == 574 if (ah->txq[q].tqi_type ==
588 ATH9K_TX_QUEUE_INACTIVE) 575 ATH9K_TX_QUEUE_INACTIVE)
589 break; 576 break;
590 if (q == pCap->total_queues) { 577 if (q == pCap->total_queues) {
@@ -600,7 +587,7 @@ int ath9k_hw_setuptxqueue(struct ath_hal *ah, enum ath9k_tx_queue type,
600 587
601 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "queue %u\n", q); 588 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "queue %u\n", q);
602 589
603 qi = &ahp->ah_txq[q]; 590 qi = &ah->txq[q];
604 if (qi->tqi_type != ATH9K_TX_QUEUE_INACTIVE) { 591 if (qi->tqi_type != ATH9K_TX_QUEUE_INACTIVE) {
605 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, 592 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE,
606 "tx queue %u already active\n", q); 593 "tx queue %u already active\n", q);
@@ -627,17 +614,16 @@ int ath9k_hw_setuptxqueue(struct ath_hal *ah, enum ath9k_tx_queue type,
627 return q; 614 return q;
628} 615}
629 616
630bool ath9k_hw_releasetxqueue(struct ath_hal *ah, u32 q) 617bool ath9k_hw_releasetxqueue(struct ath_hw *ah, u32 q)
631{ 618{
632 struct ath_hal_5416 *ahp = AH5416(ah); 619 struct ath9k_hw_capabilities *pCap = &ah->caps;
633 struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
634 struct ath9k_tx_queue_info *qi; 620 struct ath9k_tx_queue_info *qi;
635 621
636 if (q >= pCap->total_queues) { 622 if (q >= pCap->total_queues) {
637 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "invalid queue num %u\n", q); 623 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "invalid queue num %u\n", q);
638 return false; 624 return false;
639 } 625 }
640 qi = &ahp->ah_txq[q]; 626 qi = &ah->txq[q];
641 if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) { 627 if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
642 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "inactive queue %u\n", q); 628 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "inactive queue %u\n", q);
643 return false; 629 return false;
@@ -646,21 +632,20 @@ bool ath9k_hw_releasetxqueue(struct ath_hal *ah, u32 q)
646 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "release queue %u\n", q); 632 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "release queue %u\n", q);
647 633
648 qi->tqi_type = ATH9K_TX_QUEUE_INACTIVE; 634 qi->tqi_type = ATH9K_TX_QUEUE_INACTIVE;
649 ahp->ah_txOkInterruptMask &= ~(1 << q); 635 ah->txok_interrupt_mask &= ~(1 << q);
650 ahp->ah_txErrInterruptMask &= ~(1 << q); 636 ah->txerr_interrupt_mask &= ~(1 << q);
651 ahp->ah_txDescInterruptMask &= ~(1 << q); 637 ah->txdesc_interrupt_mask &= ~(1 << q);
652 ahp->ah_txEolInterruptMask &= ~(1 << q); 638 ah->txeol_interrupt_mask &= ~(1 << q);
653 ahp->ah_txUrnInterruptMask &= ~(1 << q); 639 ah->txurn_interrupt_mask &= ~(1 << q);
654 ath9k_hw_set_txq_interrupts(ah, qi); 640 ath9k_hw_set_txq_interrupts(ah, qi);
655 641
656 return true; 642 return true;
657} 643}
658 644
659bool ath9k_hw_resettxqueue(struct ath_hal *ah, u32 q) 645bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q)
660{ 646{
661 struct ath_hal_5416 *ahp = AH5416(ah); 647 struct ath9k_hw_capabilities *pCap = &ah->caps;
662 struct ath9k_hw_capabilities *pCap = &ah->ah_caps; 648 struct ath9k_channel *chan = ah->curchan;
663 struct ath9k_channel *chan = ah->ah_curchan;
664 struct ath9k_tx_queue_info *qi; 649 struct ath9k_tx_queue_info *qi;
665 u32 cwMin, chanCwMin, value; 650 u32 cwMin, chanCwMin, value;
666 651
@@ -669,7 +654,7 @@ bool ath9k_hw_resettxqueue(struct ath_hal *ah, u32 q)
669 return false; 654 return false;
670 } 655 }
671 656
672 qi = &ahp->ah_txq[q]; 657 qi = &ah->txq[q];
673 if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) { 658 if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
674 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "inactive queue %u\n", q); 659 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "inactive queue %u\n", q);
675 return true; 660 return true;
@@ -757,9 +742,9 @@ bool ath9k_hw_resettxqueue(struct ath_hal *ah, u32 q)
757 | AR_Q_MISC_CBR_INCR_DIS1 742 | AR_Q_MISC_CBR_INCR_DIS1
758 | AR_Q_MISC_CBR_INCR_DIS0); 743 | AR_Q_MISC_CBR_INCR_DIS0);
759 value = (qi->tqi_readyTime - 744 value = (qi->tqi_readyTime -
760 (ah->ah_config.sw_beacon_response_time - 745 (ah->config.sw_beacon_response_time -
761 ah->ah_config.dma_beacon_response_time) - 746 ah->config.dma_beacon_response_time) -
762 ah->ah_config.additional_swba_backoff) * 1024; 747 ah->config.additional_swba_backoff) * 1024;
763 REG_WRITE(ah, AR_QRDYTIMECFG(q), 748 REG_WRITE(ah, AR_QRDYTIMECFG(q),
764 value | AR_Q_RDYTIMECFG_EN); 749 value | AR_Q_RDYTIMECFG_EN);
765 REG_WRITE(ah, AR_DMISC(q), REG_READ(ah, AR_DMISC(q)) 750 REG_WRITE(ah, AR_DMISC(q), REG_READ(ah, AR_DMISC(q))
@@ -787,31 +772,31 @@ bool ath9k_hw_resettxqueue(struct ath_hal *ah, u32 q)
787 } 772 }
788 773
789 if (qi->tqi_qflags & TXQ_FLAG_TXOKINT_ENABLE) 774 if (qi->tqi_qflags & TXQ_FLAG_TXOKINT_ENABLE)
790 ahp->ah_txOkInterruptMask |= 1 << q; 775 ah->txok_interrupt_mask |= 1 << q;
791 else 776 else
792 ahp->ah_txOkInterruptMask &= ~(1 << q); 777 ah->txok_interrupt_mask &= ~(1 << q);
793 if (qi->tqi_qflags & TXQ_FLAG_TXERRINT_ENABLE) 778 if (qi->tqi_qflags & TXQ_FLAG_TXERRINT_ENABLE)
794 ahp->ah_txErrInterruptMask |= 1 << q; 779 ah->txerr_interrupt_mask |= 1 << q;
795 else 780 else
796 ahp->ah_txErrInterruptMask &= ~(1 << q); 781 ah->txerr_interrupt_mask &= ~(1 << q);
797 if (qi->tqi_qflags & TXQ_FLAG_TXDESCINT_ENABLE) 782 if (qi->tqi_qflags & TXQ_FLAG_TXDESCINT_ENABLE)
798 ahp->ah_txDescInterruptMask |= 1 << q; 783 ah->txdesc_interrupt_mask |= 1 << q;
799 else 784 else
800 ahp->ah_txDescInterruptMask &= ~(1 << q); 785 ah->txdesc_interrupt_mask &= ~(1 << q);
801 if (qi->tqi_qflags & TXQ_FLAG_TXEOLINT_ENABLE) 786 if (qi->tqi_qflags & TXQ_FLAG_TXEOLINT_ENABLE)
802 ahp->ah_txEolInterruptMask |= 1 << q; 787 ah->txeol_interrupt_mask |= 1 << q;
803 else 788 else
804 ahp->ah_txEolInterruptMask &= ~(1 << q); 789 ah->txeol_interrupt_mask &= ~(1 << q);
805 if (qi->tqi_qflags & TXQ_FLAG_TXURNINT_ENABLE) 790 if (qi->tqi_qflags & TXQ_FLAG_TXURNINT_ENABLE)
806 ahp->ah_txUrnInterruptMask |= 1 << q; 791 ah->txurn_interrupt_mask |= 1 << q;
807 else 792 else
808 ahp->ah_txUrnInterruptMask &= ~(1 << q); 793 ah->txurn_interrupt_mask &= ~(1 << q);
809 ath9k_hw_set_txq_interrupts(ah, qi); 794 ath9k_hw_set_txq_interrupts(ah, qi);
810 795
811 return true; 796 return true;
812} 797}
813 798
814int ath9k_hw_rxprocdesc(struct ath_hal *ah, struct ath_desc *ds, 799int ath9k_hw_rxprocdesc(struct ath_hw *ah, struct ath_desc *ds,
815 u32 pa, struct ath_desc *nds, u64 tsf) 800 u32 pa, struct ath_desc *nds, u64 tsf)
816{ 801{
817 struct ar5416_desc ads; 802 struct ar5416_desc ads;
@@ -876,11 +861,11 @@ int ath9k_hw_rxprocdesc(struct ath_hal *ah, struct ath_desc *ds,
876 return 0; 861 return 0;
877} 862}
878 863
879bool ath9k_hw_setuprxdesc(struct ath_hal *ah, struct ath_desc *ds, 864bool ath9k_hw_setuprxdesc(struct ath_hw *ah, struct ath_desc *ds,
880 u32 size, u32 flags) 865 u32 size, u32 flags)
881{ 866{
882 struct ar5416_desc *ads = AR5416DESC(ds); 867 struct ar5416_desc *ads = AR5416DESC(ds);
883 struct ath9k_hw_capabilities *pCap = &ah->ah_caps; 868 struct ath9k_hw_capabilities *pCap = &ah->caps;
884 869
885 ads->ds_ctl1 = size & AR_BufLen; 870 ads->ds_ctl1 = size & AR_BufLen;
886 if (flags & ATH9K_RXDESC_INTREQ) 871 if (flags & ATH9K_RXDESC_INTREQ)
@@ -893,7 +878,7 @@ bool ath9k_hw_setuprxdesc(struct ath_hal *ah, struct ath_desc *ds,
893 return true; 878 return true;
894} 879}
895 880
896bool ath9k_hw_setrxabort(struct ath_hal *ah, bool set) 881bool ath9k_hw_setrxabort(struct ath_hw *ah, bool set)
897{ 882{
898 u32 reg; 883 u32 reg;
899 884
@@ -920,17 +905,17 @@ bool ath9k_hw_setrxabort(struct ath_hal *ah, bool set)
920 return true; 905 return true;
921} 906}
922 907
923void ath9k_hw_putrxbuf(struct ath_hal *ah, u32 rxdp) 908void ath9k_hw_putrxbuf(struct ath_hw *ah, u32 rxdp)
924{ 909{
925 REG_WRITE(ah, AR_RXDP, rxdp); 910 REG_WRITE(ah, AR_RXDP, rxdp);
926} 911}
927 912
928void ath9k_hw_rxena(struct ath_hal *ah) 913void ath9k_hw_rxena(struct ath_hw *ah)
929{ 914{
930 REG_WRITE(ah, AR_CR, AR_CR_RXE); 915 REG_WRITE(ah, AR_CR, AR_CR_RXE);
931} 916}
932 917
933void ath9k_hw_startpcureceive(struct ath_hal *ah) 918void ath9k_hw_startpcureceive(struct ath_hw *ah)
934{ 919{
935 ath9k_enable_mib_counters(ah); 920 ath9k_enable_mib_counters(ah);
936 921
@@ -939,14 +924,14 @@ void ath9k_hw_startpcureceive(struct ath_hal *ah)
939 REG_CLR_BIT(ah, AR_DIAG_SW, (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT)); 924 REG_CLR_BIT(ah, AR_DIAG_SW, (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
940} 925}
941 926
942void ath9k_hw_stoppcurecv(struct ath_hal *ah) 927void ath9k_hw_stoppcurecv(struct ath_hw *ah)
943{ 928{
944 REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_RX_DIS); 929 REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_RX_DIS);
945 930
946 ath9k_hw_disable_mib_counters(ah); 931 ath9k_hw_disable_mib_counters(ah);
947} 932}
948 933
949bool ath9k_hw_stopdmarecv(struct ath_hal *ah) 934bool ath9k_hw_stopdmarecv(struct ath_hw *ah)
950{ 935{
951 REG_WRITE(ah, AR_CR, AR_CR_RXD); 936 REG_WRITE(ah, AR_CR, AR_CR_RXD);
952 937
diff --git a/drivers/net/wireless/ath9k/mac.h b/drivers/net/wireless/ath9k/mac.h
new file mode 100644
index 000000000000..74b660ae8add
--- /dev/null
+++ b/drivers/net/wireless/ath9k/mac.h
@@ -0,0 +1,676 @@
1/*
2 * Copyright (c) 2008 Atheros Communications Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#ifndef MAC_H
18#define MAC_H
19
20#define RXSTATUS_RATE(ah, ads) (AR_SREV_5416_V20_OR_LATER(ah) ? \
21 MS(ads->ds_rxstatus0, AR_RxRate) : \
22 (ads->ds_rxstatus3 >> 2) & 0xFF)
23
24#define set11nTries(_series, _index) \
25 (SM((_series)[_index].Tries, AR_XmitDataTries##_index))
26
27#define set11nRate(_series, _index) \
28 (SM((_series)[_index].Rate, AR_XmitRate##_index))
29
30#define set11nPktDurRTSCTS(_series, _index) \
31 (SM((_series)[_index].PktDuration, AR_PacketDur##_index) | \
32 ((_series)[_index].RateFlags & ATH9K_RATESERIES_RTS_CTS ? \
33 AR_RTSCTSQual##_index : 0))
34
35#define set11nRateFlags(_series, _index) \
36 (((_series)[_index].RateFlags & ATH9K_RATESERIES_2040 ? \
37 AR_2040_##_index : 0) \
38 |((_series)[_index].RateFlags & ATH9K_RATESERIES_HALFGI ? \
39 AR_GI##_index : 0) \
40 |SM((_series)[_index].ChSel, AR_ChainSel##_index))
41
42#define CCK_SIFS_TIME 10
43#define CCK_PREAMBLE_BITS 144
44#define CCK_PLCP_BITS 48
45
46#define OFDM_SIFS_TIME 16
47#define OFDM_PREAMBLE_TIME 20
48#define OFDM_PLCP_BITS 22
49#define OFDM_SYMBOL_TIME 4
50
51#define OFDM_SIFS_TIME_HALF 32
52#define OFDM_PREAMBLE_TIME_HALF 40
53#define OFDM_PLCP_BITS_HALF 22
54#define OFDM_SYMBOL_TIME_HALF 8
55
56#define OFDM_SIFS_TIME_QUARTER 64
57#define OFDM_PREAMBLE_TIME_QUARTER 80
58#define OFDM_PLCP_BITS_QUARTER 22
59#define OFDM_SYMBOL_TIME_QUARTER 16
60
61#define INIT_AIFS 2
62#define INIT_CWMIN 15
63#define INIT_CWMIN_11B 31
64#define INIT_CWMAX 1023
65#define INIT_SH_RETRY 10
66#define INIT_LG_RETRY 10
67#define INIT_SSH_RETRY 32
68#define INIT_SLG_RETRY 32
69
70#define ATH9K_SLOT_TIME_6 6
71#define ATH9K_SLOT_TIME_9 9
72#define ATH9K_SLOT_TIME_20 20
73
74#define ATH9K_TXERR_XRETRY 0x01
75#define ATH9K_TXERR_FILT 0x02
76#define ATH9K_TXERR_FIFO 0x04
77#define ATH9K_TXERR_XTXOP 0x08
78#define ATH9K_TXERR_TIMER_EXPIRED 0x10
79
80#define ATH9K_TX_BA 0x01
81#define ATH9K_TX_PWRMGMT 0x02
82#define ATH9K_TX_DESC_CFG_ERR 0x04
83#define ATH9K_TX_DATA_UNDERRUN 0x08
84#define ATH9K_TX_DELIM_UNDERRUN 0x10
85#define ATH9K_TX_SW_ABORTED 0x40
86#define ATH9K_TX_SW_FILTERED 0x80
87
88#define MIN_TX_FIFO_THRESHOLD 0x1
89#define MAX_TX_FIFO_THRESHOLD ((4096 / 64) - 1)
90#define INIT_TX_FIFO_THRESHOLD MIN_TX_FIFO_THRESHOLD
91
92struct ath_tx_status {
93 u32 ts_tstamp;
94 u16 ts_seqnum;
95 u8 ts_status;
96 u8 ts_ratecode;
97 u8 ts_rateindex;
98 int8_t ts_rssi;
99 u8 ts_shortretry;
100 u8 ts_longretry;
101 u8 ts_virtcol;
102 u8 ts_antenna;
103 u8 ts_flags;
104 int8_t ts_rssi_ctl0;
105 int8_t ts_rssi_ctl1;
106 int8_t ts_rssi_ctl2;
107 int8_t ts_rssi_ext0;
108 int8_t ts_rssi_ext1;
109 int8_t ts_rssi_ext2;
110 u8 pad[3];
111 u32 ba_low;
112 u32 ba_high;
113 u32 evm0;
114 u32 evm1;
115 u32 evm2;
116};
117
118struct ath_rx_status {
119 u32 rs_tstamp;
120 u16 rs_datalen;
121 u8 rs_status;
122 u8 rs_phyerr;
123 int8_t rs_rssi;
124 u8 rs_keyix;
125 u8 rs_rate;
126 u8 rs_antenna;
127 u8 rs_more;
128 int8_t rs_rssi_ctl0;
129 int8_t rs_rssi_ctl1;
130 int8_t rs_rssi_ctl2;
131 int8_t rs_rssi_ext0;
132 int8_t rs_rssi_ext1;
133 int8_t rs_rssi_ext2;
134 u8 rs_isaggr;
135 u8 rs_moreaggr;
136 u8 rs_num_delims;
137 u8 rs_flags;
138 u32 evm0;
139 u32 evm1;
140 u32 evm2;
141};
142
143#define ATH9K_RXERR_CRC 0x01
144#define ATH9K_RXERR_PHY 0x02
145#define ATH9K_RXERR_FIFO 0x04
146#define ATH9K_RXERR_DECRYPT 0x08
147#define ATH9K_RXERR_MIC 0x10
148
149#define ATH9K_RX_MORE 0x01
150#define ATH9K_RX_MORE_AGGR 0x02
151#define ATH9K_RX_GI 0x04
152#define ATH9K_RX_2040 0x08
153#define ATH9K_RX_DELIM_CRC_PRE 0x10
154#define ATH9K_RX_DELIM_CRC_POST 0x20
155#define ATH9K_RX_DECRYPT_BUSY 0x40
156
157#define ATH9K_RXKEYIX_INVALID ((u8)-1)
158#define ATH9K_TXKEYIX_INVALID ((u32)-1)
159
160struct ath_desc {
161 u32 ds_link;
162 u32 ds_data;
163 u32 ds_ctl0;
164 u32 ds_ctl1;
165 u32 ds_hw[20];
166 union {
167 struct ath_tx_status tx;
168 struct ath_rx_status rx;
169 void *stats;
170 } ds_us;
171 void *ds_vdata;
172} __packed;
173
174#define ds_txstat ds_us.tx
175#define ds_rxstat ds_us.rx
176#define ds_stat ds_us.stats
177
178#define ATH9K_TXDESC_CLRDMASK 0x0001
179#define ATH9K_TXDESC_NOACK 0x0002
180#define ATH9K_TXDESC_RTSENA 0x0004
181#define ATH9K_TXDESC_CTSENA 0x0008
182/* ATH9K_TXDESC_INTREQ forces a tx interrupt to be generated for
183 * the descriptor its marked on. We take a tx interrupt to reap
184 * descriptors when the h/w hits an EOL condition or
185 * when the descriptor is specifically marked to generate
186 * an interrupt with this flag. Descriptors should be
187 * marked periodically to insure timely replenishing of the
188 * supply needed for sending frames. Defering interrupts
189 * reduces system load and potentially allows more concurrent
190 * work to be done but if done to aggressively can cause
191 * senders to backup. When the hardware queue is left too
192 * large rate control information may also be too out of
193 * date. An Alternative for this is TX interrupt mitigation
194 * but this needs more testing. */
195#define ATH9K_TXDESC_INTREQ 0x0010
196#define ATH9K_TXDESC_VEOL 0x0020
197#define ATH9K_TXDESC_EXT_ONLY 0x0040
198#define ATH9K_TXDESC_EXT_AND_CTL 0x0080
199#define ATH9K_TXDESC_VMF 0x0100
200#define ATH9K_TXDESC_FRAG_IS_ON 0x0200
201#define ATH9K_TXDESC_CAB 0x0400
202
203#define ATH9K_RXDESC_INTREQ 0x0020
204
205struct ar5416_desc {
206 u32 ds_link;
207 u32 ds_data;
208 u32 ds_ctl0;
209 u32 ds_ctl1;
210 union {
211 struct {
212 u32 ctl2;
213 u32 ctl3;
214 u32 ctl4;
215 u32 ctl5;
216 u32 ctl6;
217 u32 ctl7;
218 u32 ctl8;
219 u32 ctl9;
220 u32 ctl10;
221 u32 ctl11;
222 u32 status0;
223 u32 status1;
224 u32 status2;
225 u32 status3;
226 u32 status4;
227 u32 status5;
228 u32 status6;
229 u32 status7;
230 u32 status8;
231 u32 status9;
232 } tx;
233 struct {
234 u32 status0;
235 u32 status1;
236 u32 status2;
237 u32 status3;
238 u32 status4;
239 u32 status5;
240 u32 status6;
241 u32 status7;
242 u32 status8;
243 } rx;
244 } u;
245} __packed;
246
247#define AR5416DESC(_ds) ((struct ar5416_desc *)(_ds))
248#define AR5416DESC_CONST(_ds) ((const struct ar5416_desc *)(_ds))
249
250#define ds_ctl2 u.tx.ctl2
251#define ds_ctl3 u.tx.ctl3
252#define ds_ctl4 u.tx.ctl4
253#define ds_ctl5 u.tx.ctl5
254#define ds_ctl6 u.tx.ctl6
255#define ds_ctl7 u.tx.ctl7
256#define ds_ctl8 u.tx.ctl8
257#define ds_ctl9 u.tx.ctl9
258#define ds_ctl10 u.tx.ctl10
259#define ds_ctl11 u.tx.ctl11
260
261#define ds_txstatus0 u.tx.status0
262#define ds_txstatus1 u.tx.status1
263#define ds_txstatus2 u.tx.status2
264#define ds_txstatus3 u.tx.status3
265#define ds_txstatus4 u.tx.status4
266#define ds_txstatus5 u.tx.status5
267#define ds_txstatus6 u.tx.status6
268#define ds_txstatus7 u.tx.status7
269#define ds_txstatus8 u.tx.status8
270#define ds_txstatus9 u.tx.status9
271
272#define ds_rxstatus0 u.rx.status0
273#define ds_rxstatus1 u.rx.status1
274#define ds_rxstatus2 u.rx.status2
275#define ds_rxstatus3 u.rx.status3
276#define ds_rxstatus4 u.rx.status4
277#define ds_rxstatus5 u.rx.status5
278#define ds_rxstatus6 u.rx.status6
279#define ds_rxstatus7 u.rx.status7
280#define ds_rxstatus8 u.rx.status8
281
282#define AR_FrameLen 0x00000fff
283#define AR_VirtMoreFrag 0x00001000
284#define AR_TxCtlRsvd00 0x0000e000
285#define AR_XmitPower 0x003f0000
286#define AR_XmitPower_S 16
287#define AR_RTSEnable 0x00400000
288#define AR_VEOL 0x00800000
289#define AR_ClrDestMask 0x01000000
290#define AR_TxCtlRsvd01 0x1e000000
291#define AR_TxIntrReq 0x20000000
292#define AR_DestIdxValid 0x40000000
293#define AR_CTSEnable 0x80000000
294
295#define AR_BufLen 0x00000fff
296#define AR_TxMore 0x00001000
297#define AR_DestIdx 0x000fe000
298#define AR_DestIdx_S 13
299#define AR_FrameType 0x00f00000
300#define AR_FrameType_S 20
301#define AR_NoAck 0x01000000
302#define AR_InsertTS 0x02000000
303#define AR_CorruptFCS 0x04000000
304#define AR_ExtOnly 0x08000000
305#define AR_ExtAndCtl 0x10000000
306#define AR_MoreAggr 0x20000000
307#define AR_IsAggr 0x40000000
308
309#define AR_BurstDur 0x00007fff
310#define AR_BurstDur_S 0
311#define AR_DurUpdateEna 0x00008000
312#define AR_XmitDataTries0 0x000f0000
313#define AR_XmitDataTries0_S 16
314#define AR_XmitDataTries1 0x00f00000
315#define AR_XmitDataTries1_S 20
316#define AR_XmitDataTries2 0x0f000000
317#define AR_XmitDataTries2_S 24
318#define AR_XmitDataTries3 0xf0000000
319#define AR_XmitDataTries3_S 28
320
321#define AR_XmitRate0 0x000000ff
322#define AR_XmitRate0_S 0
323#define AR_XmitRate1 0x0000ff00
324#define AR_XmitRate1_S 8
325#define AR_XmitRate2 0x00ff0000
326#define AR_XmitRate2_S 16
327#define AR_XmitRate3 0xff000000
328#define AR_XmitRate3_S 24
329
330#define AR_PacketDur0 0x00007fff
331#define AR_PacketDur0_S 0
332#define AR_RTSCTSQual0 0x00008000
333#define AR_PacketDur1 0x7fff0000
334#define AR_PacketDur1_S 16
335#define AR_RTSCTSQual1 0x80000000
336
337#define AR_PacketDur2 0x00007fff
338#define AR_PacketDur2_S 0
339#define AR_RTSCTSQual2 0x00008000
340#define AR_PacketDur3 0x7fff0000
341#define AR_PacketDur3_S 16
342#define AR_RTSCTSQual3 0x80000000
343
344#define AR_AggrLen 0x0000ffff
345#define AR_AggrLen_S 0
346#define AR_TxCtlRsvd60 0x00030000
347#define AR_PadDelim 0x03fc0000
348#define AR_PadDelim_S 18
349#define AR_EncrType 0x0c000000
350#define AR_EncrType_S 26
351#define AR_TxCtlRsvd61 0xf0000000
352
353#define AR_2040_0 0x00000001
354#define AR_GI0 0x00000002
355#define AR_ChainSel0 0x0000001c
356#define AR_ChainSel0_S 2
357#define AR_2040_1 0x00000020
358#define AR_GI1 0x00000040
359#define AR_ChainSel1 0x00000380
360#define AR_ChainSel1_S 7
361#define AR_2040_2 0x00000400
362#define AR_GI2 0x00000800
363#define AR_ChainSel2 0x00007000
364#define AR_ChainSel2_S 12
365#define AR_2040_3 0x00008000
366#define AR_GI3 0x00010000
367#define AR_ChainSel3 0x000e0000
368#define AR_ChainSel3_S 17
369#define AR_RTSCTSRate 0x0ff00000
370#define AR_RTSCTSRate_S 20
371#define AR_TxCtlRsvd70 0xf0000000
372
373#define AR_TxRSSIAnt00 0x000000ff
374#define AR_TxRSSIAnt00_S 0
375#define AR_TxRSSIAnt01 0x0000ff00
376#define AR_TxRSSIAnt01_S 8
377#define AR_TxRSSIAnt02 0x00ff0000
378#define AR_TxRSSIAnt02_S 16
379#define AR_TxStatusRsvd00 0x3f000000
380#define AR_TxBaStatus 0x40000000
381#define AR_TxStatusRsvd01 0x80000000
382
383#define AR_FrmXmitOK 0x00000001
384#define AR_ExcessiveRetries 0x00000002
385#define AR_FIFOUnderrun 0x00000004
386#define AR_Filtered 0x00000008
387#define AR_RTSFailCnt 0x000000f0
388#define AR_RTSFailCnt_S 4
389#define AR_DataFailCnt 0x00000f00
390#define AR_DataFailCnt_S 8
391#define AR_VirtRetryCnt 0x0000f000
392#define AR_VirtRetryCnt_S 12
393#define AR_TxDelimUnderrun 0x00010000
394#define AR_TxDataUnderrun 0x00020000
395#define AR_DescCfgErr 0x00040000
396#define AR_TxTimerExpired 0x00080000
397#define AR_TxStatusRsvd10 0xfff00000
398
399#define AR_SendTimestamp ds_txstatus2
400#define AR_BaBitmapLow ds_txstatus3
401#define AR_BaBitmapHigh ds_txstatus4
402
403#define AR_TxRSSIAnt10 0x000000ff
404#define AR_TxRSSIAnt10_S 0
405#define AR_TxRSSIAnt11 0x0000ff00
406#define AR_TxRSSIAnt11_S 8
407#define AR_TxRSSIAnt12 0x00ff0000
408#define AR_TxRSSIAnt12_S 16
409#define AR_TxRSSICombined 0xff000000
410#define AR_TxRSSICombined_S 24
411
412#define AR_TxEVM0 ds_txstatus5
413#define AR_TxEVM1 ds_txstatus6
414#define AR_TxEVM2 ds_txstatus7
415
416#define AR_TxDone 0x00000001
417#define AR_SeqNum 0x00001ffe
418#define AR_SeqNum_S 1
419#define AR_TxStatusRsvd80 0x0001e000
420#define AR_TxOpExceeded 0x00020000
421#define AR_TxStatusRsvd81 0x001c0000
422#define AR_FinalTxIdx 0x00600000
423#define AR_FinalTxIdx_S 21
424#define AR_TxStatusRsvd82 0x01800000
425#define AR_PowerMgmt 0x02000000
426#define AR_TxStatusRsvd83 0xfc000000
427
428#define AR_RxCTLRsvd00 0xffffffff
429
430#define AR_BufLen 0x00000fff
431#define AR_RxCtlRsvd00 0x00001000
432#define AR_RxIntrReq 0x00002000
433#define AR_RxCtlRsvd01 0xffffc000
434
435#define AR_RxRSSIAnt00 0x000000ff
436#define AR_RxRSSIAnt00_S 0
437#define AR_RxRSSIAnt01 0x0000ff00
438#define AR_RxRSSIAnt01_S 8
439#define AR_RxRSSIAnt02 0x00ff0000
440#define AR_RxRSSIAnt02_S 16
441#define AR_RxRate 0xff000000
442#define AR_RxRate_S 24
443#define AR_RxStatusRsvd00 0xff000000
444
445#define AR_DataLen 0x00000fff
446#define AR_RxMore 0x00001000
447#define AR_NumDelim 0x003fc000
448#define AR_NumDelim_S 14
449#define AR_RxStatusRsvd10 0xff800000
450
451#define AR_RcvTimestamp ds_rxstatus2
452
453#define AR_GI 0x00000001
454#define AR_2040 0x00000002
455#define AR_Parallel40 0x00000004
456#define AR_Parallel40_S 2
457#define AR_RxStatusRsvd30 0x000000f8
458#define AR_RxAntenna 0xffffff00
459#define AR_RxAntenna_S 8
460
461#define AR_RxRSSIAnt10 0x000000ff
462#define AR_RxRSSIAnt10_S 0
463#define AR_RxRSSIAnt11 0x0000ff00
464#define AR_RxRSSIAnt11_S 8
465#define AR_RxRSSIAnt12 0x00ff0000
466#define AR_RxRSSIAnt12_S 16
467#define AR_RxRSSICombined 0xff000000
468#define AR_RxRSSICombined_S 24
469
470#define AR_RxEVM0 ds_rxstatus4
471#define AR_RxEVM1 ds_rxstatus5
472#define AR_RxEVM2 ds_rxstatus6
473
474#define AR_RxDone 0x00000001
475#define AR_RxFrameOK 0x00000002
476#define AR_CRCErr 0x00000004
477#define AR_DecryptCRCErr 0x00000008
478#define AR_PHYErr 0x00000010
479#define AR_MichaelErr 0x00000020
480#define AR_PreDelimCRCErr 0x00000040
481#define AR_RxStatusRsvd70 0x00000080
482#define AR_RxKeyIdxValid 0x00000100
483#define AR_KeyIdx 0x0000fe00
484#define AR_KeyIdx_S 9
485#define AR_PHYErrCode 0x0000ff00
486#define AR_PHYErrCode_S 8
487#define AR_RxMoreAggr 0x00010000
488#define AR_RxAggr 0x00020000
489#define AR_PostDelimCRCErr 0x00040000
490#define AR_RxStatusRsvd71 0x3ff80000
491#define AR_DecryptBusyErr 0x40000000
492#define AR_KeyMiss 0x80000000
493
494enum ath9k_tx_queue {
495 ATH9K_TX_QUEUE_INACTIVE = 0,
496 ATH9K_TX_QUEUE_DATA,
497 ATH9K_TX_QUEUE_BEACON,
498 ATH9K_TX_QUEUE_CAB,
499 ATH9K_TX_QUEUE_UAPSD,
500 ATH9K_TX_QUEUE_PSPOLL
501};
502
503#define ATH9K_NUM_TX_QUEUES 10
504
505enum ath9k_tx_queue_subtype {
506 ATH9K_WME_AC_BK = 0,
507 ATH9K_WME_AC_BE,
508 ATH9K_WME_AC_VI,
509 ATH9K_WME_AC_VO,
510 ATH9K_WME_UPSD
511};
512
513enum ath9k_tx_queue_flags {
514 TXQ_FLAG_TXOKINT_ENABLE = 0x0001,
515 TXQ_FLAG_TXERRINT_ENABLE = 0x0001,
516 TXQ_FLAG_TXDESCINT_ENABLE = 0x0002,
517 TXQ_FLAG_TXEOLINT_ENABLE = 0x0004,
518 TXQ_FLAG_TXURNINT_ENABLE = 0x0008,
519 TXQ_FLAG_BACKOFF_DISABLE = 0x0010,
520 TXQ_FLAG_COMPRESSION_ENABLE = 0x0020,
521 TXQ_FLAG_RDYTIME_EXP_POLICY_ENABLE = 0x0040,
522 TXQ_FLAG_FRAG_BURST_BACKOFF_ENABLE = 0x0080,
523};
524
525#define ATH9K_TXQ_USEDEFAULT ((u32) -1)
526#define ATH9K_TXQ_USE_LOCKOUT_BKOFF_DIS 0x00000001
527
528#define ATH9K_DECOMP_MASK_SIZE 128
529#define ATH9K_READY_TIME_LO_BOUND 50
530#define ATH9K_READY_TIME_HI_BOUND 96
531
532enum ath9k_pkt_type {
533 ATH9K_PKT_TYPE_NORMAL = 0,
534 ATH9K_PKT_TYPE_ATIM,
535 ATH9K_PKT_TYPE_PSPOLL,
536 ATH9K_PKT_TYPE_BEACON,
537 ATH9K_PKT_TYPE_PROBE_RESP,
538 ATH9K_PKT_TYPE_CHIRP,
539 ATH9K_PKT_TYPE_GRP_POLL,
540};
541
542struct ath9k_tx_queue_info {
543 u32 tqi_ver;
544 enum ath9k_tx_queue tqi_type;
545 enum ath9k_tx_queue_subtype tqi_subtype;
546 enum ath9k_tx_queue_flags tqi_qflags;
547 u32 tqi_priority;
548 u32 tqi_aifs;
549 u32 tqi_cwmin;
550 u32 tqi_cwmax;
551 u16 tqi_shretry;
552 u16 tqi_lgretry;
553 u32 tqi_cbrPeriod;
554 u32 tqi_cbrOverflowLimit;
555 u32 tqi_burstTime;
556 u32 tqi_readyTime;
557 u32 tqi_physCompBuf;
558 u32 tqi_intFlags;
559};
560
561enum ath9k_rx_filter {
562 ATH9K_RX_FILTER_UCAST = 0x00000001,
563 ATH9K_RX_FILTER_MCAST = 0x00000002,
564 ATH9K_RX_FILTER_BCAST = 0x00000004,
565 ATH9K_RX_FILTER_CONTROL = 0x00000008,
566 ATH9K_RX_FILTER_BEACON = 0x00000010,
567 ATH9K_RX_FILTER_PROM = 0x00000020,
568 ATH9K_RX_FILTER_PROBEREQ = 0x00000080,
569 ATH9K_RX_FILTER_PSPOLL = 0x00004000,
570 ATH9K_RX_FILTER_PHYERR = 0x00000100,
571 ATH9K_RX_FILTER_PHYRADAR = 0x00002000,
572};
573
574#define ATH9K_RATESERIES_RTS_CTS 0x0001
575#define ATH9K_RATESERIES_2040 0x0002
576#define ATH9K_RATESERIES_HALFGI 0x0004
577
578struct ath9k_11n_rate_series {
579 u32 Tries;
580 u32 Rate;
581 u32 PktDuration;
582 u32 ChSel;
583 u32 RateFlags;
584};
585
586struct ath9k_keyval {
587 u8 kv_type;
588 u8 kv_pad;
589 u16 kv_len;
590 u8 kv_val[16];
591 u8 kv_mic[8];
592 u8 kv_txmic[8];
593};
594
595enum ath9k_key_type {
596 ATH9K_KEY_TYPE_CLEAR,
597 ATH9K_KEY_TYPE_WEP,
598 ATH9K_KEY_TYPE_AES,
599 ATH9K_KEY_TYPE_TKIP,
600};
601
602enum ath9k_cipher {
603 ATH9K_CIPHER_WEP = 0,
604 ATH9K_CIPHER_AES_OCB = 1,
605 ATH9K_CIPHER_AES_CCM = 2,
606 ATH9K_CIPHER_CKIP = 3,
607 ATH9K_CIPHER_TKIP = 4,
608 ATH9K_CIPHER_CLR = 5,
609 ATH9K_CIPHER_MIC = 127
610};
611
612enum ath9k_ht_macmode {
613 ATH9K_HT_MACMODE_20 = 0,
614 ATH9K_HT_MACMODE_2040 = 1,
615};
616
617enum ath9k_ht_extprotspacing {
618 ATH9K_HT_EXTPROTSPACING_20 = 0,
619 ATH9K_HT_EXTPROTSPACING_25 = 1,
620};
621
622struct ath_hw;
623struct ath9k_channel;
624struct ath_rate_table;
625
626u32 ath9k_hw_gettxbuf(struct ath_hw *ah, u32 q);
627bool ath9k_hw_puttxbuf(struct ath_hw *ah, u32 q, u32 txdp);
628bool ath9k_hw_txstart(struct ath_hw *ah, u32 q);
629u32 ath9k_hw_numtxpending(struct ath_hw *ah, u32 q);
630bool ath9k_hw_updatetxtriglevel(struct ath_hw *ah, bool bIncTrigLevel);
631bool ath9k_hw_stoptxdma(struct ath_hw *ah, u32 q);
632bool ath9k_hw_filltxdesc(struct ath_hw *ah, struct ath_desc *ds,
633 u32 segLen, bool firstSeg,
634 bool lastSeg, const struct ath_desc *ds0);
635void ath9k_hw_cleartxdesc(struct ath_hw *ah, struct ath_desc *ds);
636int ath9k_hw_txprocdesc(struct ath_hw *ah, struct ath_desc *ds);
637void ath9k_hw_set11n_txdesc(struct ath_hw *ah, struct ath_desc *ds,
638 u32 pktLen, enum ath9k_pkt_type type, u32 txPower,
639 u32 keyIx, enum ath9k_key_type keyType, u32 flags);
640void ath9k_hw_set11n_ratescenario(struct ath_hw *ah, struct ath_desc *ds,
641 struct ath_desc *lastds,
642 u32 durUpdateEn, u32 rtsctsRate,
643 u32 rtsctsDuration,
644 struct ath9k_11n_rate_series series[],
645 u32 nseries, u32 flags);
646void ath9k_hw_set11n_aggr_first(struct ath_hw *ah, struct ath_desc *ds,
647 u32 aggrLen);
648void ath9k_hw_set11n_aggr_middle(struct ath_hw *ah, struct ath_desc *ds,
649 u32 numDelims);
650void ath9k_hw_set11n_aggr_last(struct ath_hw *ah, struct ath_desc *ds);
651void ath9k_hw_clr11n_aggr(struct ath_hw *ah, struct ath_desc *ds);
652void ath9k_hw_set11n_burstduration(struct ath_hw *ah, struct ath_desc *ds,
653 u32 burstDuration);
654void ath9k_hw_set11n_virtualmorefrag(struct ath_hw *ah, struct ath_desc *ds,
655 u32 vmf);
656void ath9k_hw_gettxintrtxqs(struct ath_hw *ah, u32 *txqs);
657bool ath9k_hw_set_txq_props(struct ath_hw *ah, int q,
658 const struct ath9k_tx_queue_info *qinfo);
659bool ath9k_hw_get_txq_props(struct ath_hw *ah, int q,
660 struct ath9k_tx_queue_info *qinfo);
661int ath9k_hw_setuptxqueue(struct ath_hw *ah, enum ath9k_tx_queue type,
662 const struct ath9k_tx_queue_info *qinfo);
663bool ath9k_hw_releasetxqueue(struct ath_hw *ah, u32 q);
664bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q);
665int ath9k_hw_rxprocdesc(struct ath_hw *ah, struct ath_desc *ds,
666 u32 pa, struct ath_desc *nds, u64 tsf);
667bool ath9k_hw_setuprxdesc(struct ath_hw *ah, struct ath_desc *ds,
668 u32 size, u32 flags);
669bool ath9k_hw_setrxabort(struct ath_hw *ah, bool set);
670void ath9k_hw_putrxbuf(struct ath_hw *ah, u32 rxdp);
671void ath9k_hw_rxena(struct ath_hw *ah);
672void ath9k_hw_startpcureceive(struct ath_hw *ah);
673void ath9k_hw_stoppcurecv(struct ath_hw *ah);
674bool ath9k_hw_stopdmarecv(struct ath_hw *ah);
675
676#endif /* MAC_H */
diff --git a/drivers/net/wireless/ath9k/main.c b/drivers/net/wireless/ath9k/main.c
index 1c0f893e1c0a..fc3460f8f7fc 100644
--- a/drivers/net/wireless/ath9k/main.c
+++ b/drivers/net/wireless/ath9k/main.c
@@ -15,9 +15,7 @@
15 */ 15 */
16 16
17#include <linux/nl80211.h> 17#include <linux/nl80211.h>
18#include "core.h" 18#include "ath9k.h"
19#include "reg.h"
20#include "hw.h"
21 19
22#define ATH_PCI_VERSION "0.1" 20#define ATH_PCI_VERSION "0.1"
23 21
@@ -139,14 +137,14 @@ static void ath_cache_conf_rate(struct ath_softc *sc,
139 137
140static void ath_update_txpow(struct ath_softc *sc) 138static void ath_update_txpow(struct ath_softc *sc)
141{ 139{
142 struct ath_hal *ah = sc->sc_ah; 140 struct ath_hw *ah = sc->sc_ah;
143 u32 txpow; 141 u32 txpow;
144 142
145 if (sc->sc_curtxpow != sc->sc_config.txpowlimit) { 143 if (sc->curtxpow != sc->config.txpowlimit) {
146 ath9k_hw_set_txpowerlimit(ah, sc->sc_config.txpowlimit); 144 ath9k_hw_set_txpowerlimit(ah, sc->config.txpowlimit);
147 /* read back in case value is clamped */ 145 /* read back in case value is clamped */
148 ath9k_hw_getcapability(ah, ATH9K_CAP_TXPOW, 1, &txpow); 146 ath9k_hw_getcapability(ah, ATH9K_CAP_TXPOW, 1, &txpow);
149 sc->sc_curtxpow = txpow; 147 sc->curtxpow = txpow;
150 } 148 }
151} 149}
152 150
@@ -236,7 +234,7 @@ static void ath_setup_rates(struct ath_softc *sc, enum ieee80211_band band)
236*/ 234*/
237static int ath_set_channel(struct ath_softc *sc, struct ath9k_channel *hchan) 235static int ath_set_channel(struct ath_softc *sc, struct ath9k_channel *hchan)
238{ 236{
239 struct ath_hal *ah = sc->sc_ah; 237 struct ath_hw *ah = sc->sc_ah;
240 bool fastcc = true, stopped; 238 bool fastcc = true, stopped;
241 struct ieee80211_hw *hw = sc->hw; 239 struct ieee80211_hw *hw = sc->hw;
242 struct ieee80211_channel *channel = hw->conf.channel; 240 struct ieee80211_channel *channel = hw->conf.channel;
@@ -269,7 +267,7 @@ static int ath_set_channel(struct ath_softc *sc, struct ath9k_channel *hchan)
269 267
270 DPRINTF(sc, ATH_DBG_CONFIG, 268 DPRINTF(sc, ATH_DBG_CONFIG,
271 "(%u MHz) -> (%u MHz), chanwidth: %d\n", 269 "(%u MHz) -> (%u MHz), chanwidth: %d\n",
272 sc->sc_ah->ah_curchan->channel, 270 sc->sc_ah->curchan->channel,
273 channel->center_freq, sc->tx_chan_width); 271 channel->center_freq, sc->tx_chan_width);
274 272
275 spin_lock_bh(&sc->sc_resetlock); 273 spin_lock_bh(&sc->sc_resetlock);
@@ -296,7 +294,7 @@ static int ath_set_channel(struct ath_softc *sc, struct ath9k_channel *hchan)
296 294
297 ath_cache_conf_rate(sc, &hw->conf); 295 ath_cache_conf_rate(sc, &hw->conf);
298 ath_update_txpow(sc); 296 ath_update_txpow(sc);
299 ath9k_hw_set_interrupts(ah, sc->sc_imask); 297 ath9k_hw_set_interrupts(ah, sc->imask);
300 ath9k_ps_restore(sc); 298 ath9k_ps_restore(sc);
301 return 0; 299 return 0;
302} 300}
@@ -311,7 +309,7 @@ static int ath_set_channel(struct ath_softc *sc, struct ath9k_channel *hchan)
311static void ath_ani_calibrate(unsigned long data) 309static void ath_ani_calibrate(unsigned long data)
312{ 310{
313 struct ath_softc *sc; 311 struct ath_softc *sc;
314 struct ath_hal *ah; 312 struct ath_hw *ah;
315 bool longcal = false; 313 bool longcal = false;
316 bool shortcal = false; 314 bool shortcal = false;
317 bool aniflag = false; 315 bool aniflag = false;
@@ -329,68 +327,68 @@ static void ath_ani_calibrate(unsigned long data)
329 return; 327 return;
330 328
331 /* Long calibration runs independently of short calibration. */ 329 /* Long calibration runs independently of short calibration. */
332 if ((timestamp - sc->sc_ani.sc_longcal_timer) >= ATH_LONG_CALINTERVAL) { 330 if ((timestamp - sc->ani.longcal_timer) >= ATH_LONG_CALINTERVAL) {
333 longcal = true; 331 longcal = true;
334 DPRINTF(sc, ATH_DBG_ANI, "longcal @%lu\n", jiffies); 332 DPRINTF(sc, ATH_DBG_ANI, "longcal @%lu\n", jiffies);
335 sc->sc_ani.sc_longcal_timer = timestamp; 333 sc->ani.longcal_timer = timestamp;
336 } 334 }
337 335
338 /* Short calibration applies only while sc_caldone is false */ 336 /* Short calibration applies only while caldone is false */
339 if (!sc->sc_ani.sc_caldone) { 337 if (!sc->ani.caldone) {
340 if ((timestamp - sc->sc_ani.sc_shortcal_timer) >= 338 if ((timestamp - sc->ani.shortcal_timer) >=
341 ATH_SHORT_CALINTERVAL) { 339 ATH_SHORT_CALINTERVAL) {
342 shortcal = true; 340 shortcal = true;
343 DPRINTF(sc, ATH_DBG_ANI, "shortcal @%lu\n", jiffies); 341 DPRINTF(sc, ATH_DBG_ANI, "shortcal @%lu\n", jiffies);
344 sc->sc_ani.sc_shortcal_timer = timestamp; 342 sc->ani.shortcal_timer = timestamp;
345 sc->sc_ani.sc_resetcal_timer = timestamp; 343 sc->ani.resetcal_timer = timestamp;
346 } 344 }
347 } else { 345 } else {
348 if ((timestamp - sc->sc_ani.sc_resetcal_timer) >= 346 if ((timestamp - sc->ani.resetcal_timer) >=
349 ATH_RESTART_CALINTERVAL) { 347 ATH_RESTART_CALINTERVAL) {
350 sc->sc_ani.sc_caldone = ath9k_hw_reset_calvalid(ah); 348 sc->ani.caldone = ath9k_hw_reset_calvalid(ah);
351 if (sc->sc_ani.sc_caldone) 349 if (sc->ani.caldone)
352 sc->sc_ani.sc_resetcal_timer = timestamp; 350 sc->ani.resetcal_timer = timestamp;
353 } 351 }
354 } 352 }
355 353
356 /* Verify whether we must check ANI */ 354 /* Verify whether we must check ANI */
357 if ((timestamp - sc->sc_ani.sc_checkani_timer) >= 355 if ((timestamp - sc->ani.checkani_timer) >=
358 ATH_ANI_POLLINTERVAL) { 356 ATH_ANI_POLLINTERVAL) {
359 aniflag = true; 357 aniflag = true;
360 sc->sc_ani.sc_checkani_timer = timestamp; 358 sc->ani.checkani_timer = timestamp;
361 } 359 }
362 360
363 /* Skip all processing if there's nothing to do. */ 361 /* Skip all processing if there's nothing to do. */
364 if (longcal || shortcal || aniflag) { 362 if (longcal || shortcal || aniflag) {
365 /* Call ANI routine if necessary */ 363 /* Call ANI routine if necessary */
366 if (aniflag) 364 if (aniflag)
367 ath9k_hw_ani_monitor(ah, &sc->sc_halstats, 365 ath9k_hw_ani_monitor(ah, &sc->nodestats,
368 ah->ah_curchan); 366 ah->curchan);
369 367
370 /* Perform calibration if necessary */ 368 /* Perform calibration if necessary */
371 if (longcal || shortcal) { 369 if (longcal || shortcal) {
372 bool iscaldone = false; 370 bool iscaldone = false;
373 371
374 if (ath9k_hw_calibrate(ah, ah->ah_curchan, 372 if (ath9k_hw_calibrate(ah, ah->curchan,
375 sc->sc_rx_chainmask, longcal, 373 sc->rx_chainmask, longcal,
376 &iscaldone)) { 374 &iscaldone)) {
377 if (longcal) 375 if (longcal)
378 sc->sc_ani.sc_noise_floor = 376 sc->ani.noise_floor =
379 ath9k_hw_getchan_noise(ah, 377 ath9k_hw_getchan_noise(ah,
380 ah->ah_curchan); 378 ah->curchan);
381 379
382 DPRINTF(sc, ATH_DBG_ANI, 380 DPRINTF(sc, ATH_DBG_ANI,
383 "calibrate chan %u/%x nf: %d\n", 381 "calibrate chan %u/%x nf: %d\n",
384 ah->ah_curchan->channel, 382 ah->curchan->channel,
385 ah->ah_curchan->channelFlags, 383 ah->curchan->channelFlags,
386 sc->sc_ani.sc_noise_floor); 384 sc->ani.noise_floor);
387 } else { 385 } else {
388 DPRINTF(sc, ATH_DBG_ANY, 386 DPRINTF(sc, ATH_DBG_ANY,
389 "calibrate chan %u/%x failed\n", 387 "calibrate chan %u/%x failed\n",
390 ah->ah_curchan->channel, 388 ah->curchan->channel,
391 ah->ah_curchan->channelFlags); 389 ah->curchan->channelFlags);
392 } 390 }
393 sc->sc_ani.sc_caldone = iscaldone; 391 sc->ani.caldone = iscaldone;
394 } 392 }
395 } 393 }
396 394
@@ -400,12 +398,12 @@ static void ath_ani_calibrate(unsigned long data)
400 * short calibration and long calibration. 398 * short calibration and long calibration.
401 */ 399 */
402 cal_interval = ATH_LONG_CALINTERVAL; 400 cal_interval = ATH_LONG_CALINTERVAL;
403 if (sc->sc_ah->ah_config.enable_ani) 401 if (sc->sc_ah->config.enable_ani)
404 cal_interval = min(cal_interval, (u32)ATH_ANI_POLLINTERVAL); 402 cal_interval = min(cal_interval, (u32)ATH_ANI_POLLINTERVAL);
405 if (!sc->sc_ani.sc_caldone) 403 if (!sc->ani.caldone)
406 cal_interval = min(cal_interval, (u32)ATH_SHORT_CALINTERVAL); 404 cal_interval = min(cal_interval, (u32)ATH_SHORT_CALINTERVAL);
407 405
408 mod_timer(&sc->sc_ani.timer, jiffies + msecs_to_jiffies(cal_interval)); 406 mod_timer(&sc->ani.timer, jiffies + msecs_to_jiffies(cal_interval));
409} 407}
410 408
411/* 409/*
@@ -418,16 +416,16 @@ static void ath_update_chainmask(struct ath_softc *sc, int is_ht)
418{ 416{
419 sc->sc_flags |= SC_OP_CHAINMASK_UPDATE; 417 sc->sc_flags |= SC_OP_CHAINMASK_UPDATE;
420 if (is_ht || 418 if (is_ht ||
421 (sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_BT_COEX)) { 419 (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_BT_COEX)) {
422 sc->sc_tx_chainmask = sc->sc_ah->ah_caps.tx_chainmask; 420 sc->tx_chainmask = sc->sc_ah->caps.tx_chainmask;
423 sc->sc_rx_chainmask = sc->sc_ah->ah_caps.rx_chainmask; 421 sc->rx_chainmask = sc->sc_ah->caps.rx_chainmask;
424 } else { 422 } else {
425 sc->sc_tx_chainmask = 1; 423 sc->tx_chainmask = 1;
426 sc->sc_rx_chainmask = 1; 424 sc->rx_chainmask = 1;
427 } 425 }
428 426
429 DPRINTF(sc, ATH_DBG_CONFIG, "tx chmask: %d, rx chmask: %d\n", 427 DPRINTF(sc, ATH_DBG_CONFIG, "tx chmask: %d, rx chmask: %d\n",
430 sc->sc_tx_chainmask, sc->sc_rx_chainmask); 428 sc->tx_chainmask, sc->rx_chainmask);
431} 429}
432 430
433static void ath_node_attach(struct ath_softc *sc, struct ieee80211_sta *sta) 431static void ath_node_attach(struct ath_softc *sc, struct ieee80211_sta *sta)
@@ -455,7 +453,7 @@ static void ath_node_detach(struct ath_softc *sc, struct ieee80211_sta *sta)
455static void ath9k_tasklet(unsigned long data) 453static void ath9k_tasklet(unsigned long data)
456{ 454{
457 struct ath_softc *sc = (struct ath_softc *)data; 455 struct ath_softc *sc = (struct ath_softc *)data;
458 u32 status = sc->sc_intrstatus; 456 u32 status = sc->intrstatus;
459 457
460 if (status & ATH9K_INT_FATAL) { 458 if (status & ATH9K_INT_FATAL) {
461 /* need a chip reset */ 459 /* need a chip reset */
@@ -475,13 +473,13 @@ static void ath9k_tasklet(unsigned long data)
475 } 473 }
476 474
477 /* re-enable hardware interrupt */ 475 /* re-enable hardware interrupt */
478 ath9k_hw_set_interrupts(sc->sc_ah, sc->sc_imask); 476 ath9k_hw_set_interrupts(sc->sc_ah, sc->imask);
479} 477}
480 478
481irqreturn_t ath_isr(int irq, void *dev) 479irqreturn_t ath_isr(int irq, void *dev)
482{ 480{
483 struct ath_softc *sc = dev; 481 struct ath_softc *sc = dev;
484 struct ath_hal *ah = sc->sc_ah; 482 struct ath_hw *ah = sc->sc_ah;
485 enum ath9k_int status; 483 enum ath9k_int status;
486 bool sched = false; 484 bool sched = false;
487 485
@@ -506,7 +504,7 @@ irqreturn_t ath_isr(int irq, void *dev)
506 */ 504 */
507 ath9k_hw_getisr(ah, &status); /* NB: clears ISR too */ 505 ath9k_hw_getisr(ah, &status); /* NB: clears ISR too */
508 506
509 status &= sc->sc_imask; /* discard unasked-for bits */ 507 status &= sc->imask; /* discard unasked-for bits */
510 508
511 /* 509 /*
512 * If there are no status bits set, then this interrupt was not 510 * If there are no status bits set, then this interrupt was not
@@ -515,7 +513,7 @@ irqreturn_t ath_isr(int irq, void *dev)
515 if (!status) 513 if (!status)
516 return IRQ_NONE; 514 return IRQ_NONE;
517 515
518 sc->sc_intrstatus = status; 516 sc->intrstatus = status;
519 517
520 if (status & ATH9K_INT_FATAL) { 518 if (status & ATH9K_INT_FATAL) {
521 /* need a chip reset */ 519 /* need a chip reset */
@@ -562,11 +560,11 @@ irqreturn_t ath_isr(int irq, void *dev)
562 * it will clear whatever condition caused 560 * it will clear whatever condition caused
563 * the interrupt. 561 * the interrupt.
564 */ 562 */
565 ath9k_hw_procmibevent(ah, &sc->sc_halstats); 563 ath9k_hw_procmibevent(ah, &sc->nodestats);
566 ath9k_hw_set_interrupts(ah, sc->sc_imask); 564 ath9k_hw_set_interrupts(ah, sc->imask);
567 } 565 }
568 if (status & ATH9K_INT_TIM_TIMER) { 566 if (status & ATH9K_INT_TIM_TIMER) {
569 if (!(ah->ah_caps.hw_caps & 567 if (!(ah->caps.hw_caps &
570 ATH9K_HW_CAP_AUTOSLEEP)) { 568 ATH9K_HW_CAP_AUTOSLEEP)) {
571 /* Clear RxAbort bit so that we can 569 /* Clear RxAbort bit so that we can
572 * receive frames */ 570 * receive frames */
@@ -583,7 +581,7 @@ irqreturn_t ath_isr(int irq, void *dev)
583 581
584 if (sched) { 582 if (sched) {
585 /* turn off every interrupt except SWBA */ 583 /* turn off every interrupt except SWBA */
586 ath9k_hw_set_interrupts(ah, (sc->sc_imask & ATH9K_INT_SWBA)); 584 ath9k_hw_set_interrupts(ah, (sc->imask & ATH9K_INT_SWBA));
587 tasklet_schedule(&sc->intr_tq); 585 tasklet_schedule(&sc->intr_tq);
588 } 586 }
589 587
@@ -658,7 +656,7 @@ static int ath_setkey_tkip(struct ath_softc *sc, u16 keyix, const u8 *key,
658 memcpy(hk->kv_mic, key_rxmic, sizeof(hk->kv_mic)); 656 memcpy(hk->kv_mic, key_rxmic, sizeof(hk->kv_mic));
659 return ath_keyset(sc, keyix, hk, addr); 657 return ath_keyset(sc, keyix, hk, addr);
660 } 658 }
661 if (!sc->sc_splitmic) { 659 if (!sc->splitmic) {
662 /* 660 /*
663 * data key goes at first index, 661 * data key goes at first index,
664 * the hal handles the MIC keys at index+64. 662 * the hal handles the MIC keys at index+64.
@@ -688,13 +686,13 @@ static int ath_reserve_key_cache_slot_tkip(struct ath_softc *sc)
688{ 686{
689 int i; 687 int i;
690 688
691 for (i = IEEE80211_WEP_NKID; i < sc->sc_keymax / 2; i++) { 689 for (i = IEEE80211_WEP_NKID; i < sc->keymax / 2; i++) {
692 if (test_bit(i, sc->sc_keymap) || 690 if (test_bit(i, sc->keymap) ||
693 test_bit(i + 64, sc->sc_keymap)) 691 test_bit(i + 64, sc->keymap))
694 continue; /* At least one part of TKIP key allocated */ 692 continue; /* At least one part of TKIP key allocated */
695 if (sc->sc_splitmic && 693 if (sc->splitmic &&
696 (test_bit(i + 32, sc->sc_keymap) || 694 (test_bit(i + 32, sc->keymap) ||
697 test_bit(i + 64 + 32, sc->sc_keymap))) 695 test_bit(i + 64 + 32, sc->keymap)))
698 continue; /* At least one part of TKIP key allocated */ 696 continue; /* At least one part of TKIP key allocated */
699 697
700 /* Found a free slot for a TKIP key */ 698 /* Found a free slot for a TKIP key */
@@ -708,55 +706,55 @@ static int ath_reserve_key_cache_slot(struct ath_softc *sc)
708 int i; 706 int i;
709 707
710 /* First, try to find slots that would not be available for TKIP. */ 708 /* First, try to find slots that would not be available for TKIP. */
711 if (sc->sc_splitmic) { 709 if (sc->splitmic) {
712 for (i = IEEE80211_WEP_NKID; i < sc->sc_keymax / 4; i++) { 710 for (i = IEEE80211_WEP_NKID; i < sc->keymax / 4; i++) {
713 if (!test_bit(i, sc->sc_keymap) && 711 if (!test_bit(i, sc->keymap) &&
714 (test_bit(i + 32, sc->sc_keymap) || 712 (test_bit(i + 32, sc->keymap) ||
715 test_bit(i + 64, sc->sc_keymap) || 713 test_bit(i + 64, sc->keymap) ||
716 test_bit(i + 64 + 32, sc->sc_keymap))) 714 test_bit(i + 64 + 32, sc->keymap)))
717 return i; 715 return i;
718 if (!test_bit(i + 32, sc->sc_keymap) && 716 if (!test_bit(i + 32, sc->keymap) &&
719 (test_bit(i, sc->sc_keymap) || 717 (test_bit(i, sc->keymap) ||
720 test_bit(i + 64, sc->sc_keymap) || 718 test_bit(i + 64, sc->keymap) ||
721 test_bit(i + 64 + 32, sc->sc_keymap))) 719 test_bit(i + 64 + 32, sc->keymap)))
722 return i + 32; 720 return i + 32;
723 if (!test_bit(i + 64, sc->sc_keymap) && 721 if (!test_bit(i + 64, sc->keymap) &&
724 (test_bit(i , sc->sc_keymap) || 722 (test_bit(i , sc->keymap) ||
725 test_bit(i + 32, sc->sc_keymap) || 723 test_bit(i + 32, sc->keymap) ||
726 test_bit(i + 64 + 32, sc->sc_keymap))) 724 test_bit(i + 64 + 32, sc->keymap)))
727 return i + 64; 725 return i + 64;
728 if (!test_bit(i + 64 + 32, sc->sc_keymap) && 726 if (!test_bit(i + 64 + 32, sc->keymap) &&
729 (test_bit(i, sc->sc_keymap) || 727 (test_bit(i, sc->keymap) ||
730 test_bit(i + 32, sc->sc_keymap) || 728 test_bit(i + 32, sc->keymap) ||
731 test_bit(i + 64, sc->sc_keymap))) 729 test_bit(i + 64, sc->keymap)))
732 return i + 64 + 32; 730 return i + 64 + 32;
733 } 731 }
734 } else { 732 } else {
735 for (i = IEEE80211_WEP_NKID; i < sc->sc_keymax / 2; i++) { 733 for (i = IEEE80211_WEP_NKID; i < sc->keymax / 2; i++) {
736 if (!test_bit(i, sc->sc_keymap) && 734 if (!test_bit(i, sc->keymap) &&
737 test_bit(i + 64, sc->sc_keymap)) 735 test_bit(i + 64, sc->keymap))
738 return i; 736 return i;
739 if (test_bit(i, sc->sc_keymap) && 737 if (test_bit(i, sc->keymap) &&
740 !test_bit(i + 64, sc->sc_keymap)) 738 !test_bit(i + 64, sc->keymap))
741 return i + 64; 739 return i + 64;
742 } 740 }
743 } 741 }
744 742
745 /* No partially used TKIP slots, pick any available slot */ 743 /* No partially used TKIP slots, pick any available slot */
746 for (i = IEEE80211_WEP_NKID; i < sc->sc_keymax; i++) { 744 for (i = IEEE80211_WEP_NKID; i < sc->keymax; i++) {
747 /* Do not allow slots that could be needed for TKIP group keys 745 /* Do not allow slots that could be needed for TKIP group keys
748 * to be used. This limitation could be removed if we know that 746 * to be used. This limitation could be removed if we know that
749 * TKIP will not be used. */ 747 * TKIP will not be used. */
750 if (i >= 64 && i < 64 + IEEE80211_WEP_NKID) 748 if (i >= 64 && i < 64 + IEEE80211_WEP_NKID)
751 continue; 749 continue;
752 if (sc->sc_splitmic) { 750 if (sc->splitmic) {
753 if (i >= 32 && i < 32 + IEEE80211_WEP_NKID) 751 if (i >= 32 && i < 32 + IEEE80211_WEP_NKID)
754 continue; 752 continue;
755 if (i >= 64 + 32 && i < 64 + 32 + IEEE80211_WEP_NKID) 753 if (i >= 64 + 32 && i < 64 + 32 + IEEE80211_WEP_NKID)
756 continue; 754 continue;
757 } 755 }
758 756
759 if (!test_bit(i, sc->sc_keymap)) 757 if (!test_bit(i, sc->keymap))
760 return i; /* Found a free slot for a key */ 758 return i; /* Found a free slot for a key */
761 } 759 }
762 760
@@ -803,7 +801,7 @@ static int ath_key_config(struct ath_softc *sc,
803 return -EOPNOTSUPP; 801 return -EOPNOTSUPP;
804 mac = sta->addr; 802 mac = sta->addr;
805 803
806 vif = sc->sc_vaps[0]; 804 vif = sc->vifs[0];
807 if (vif->type != NL80211_IFTYPE_AP) { 805 if (vif->type != NL80211_IFTYPE_AP) {
808 /* Only keyidx 0 should be used with unicast key, but 806 /* Only keyidx 0 should be used with unicast key, but
809 * allow this for client mode for now. */ 807 * allow this for client mode for now. */
@@ -831,12 +829,12 @@ static int ath_key_config(struct ath_softc *sc,
831 if (!ret) 829 if (!ret)
832 return -EIO; 830 return -EIO;
833 831
834 set_bit(idx, sc->sc_keymap); 832 set_bit(idx, sc->keymap);
835 if (key->alg == ALG_TKIP) { 833 if (key->alg == ALG_TKIP) {
836 set_bit(idx + 64, sc->sc_keymap); 834 set_bit(idx + 64, sc->keymap);
837 if (sc->sc_splitmic) { 835 if (sc->splitmic) {
838 set_bit(idx + 32, sc->sc_keymap); 836 set_bit(idx + 32, sc->keymap);
839 set_bit(idx + 64 + 32, sc->sc_keymap); 837 set_bit(idx + 64 + 32, sc->keymap);
840 } 838 }
841 } 839 }
842 840
@@ -849,14 +847,14 @@ static void ath_key_delete(struct ath_softc *sc, struct ieee80211_key_conf *key)
849 if (key->hw_key_idx < IEEE80211_WEP_NKID) 847 if (key->hw_key_idx < IEEE80211_WEP_NKID)
850 return; 848 return;
851 849
852 clear_bit(key->hw_key_idx, sc->sc_keymap); 850 clear_bit(key->hw_key_idx, sc->keymap);
853 if (key->alg != ALG_TKIP) 851 if (key->alg != ALG_TKIP)
854 return; 852 return;
855 853
856 clear_bit(key->hw_key_idx + 64, sc->sc_keymap); 854 clear_bit(key->hw_key_idx + 64, sc->keymap);
857 if (sc->sc_splitmic) { 855 if (sc->splitmic) {
858 clear_bit(key->hw_key_idx + 32, sc->sc_keymap); 856 clear_bit(key->hw_key_idx + 32, sc->keymap);
859 clear_bit(key->hw_key_idx + 64 + 32, sc->sc_keymap); 857 clear_bit(key->hw_key_idx + 64 + 32, sc->keymap);
860 } 858 }
861} 859}
862 860
@@ -878,7 +876,7 @@ static void setup_ht_cap(struct ath_softc *sc,
878 /* set up supported mcs set */ 876 /* set up supported mcs set */
879 memset(&ht_info->mcs, 0, sizeof(ht_info->mcs)); 877 memset(&ht_info->mcs, 0, sizeof(ht_info->mcs));
880 878
881 switch(sc->sc_rx_chainmask) { 879 switch(sc->rx_chainmask) {
882 case 1: 880 case 1:
883 ht_info->mcs.rx_mask[0] = 0xff; 881 ht_info->mcs.rx_mask[0] = 0xff;
884 break; 882 break;
@@ -898,17 +896,16 @@ static void ath9k_bss_assoc_info(struct ath_softc *sc,
898 struct ieee80211_vif *vif, 896 struct ieee80211_vif *vif,
899 struct ieee80211_bss_conf *bss_conf) 897 struct ieee80211_bss_conf *bss_conf)
900{ 898{
901 struct ath_vap *avp = (void *)vif->drv_priv; 899 struct ath_vif *avp = (void *)vif->drv_priv;
902 900
903 if (bss_conf->assoc) { 901 if (bss_conf->assoc) {
904 DPRINTF(sc, ATH_DBG_CONFIG, "Bss Info ASSOC %d, bssid: %pM\n", 902 DPRINTF(sc, ATH_DBG_CONFIG, "Bss Info ASSOC %d, bssid: %pM\n",
905 bss_conf->aid, sc->sc_curbssid); 903 bss_conf->aid, sc->curbssid);
906 904
907 /* New association, store aid */ 905 /* New association, store aid */
908 if (avp->av_opmode == NL80211_IFTYPE_STATION) { 906 if (avp->av_opmode == NL80211_IFTYPE_STATION) {
909 sc->sc_curaid = bss_conf->aid; 907 sc->curaid = bss_conf->aid;
910 ath9k_hw_write_associd(sc->sc_ah, sc->sc_curbssid, 908 ath9k_hw_write_associd(sc);
911 sc->sc_curaid);
912 } 909 }
913 910
914 /* Configure the beacon */ 911 /* Configure the beacon */
@@ -916,18 +913,18 @@ static void ath9k_bss_assoc_info(struct ath_softc *sc,
916 sc->sc_flags |= SC_OP_BEACONS; 913 sc->sc_flags |= SC_OP_BEACONS;
917 914
918 /* Reset rssi stats */ 915 /* Reset rssi stats */
919 sc->sc_halstats.ns_avgbrssi = ATH_RSSI_DUMMY_MARKER; 916 sc->nodestats.ns_avgbrssi = ATH_RSSI_DUMMY_MARKER;
920 sc->sc_halstats.ns_avgrssi = ATH_RSSI_DUMMY_MARKER; 917 sc->nodestats.ns_avgrssi = ATH_RSSI_DUMMY_MARKER;
921 sc->sc_halstats.ns_avgtxrssi = ATH_RSSI_DUMMY_MARKER; 918 sc->nodestats.ns_avgtxrssi = ATH_RSSI_DUMMY_MARKER;
922 sc->sc_halstats.ns_avgtxrate = ATH_RATE_DUMMY_MARKER; 919 sc->nodestats.ns_avgtxrate = ATH_RATE_DUMMY_MARKER;
923 920
924 /* Start ANI */ 921 /* Start ANI */
925 mod_timer(&sc->sc_ani.timer, 922 mod_timer(&sc->ani.timer,
926 jiffies + msecs_to_jiffies(ATH_ANI_POLLINTERVAL)); 923 jiffies + msecs_to_jiffies(ATH_ANI_POLLINTERVAL));
927 924
928 } else { 925 } else {
929 DPRINTF(sc, ATH_DBG_CONFIG, "Bss Info DISSOC\n"); 926 DPRINTF(sc, ATH_DBG_CONFIG, "Bss Info DISSOC\n");
930 sc->sc_curaid = 0; 927 sc->curaid = 0;
931 } 928 }
932} 929}
933 930
@@ -1094,14 +1091,14 @@ fail:
1094 1091
1095static void ath_radio_enable(struct ath_softc *sc) 1092static void ath_radio_enable(struct ath_softc *sc)
1096{ 1093{
1097 struct ath_hal *ah = sc->sc_ah; 1094 struct ath_hw *ah = sc->sc_ah;
1098 struct ieee80211_channel *channel = sc->hw->conf.channel; 1095 struct ieee80211_channel *channel = sc->hw->conf.channel;
1099 int r; 1096 int r;
1100 1097
1101 ath9k_ps_wakeup(sc); 1098 ath9k_ps_wakeup(sc);
1102 spin_lock_bh(&sc->sc_resetlock); 1099 spin_lock_bh(&sc->sc_resetlock);
1103 1100
1104 r = ath9k_hw_reset(ah, ah->ah_curchan, false); 1101 r = ath9k_hw_reset(ah, ah->curchan, false);
1105 1102
1106 if (r) { 1103 if (r) {
1107 DPRINTF(sc, ATH_DBG_FATAL, 1104 DPRINTF(sc, ATH_DBG_FATAL,
@@ -1122,7 +1119,7 @@ static void ath_radio_enable(struct ath_softc *sc)
1122 ath_beacon_config(sc, ATH_IF_ID_ANY); /* restart beacons */ 1119 ath_beacon_config(sc, ATH_IF_ID_ANY); /* restart beacons */
1123 1120
1124 /* Re-Enable interrupts */ 1121 /* Re-Enable interrupts */
1125 ath9k_hw_set_interrupts(ah, sc->sc_imask); 1122 ath9k_hw_set_interrupts(ah, sc->imask);
1126 1123
1127 /* Enable LED */ 1124 /* Enable LED */
1128 ath9k_hw_cfg_output(ah, ATH_LED_PIN, 1125 ath9k_hw_cfg_output(ah, ATH_LED_PIN,
@@ -1135,7 +1132,7 @@ static void ath_radio_enable(struct ath_softc *sc)
1135 1132
1136static void ath_radio_disable(struct ath_softc *sc) 1133static void ath_radio_disable(struct ath_softc *sc)
1137{ 1134{
1138 struct ath_hal *ah = sc->sc_ah; 1135 struct ath_hw *ah = sc->sc_ah;
1139 struct ieee80211_channel *channel = sc->hw->conf.channel; 1136 struct ieee80211_channel *channel = sc->hw->conf.channel;
1140 int r; 1137 int r;
1141 1138
@@ -1154,7 +1151,7 @@ static void ath_radio_disable(struct ath_softc *sc)
1154 ath_flushrecv(sc); /* flush recv queue */ 1151 ath_flushrecv(sc); /* flush recv queue */
1155 1152
1156 spin_lock_bh(&sc->sc_resetlock); 1153 spin_lock_bh(&sc->sc_resetlock);
1157 r = ath9k_hw_reset(ah, ah->ah_curchan, false); 1154 r = ath9k_hw_reset(ah, ah->curchan, false);
1158 if (r) { 1155 if (r) {
1159 DPRINTF(sc, ATH_DBG_FATAL, 1156 DPRINTF(sc, ATH_DBG_FATAL,
1160 "Unable to reset channel %u (%uMhz) " 1157 "Unable to reset channel %u (%uMhz) "
@@ -1170,10 +1167,10 @@ static void ath_radio_disable(struct ath_softc *sc)
1170 1167
1171static bool ath_is_rfkill_set(struct ath_softc *sc) 1168static bool ath_is_rfkill_set(struct ath_softc *sc)
1172{ 1169{
1173 struct ath_hal *ah = sc->sc_ah; 1170 struct ath_hw *ah = sc->sc_ah;
1174 1171
1175 return ath9k_hw_gpio_get(ah, ah->ah_rfkill_gpio) == 1172 return ath9k_hw_gpio_get(ah, ah->rfkill_gpio) ==
1176 ah->ah_rfkill_polarity; 1173 ah->rfkill_polarity;
1177} 1174}
1178 1175
1179/* h/w rfkill poll function */ 1176/* h/w rfkill poll function */
@@ -1270,7 +1267,7 @@ static int ath_init_sw_rfkill(struct ath_softc *sc)
1270/* Deinitialize rfkill */ 1267/* Deinitialize rfkill */
1271static void ath_deinit_rfkill(struct ath_softc *sc) 1268static void ath_deinit_rfkill(struct ath_softc *sc)
1272{ 1269{
1273 if (sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_RFSILENT) 1270 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
1274 cancel_delayed_work_sync(&sc->rf_kill.rfkill_poll); 1271 cancel_delayed_work_sync(&sc->rf_kill.rfkill_poll);
1275 1272
1276 if (sc->sc_flags & SC_OP_RFKILL_REGISTERED) { 1273 if (sc->sc_flags & SC_OP_RFKILL_REGISTERED) {
@@ -1282,7 +1279,7 @@ static void ath_deinit_rfkill(struct ath_softc *sc)
1282 1279
1283static int ath_start_rfkill_poll(struct ath_softc *sc) 1280static int ath_start_rfkill_poll(struct ath_softc *sc)
1284{ 1281{
1285 if (sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_RFSILENT) 1282 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
1286 queue_delayed_work(sc->hw->workqueue, 1283 queue_delayed_work(sc->hw->workqueue,
1287 &sc->rf_kill.rfkill_poll, 0); 1284 &sc->rf_kill.rfkill_poll, 0);
1288 1285
@@ -1348,7 +1345,7 @@ void ath_detach(struct ath_softc *sc)
1348 1345
1349static int ath_init(u16 devid, struct ath_softc *sc) 1346static int ath_init(u16 devid, struct ath_softc *sc)
1350{ 1347{
1351 struct ath_hal *ah = NULL; 1348 struct ath_hw *ah = NULL;
1352 int status; 1349 int status;
1353 int error = 0, i; 1350 int error = 0, i;
1354 int csz = 0; 1351 int csz = 0;
@@ -1371,9 +1368,9 @@ static int ath_init(u16 devid, struct ath_softc *sc)
1371 */ 1368 */
1372 ath_read_cachesize(sc, &csz); 1369 ath_read_cachesize(sc, &csz);
1373 /* XXX assert csz is non-zero */ 1370 /* XXX assert csz is non-zero */
1374 sc->sc_cachelsz = csz << 2; /* convert to bytes */ 1371 sc->cachelsz = csz << 2; /* convert to bytes */
1375 1372
1376 ah = ath9k_hw_attach(devid, sc, sc->mem, &status); 1373 ah = ath9k_hw_attach(devid, sc, &status);
1377 if (ah == NULL) { 1374 if (ah == NULL) {
1378 DPRINTF(sc, ATH_DBG_FATAL, 1375 DPRINTF(sc, ATH_DBG_FATAL,
1379 "Unable to attach hardware; HAL status %d\n", status); 1376 "Unable to attach hardware; HAL status %d\n", status);
@@ -1383,26 +1380,26 @@ static int ath_init(u16 devid, struct ath_softc *sc)
1383 sc->sc_ah = ah; 1380 sc->sc_ah = ah;
1384 1381
1385 /* Get the hardware key cache size. */ 1382 /* Get the hardware key cache size. */
1386 sc->sc_keymax = ah->ah_caps.keycache_size; 1383 sc->keymax = ah->caps.keycache_size;
1387 if (sc->sc_keymax > ATH_KEYMAX) { 1384 if (sc->keymax > ATH_KEYMAX) {
1388 DPRINTF(sc, ATH_DBG_KEYCACHE, 1385 DPRINTF(sc, ATH_DBG_KEYCACHE,
1389 "Warning, using only %u entries in %u key cache\n", 1386 "Warning, using only %u entries in %u key cache\n",
1390 ATH_KEYMAX, sc->sc_keymax); 1387 ATH_KEYMAX, sc->keymax);
1391 sc->sc_keymax = ATH_KEYMAX; 1388 sc->keymax = ATH_KEYMAX;
1392 } 1389 }
1393 1390
1394 /* 1391 /*
1395 * Reset the key cache since some parts do not 1392 * Reset the key cache since some parts do not
1396 * reset the contents on initial power up. 1393 * reset the contents on initial power up.
1397 */ 1394 */
1398 for (i = 0; i < sc->sc_keymax; i++) 1395 for (i = 0; i < sc->keymax; i++)
1399 ath9k_hw_keyreset(ah, (u16) i); 1396 ath9k_hw_keyreset(ah, (u16) i);
1400 1397
1401 if (ath9k_regd_init(sc->sc_ah)) 1398 if (ath9k_regd_init(sc->sc_ah))
1402 goto bad; 1399 goto bad;
1403 1400
1404 /* default to MONITOR mode */ 1401 /* default to MONITOR mode */
1405 sc->sc_ah->ah_opmode = NL80211_IFTYPE_MONITOR; 1402 sc->sc_ah->opmode = NL80211_IFTYPE_MONITOR;
1406 1403
1407 /* Setup rate tables */ 1404 /* Setup rate tables */
1408 1405
@@ -1431,7 +1428,7 @@ static int ath_init(u16 devid, struct ath_softc *sc)
1431 goto bad2; 1428 goto bad2;
1432 } 1429 }
1433 1430
1434 sc->sc_config.cabqReadytime = ATH_CABQ_READY_TIME; 1431 sc->config.cabqReadytime = ATH_CABQ_READY_TIME;
1435 ath_cabq_update(sc); 1432 ath_cabq_update(sc);
1436 1433
1437 for (i = 0; i < ARRAY_SIZE(sc->tx.hwq_map); i++) 1434 for (i = 0; i < ARRAY_SIZE(sc->tx.hwq_map); i++)
@@ -1468,8 +1465,8 @@ static int ath_init(u16 devid, struct ath_softc *sc)
1468 /* Initializes the noise floor to a reasonable default value. 1465 /* Initializes the noise floor to a reasonable default value.
1469 * Later on this will be updated during ANI processing. */ 1466 * Later on this will be updated during ANI processing. */
1470 1467
1471 sc->sc_ani.sc_noise_floor = ATH_DEFAULT_NOISE_FLOOR; 1468 sc->ani.noise_floor = ATH_DEFAULT_NOISE_FLOOR;
1472 setup_timer(&sc->sc_ani.timer, ath_ani_calibrate, (unsigned long)sc); 1469 setup_timer(&sc->ani.timer, ath_ani_calibrate, (unsigned long)sc);
1473 1470
1474 if (ath9k_hw_getcapability(ah, ATH9K_CAP_CIPHER, 1471 if (ath9k_hw_getcapability(ah, ATH9K_CAP_CIPHER,
1475 ATH9K_CIPHER_TKIP, NULL)) { 1472 ATH9K_CIPHER_TKIP, NULL)) {
@@ -1495,33 +1492,31 @@ static int ath_init(u16 devid, struct ath_softc *sc)
1495 ATH9K_CIPHER_MIC, NULL) 1492 ATH9K_CIPHER_MIC, NULL)
1496 && ath9k_hw_getcapability(ah, ATH9K_CAP_TKIP_SPLIT, 1493 && ath9k_hw_getcapability(ah, ATH9K_CAP_TKIP_SPLIT,
1497 0, NULL)) 1494 0, NULL))
1498 sc->sc_splitmic = 1; 1495 sc->splitmic = 1;
1499 1496
1500 /* turn on mcast key search if possible */ 1497 /* turn on mcast key search if possible */
1501 if (!ath9k_hw_getcapability(ah, ATH9K_CAP_MCAST_KEYSRCH, 0, NULL)) 1498 if (!ath9k_hw_getcapability(ah, ATH9K_CAP_MCAST_KEYSRCH, 0, NULL))
1502 (void)ath9k_hw_setcapability(ah, ATH9K_CAP_MCAST_KEYSRCH, 1, 1499 (void)ath9k_hw_setcapability(ah, ATH9K_CAP_MCAST_KEYSRCH, 1,
1503 1, NULL); 1500 1, NULL);
1504 1501
1505 sc->sc_config.txpowlimit = ATH_TXPOWER_MAX; 1502 sc->config.txpowlimit = ATH_TXPOWER_MAX;
1506 sc->sc_config.txpowlimit_override = 0;
1507 1503
1508 /* 11n Capabilities */ 1504 /* 11n Capabilities */
1509 if (ah->ah_caps.hw_caps & ATH9K_HW_CAP_HT) { 1505 if (ah->caps.hw_caps & ATH9K_HW_CAP_HT) {
1510 sc->sc_flags |= SC_OP_TXAGGR; 1506 sc->sc_flags |= SC_OP_TXAGGR;
1511 sc->sc_flags |= SC_OP_RXAGGR; 1507 sc->sc_flags |= SC_OP_RXAGGR;
1512 } 1508 }
1513 1509
1514 sc->sc_tx_chainmask = ah->ah_caps.tx_chainmask; 1510 sc->tx_chainmask = ah->caps.tx_chainmask;
1515 sc->sc_rx_chainmask = ah->ah_caps.rx_chainmask; 1511 sc->rx_chainmask = ah->caps.rx_chainmask;
1516 1512
1517 ath9k_hw_setcapability(ah, ATH9K_CAP_DIVERSITY, 1, true, NULL); 1513 ath9k_hw_setcapability(ah, ATH9K_CAP_DIVERSITY, 1, true, NULL);
1518 sc->rx.defant = ath9k_hw_getdefantenna(ah); 1514 sc->rx.defant = ath9k_hw_getdefantenna(ah);
1519 1515
1520 ath9k_hw_getmac(ah, sc->sc_myaddr); 1516 if (ah->caps.hw_caps & ATH9K_HW_CAP_BSSIDMASK) {
1521 if (ah->ah_caps.hw_caps & ATH9K_HW_CAP_BSSIDMASK) { 1517 memcpy(sc->bssidmask, ath_bcast_mac, ETH_ALEN);
1522 ath9k_hw_getbssidmask(ah, sc->sc_bssidmask); 1518 ATH_SET_VIF_BSSID_MASK(sc->bssidmask);
1523 ATH_SET_VAP_BSSID_MASK(sc->sc_bssidmask); 1519 ath9k_hw_setbssidmask(sc);
1524 ath9k_hw_setbssidmask(ah, sc->sc_bssidmask);
1525 } 1520 }
1526 1521
1527 sc->beacon.slottime = ATH9K_SLOT_TIME_9; /* default to short slot time */ 1522 sc->beacon.slottime = ATH9K_SLOT_TIME_9; /* default to short slot time */
@@ -1531,7 +1526,7 @@ static int ath_init(u16 devid, struct ath_softc *sc)
1531 sc->beacon.bslot[i] = ATH_IF_ID_ANY; 1526 sc->beacon.bslot[i] = ATH_IF_ID_ANY;
1532 1527
1533 /* save MISC configurations */ 1528 /* save MISC configurations */
1534 sc->sc_config.swBeaconProcess = 1; 1529 sc->config.swBeaconProcess = 1;
1535 1530
1536 /* setup channels and rates */ 1531 /* setup channels and rates */
1537 1532
@@ -1542,7 +1537,7 @@ static int ath_init(u16 devid, struct ath_softc *sc)
1542 sc->sbands[IEEE80211_BAND_2GHZ].n_channels = 1537 sc->sbands[IEEE80211_BAND_2GHZ].n_channels =
1543 ARRAY_SIZE(ath9k_2ghz_chantable); 1538 ARRAY_SIZE(ath9k_2ghz_chantable);
1544 1539
1545 if (test_bit(ATH9K_MODE_11A, sc->sc_ah->ah_caps.wireless_modes)) { 1540 if (test_bit(ATH9K_MODE_11A, sc->sc_ah->caps.wireless_modes)) {
1546 sc->sbands[IEEE80211_BAND_5GHZ].channels = ath9k_5ghz_chantable; 1541 sc->sbands[IEEE80211_BAND_5GHZ].channels = ath9k_5ghz_chantable;
1547 sc->sbands[IEEE80211_BAND_5GHZ].bitrates = 1542 sc->sbands[IEEE80211_BAND_5GHZ].bitrates =
1548 sc->rates[IEEE80211_BAND_5GHZ]; 1543 sc->rates[IEEE80211_BAND_5GHZ];
@@ -1551,7 +1546,7 @@ static int ath_init(u16 devid, struct ath_softc *sc)
1551 ARRAY_SIZE(ath9k_5ghz_chantable); 1546 ARRAY_SIZE(ath9k_5ghz_chantable);
1552 } 1547 }
1553 1548
1554 if (sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_BT_COEX) 1549 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_BT_COEX)
1555 ath9k_hw_btcoex_enable(sc->sc_ah); 1550 ath9k_hw_btcoex_enable(sc->sc_ah);
1556 1551
1557 return 0; 1552 return 0;
@@ -1580,7 +1575,7 @@ int ath_attach(u16 devid, struct ath_softc *sc)
1580 1575
1581 /* get mac address from hardware and set in mac80211 */ 1576 /* get mac address from hardware and set in mac80211 */
1582 1577
1583 SET_IEEE80211_PERM_ADDR(hw, sc->sc_myaddr); 1578 SET_IEEE80211_PERM_ADDR(hw, sc->sc_ah->macaddr);
1584 1579
1585 hw->flags = IEEE80211_HW_RX_INCLUDES_FCS | 1580 hw->flags = IEEE80211_HW_RX_INCLUDES_FCS |
1586 IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | 1581 IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
@@ -1604,18 +1599,18 @@ int ath_attach(u16 devid, struct ath_softc *sc)
1604 hw->max_rates = 4; 1599 hw->max_rates = 4;
1605 hw->max_rate_tries = ATH_11N_TXMAXTRY; 1600 hw->max_rate_tries = ATH_11N_TXMAXTRY;
1606 hw->sta_data_size = sizeof(struct ath_node); 1601 hw->sta_data_size = sizeof(struct ath_node);
1607 hw->vif_data_size = sizeof(struct ath_vap); 1602 hw->vif_data_size = sizeof(struct ath_vif);
1608 1603
1609 hw->rate_control_algorithm = "ath9k_rate_control"; 1604 hw->rate_control_algorithm = "ath9k_rate_control";
1610 1605
1611 if (sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_HT) { 1606 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) {
1612 setup_ht_cap(sc, &sc->sbands[IEEE80211_BAND_2GHZ].ht_cap); 1607 setup_ht_cap(sc, &sc->sbands[IEEE80211_BAND_2GHZ].ht_cap);
1613 if (test_bit(ATH9K_MODE_11A, sc->sc_ah->ah_caps.wireless_modes)) 1608 if (test_bit(ATH9K_MODE_11A, sc->sc_ah->caps.wireless_modes))
1614 setup_ht_cap(sc, &sc->sbands[IEEE80211_BAND_5GHZ].ht_cap); 1609 setup_ht_cap(sc, &sc->sbands[IEEE80211_BAND_5GHZ].ht_cap);
1615 } 1610 }
1616 1611
1617 hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &sc->sbands[IEEE80211_BAND_2GHZ]; 1612 hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &sc->sbands[IEEE80211_BAND_2GHZ];
1618 if (test_bit(ATH9K_MODE_11A, sc->sc_ah->ah_caps.wireless_modes)) 1613 if (test_bit(ATH9K_MODE_11A, sc->sc_ah->caps.wireless_modes))
1619 hw->wiphy->bands[IEEE80211_BAND_5GHZ] = 1614 hw->wiphy->bands[IEEE80211_BAND_5GHZ] =
1620 &sc->sbands[IEEE80211_BAND_5GHZ]; 1615 &sc->sbands[IEEE80211_BAND_5GHZ];
1621 1616
@@ -1630,7 +1625,7 @@ int ath_attach(u16 devid, struct ath_softc *sc)
1630 1625
1631#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE) 1626#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
1632 /* Initialze h/w Rfkill */ 1627 /* Initialze h/w Rfkill */
1633 if (sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_RFSILENT) 1628 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
1634 INIT_DELAYED_WORK(&sc->rf_kill.rfkill_poll, ath_rfkill_poll); 1629 INIT_DELAYED_WORK(&sc->rf_kill.rfkill_poll, ath_rfkill_poll);
1635 1630
1636 /* Initialize s/w rfkill */ 1631 /* Initialize s/w rfkill */
@@ -1662,7 +1657,7 @@ int ath_attach(u16 devid, struct ath_softc *sc)
1662 error = ieee80211_register_hw(hw); 1657 error = ieee80211_register_hw(hw);
1663 1658
1664 if (!ath9k_is_world_regd(sc->sc_ah)) 1659 if (!ath9k_is_world_regd(sc->sc_ah))
1665 regulatory_hint(hw->wiphy, sc->sc_ah->alpha2); 1660 regulatory_hint(hw->wiphy, sc->sc_ah->regulatory.alpha2);
1666 1661
1667 /* Initialize LED control */ 1662 /* Initialize LED control */
1668 ath_init_leds(sc); 1663 ath_init_leds(sc);
@@ -1676,7 +1671,7 @@ detach:
1676 1671
1677int ath_reset(struct ath_softc *sc, bool retry_tx) 1672int ath_reset(struct ath_softc *sc, bool retry_tx)
1678{ 1673{
1679 struct ath_hal *ah = sc->sc_ah; 1674 struct ath_hw *ah = sc->sc_ah;
1680 struct ieee80211_hw *hw = sc->hw; 1675 struct ieee80211_hw *hw = sc->hw;
1681 int r; 1676 int r;
1682 1677
@@ -1686,7 +1681,7 @@ int ath_reset(struct ath_softc *sc, bool retry_tx)
1686 ath_flushrecv(sc); 1681 ath_flushrecv(sc);
1687 1682
1688 spin_lock_bh(&sc->sc_resetlock); 1683 spin_lock_bh(&sc->sc_resetlock);
1689 r = ath9k_hw_reset(ah, sc->sc_ah->ah_curchan, false); 1684 r = ath9k_hw_reset(ah, sc->sc_ah->curchan, false);
1690 if (r) 1685 if (r)
1691 DPRINTF(sc, ATH_DBG_FATAL, 1686 DPRINTF(sc, ATH_DBG_FATAL,
1692 "Unable to reset hardware; reset status %u\n", r); 1687 "Unable to reset hardware; reset status %u\n", r);
@@ -1707,7 +1702,7 @@ int ath_reset(struct ath_softc *sc, bool retry_tx)
1707 if (sc->sc_flags & SC_OP_BEACONS) 1702 if (sc->sc_flags & SC_OP_BEACONS)
1708 ath_beacon_config(sc, ATH_IF_ID_ANY); /* restart beacons */ 1703 ath_beacon_config(sc, ATH_IF_ID_ANY); /* restart beacons */
1709 1704
1710 ath9k_hw_set_interrupts(ah, sc->sc_imask); 1705 ath9k_hw_set_interrupts(ah, sc->imask);
1711 1706
1712 if (retry_tx) { 1707 if (retry_tx) {
1713 int i; 1708 int i;
@@ -1760,7 +1755,7 @@ int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd,
1760 * descriptors that cross the 4K page boundary. Assume 1755 * descriptors that cross the 4K page boundary. Assume
1761 * one skipped descriptor per 4K page. 1756 * one skipped descriptor per 4K page.
1762 */ 1757 */
1763 if (!(sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_4KB_SPLITTRANS)) { 1758 if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_4KB_SPLITTRANS)) {
1764 u32 ndesc_skipped = 1759 u32 ndesc_skipped =
1765 ATH_DESC_4KB_BOUND_NUM_SKIPPED(dd->dd_desc_len); 1760 ATH_DESC_4KB_BOUND_NUM_SKIPPED(dd->dd_desc_len);
1766 u32 dma_len; 1761 u32 dma_len;
@@ -1800,7 +1795,7 @@ int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd,
1800 bf->bf_desc = ds; 1795 bf->bf_desc = ds;
1801 bf->bf_daddr = DS2PHYS(dd, ds); 1796 bf->bf_daddr = DS2PHYS(dd, ds);
1802 1797
1803 if (!(sc->sc_ah->ah_caps.hw_caps & 1798 if (!(sc->sc_ah->caps.hw_caps &
1804 ATH9K_HW_CAP_4KB_SPLITTRANS)) { 1799 ATH9K_HW_CAP_4KB_SPLITTRANS)) {
1805 /* 1800 /*
1806 * Skip descriptor addresses which can cause 4KB 1801 * Skip descriptor addresses which can cause 4KB
@@ -1938,11 +1933,13 @@ static int ath9k_start(struct ieee80211_hw *hw)
1938 DPRINTF(sc, ATH_DBG_CONFIG, "Starting driver with " 1933 DPRINTF(sc, ATH_DBG_CONFIG, "Starting driver with "
1939 "initial channel: %d MHz\n", curchan->center_freq); 1934 "initial channel: %d MHz\n", curchan->center_freq);
1940 1935
1936 mutex_lock(&sc->mutex);
1937
1941 /* setup initial channel */ 1938 /* setup initial channel */
1942 1939
1943 pos = curchan->hw_value; 1940 pos = curchan->hw_value;
1944 1941
1945 init_channel = &sc->sc_ah->ah_channels[pos]; 1942 init_channel = &sc->sc_ah->channels[pos];
1946 ath9k_update_ichannel(sc, init_channel); 1943 ath9k_update_ichannel(sc, init_channel);
1947 1944
1948 /* Reset SERDES registers */ 1945 /* Reset SERDES registers */
@@ -1963,7 +1960,7 @@ static int ath9k_start(struct ieee80211_hw *hw)
1963 "(freq %u MHz)\n", r, 1960 "(freq %u MHz)\n", r,
1964 curchan->center_freq); 1961 curchan->center_freq);
1965 spin_unlock_bh(&sc->sc_resetlock); 1962 spin_unlock_bh(&sc->sc_resetlock);
1966 return r; 1963 goto mutex_unlock;
1967 } 1964 }
1968 spin_unlock_bh(&sc->sc_resetlock); 1965 spin_unlock_bh(&sc->sc_resetlock);
1969 1966
@@ -1983,33 +1980,38 @@ static int ath9k_start(struct ieee80211_hw *hw)
1983 if (ath_startrecv(sc) != 0) { 1980 if (ath_startrecv(sc) != 0) {
1984 DPRINTF(sc, ATH_DBG_FATAL, 1981 DPRINTF(sc, ATH_DBG_FATAL,
1985 "Unable to start recv logic\n"); 1982 "Unable to start recv logic\n");
1986 return -EIO; 1983 r = -EIO;
1984 goto mutex_unlock;
1987 } 1985 }
1988 1986
1989 /* Setup our intr mask. */ 1987 /* Setup our intr mask. */
1990 sc->sc_imask = ATH9K_INT_RX | ATH9K_INT_TX 1988 sc->imask = ATH9K_INT_RX | ATH9K_INT_TX
1991 | ATH9K_INT_RXEOL | ATH9K_INT_RXORN 1989 | ATH9K_INT_RXEOL | ATH9K_INT_RXORN
1992 | ATH9K_INT_FATAL | ATH9K_INT_GLOBAL; 1990 | ATH9K_INT_FATAL | ATH9K_INT_GLOBAL;
1993 1991
1994 if (sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_GTT) 1992 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_GTT)
1995 sc->sc_imask |= ATH9K_INT_GTT; 1993 sc->imask |= ATH9K_INT_GTT;
1996 1994
1997 if (sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_HT) 1995 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT)
1998 sc->sc_imask |= ATH9K_INT_CST; 1996 sc->imask |= ATH9K_INT_CST;
1999 1997
2000 ath_cache_conf_rate(sc, &hw->conf); 1998 ath_cache_conf_rate(sc, &hw->conf);
2001 1999
2002 sc->sc_flags &= ~SC_OP_INVALID; 2000 sc->sc_flags &= ~SC_OP_INVALID;
2003 2001
2004 /* Disable BMISS interrupt when we're not associated */ 2002 /* Disable BMISS interrupt when we're not associated */
2005 sc->sc_imask &= ~(ATH9K_INT_SWBA | ATH9K_INT_BMISS); 2003 sc->imask &= ~(ATH9K_INT_SWBA | ATH9K_INT_BMISS);
2006 ath9k_hw_set_interrupts(sc->sc_ah, sc->sc_imask); 2004 ath9k_hw_set_interrupts(sc->sc_ah, sc->imask);
2007 2005
2008 ieee80211_wake_queues(sc->hw); 2006 ieee80211_wake_queues(sc->hw);
2009 2007
2010#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE) 2008#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
2011 r = ath_start_rfkill_poll(sc); 2009 r = ath_start_rfkill_poll(sc);
2012#endif 2010#endif
2011
2012mutex_unlock:
2013 mutex_unlock(&sc->mutex);
2014
2013 return r; 2015 return r;
2014} 2016}
2015 2017
@@ -2074,7 +2076,7 @@ static void ath9k_stop(struct ieee80211_hw *hw)
2074 return; 2076 return;
2075 } 2077 }
2076 2078
2077 DPRINTF(sc, ATH_DBG_CONFIG, "Cleaning up\n"); 2079 mutex_lock(&sc->mutex);
2078 2080
2079 ieee80211_stop_queues(sc->hw); 2081 ieee80211_stop_queues(sc->hw);
2080 2082
@@ -2090,7 +2092,7 @@ static void ath9k_stop(struct ieee80211_hw *hw)
2090 sc->rx.rxlink = NULL; 2092 sc->rx.rxlink = NULL;
2091 2093
2092#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE) 2094#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
2093 if (sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_RFSILENT) 2095 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
2094 cancel_delayed_work_sync(&sc->rf_kill.rfkill_poll); 2096 cancel_delayed_work_sync(&sc->rf_kill.rfkill_poll);
2095#endif 2097#endif
2096 /* disable HAL and put h/w to sleep */ 2098 /* disable HAL and put h/w to sleep */
@@ -2099,6 +2101,8 @@ static void ath9k_stop(struct ieee80211_hw *hw)
2099 2101
2100 sc->sc_flags |= SC_OP_INVALID; 2102 sc->sc_flags |= SC_OP_INVALID;
2101 2103
2104 mutex_unlock(&sc->mutex);
2105
2102 DPRINTF(sc, ATH_DBG_CONFIG, "Driver halt\n"); 2106 DPRINTF(sc, ATH_DBG_CONFIG, "Driver halt\n");
2103} 2107}
2104 2108
@@ -2106,14 +2110,16 @@ static int ath9k_add_interface(struct ieee80211_hw *hw,
2106 struct ieee80211_if_init_conf *conf) 2110 struct ieee80211_if_init_conf *conf)
2107{ 2111{
2108 struct ath_softc *sc = hw->priv; 2112 struct ath_softc *sc = hw->priv;
2109 struct ath_vap *avp = (void *)conf->vif->drv_priv; 2113 struct ath_vif *avp = (void *)conf->vif->drv_priv;
2110 enum nl80211_iftype ic_opmode = NL80211_IFTYPE_UNSPECIFIED; 2114 enum nl80211_iftype ic_opmode = NL80211_IFTYPE_UNSPECIFIED;
2111 2115
2112 /* Support only vap for now */ 2116 /* Support only vif for now */
2113 2117
2114 if (sc->sc_nvaps) 2118 if (sc->nvifs)
2115 return -ENOBUFS; 2119 return -ENOBUFS;
2116 2120
2121 mutex_lock(&sc->mutex);
2122
2117 switch (conf->type) { 2123 switch (conf->type) {
2118 case NL80211_IFTYPE_STATION: 2124 case NL80211_IFTYPE_STATION:
2119 ic_opmode = NL80211_IFTYPE_STATION; 2125 ic_opmode = NL80211_IFTYPE_STATION;
@@ -2130,20 +2136,20 @@ static int ath9k_add_interface(struct ieee80211_hw *hw,
2130 return -EOPNOTSUPP; 2136 return -EOPNOTSUPP;
2131 } 2137 }
2132 2138
2133 DPRINTF(sc, ATH_DBG_CONFIG, "Attach a VAP of type: %d\n", ic_opmode); 2139 DPRINTF(sc, ATH_DBG_CONFIG, "Attach a VIF of type: %d\n", ic_opmode);
2134 2140
2135 /* Set the VAP opmode */ 2141 /* Set the VIF opmode */
2136 avp->av_opmode = ic_opmode; 2142 avp->av_opmode = ic_opmode;
2137 avp->av_bslot = -1; 2143 avp->av_bslot = -1;
2138 2144
2139 if (ic_opmode == NL80211_IFTYPE_AP) 2145 if (ic_opmode == NL80211_IFTYPE_AP)
2140 ath9k_hw_set_tsfadjust(sc->sc_ah, 1); 2146 ath9k_hw_set_tsfadjust(sc->sc_ah, 1);
2141 2147
2142 sc->sc_vaps[0] = conf->vif; 2148 sc->vifs[0] = conf->vif;
2143 sc->sc_nvaps++; 2149 sc->nvifs++;
2144 2150
2145 /* Set the device opmode */ 2151 /* Set the device opmode */
2146 sc->sc_ah->ah_opmode = ic_opmode; 2152 sc->sc_ah->opmode = ic_opmode;
2147 2153
2148 /* 2154 /*
2149 * Enable MIB interrupts when there are hardware phy counters. 2155 * Enable MIB interrupts when there are hardware phy counters.
@@ -2152,27 +2158,29 @@ static int ath9k_add_interface(struct ieee80211_hw *hw,
2152 if (ath9k_hw_phycounters(sc->sc_ah) && 2158 if (ath9k_hw_phycounters(sc->sc_ah) &&
2153 ((conf->type == NL80211_IFTYPE_STATION) || 2159 ((conf->type == NL80211_IFTYPE_STATION) ||
2154 (conf->type == NL80211_IFTYPE_ADHOC))) 2160 (conf->type == NL80211_IFTYPE_ADHOC)))
2155 sc->sc_imask |= ATH9K_INT_MIB; 2161 sc->imask |= ATH9K_INT_MIB;
2156 /* 2162 /*
2157 * Some hardware processes the TIM IE and fires an 2163 * Some hardware processes the TIM IE and fires an
2158 * interrupt when the TIM bit is set. For hardware 2164 * interrupt when the TIM bit is set. For hardware
2159 * that does, if not overridden by configuration, 2165 * that does, if not overridden by configuration,
2160 * enable the TIM interrupt when operating as station. 2166 * enable the TIM interrupt when operating as station.
2161 */ 2167 */
2162 if ((sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_ENHANCEDPM) && 2168 if ((sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_ENHANCEDPM) &&
2163 (conf->type == NL80211_IFTYPE_STATION) && 2169 (conf->type == NL80211_IFTYPE_STATION) &&
2164 !sc->sc_config.swBeaconProcess) 2170 !sc->config.swBeaconProcess)
2165 sc->sc_imask |= ATH9K_INT_TIM; 2171 sc->imask |= ATH9K_INT_TIM;
2166 2172
2167 ath9k_hw_set_interrupts(sc->sc_ah, sc->sc_imask); 2173 ath9k_hw_set_interrupts(sc->sc_ah, sc->imask);
2168 2174
2169 if (conf->type == NL80211_IFTYPE_AP) { 2175 if (conf->type == NL80211_IFTYPE_AP) {
2170 /* TODO: is this a suitable place to start ANI for AP mode? */ 2176 /* TODO: is this a suitable place to start ANI for AP mode? */
2171 /* Start ANI */ 2177 /* Start ANI */
2172 mod_timer(&sc->sc_ani.timer, 2178 mod_timer(&sc->ani.timer,
2173 jiffies + msecs_to_jiffies(ATH_ANI_POLLINTERVAL)); 2179 jiffies + msecs_to_jiffies(ATH_ANI_POLLINTERVAL));
2174 } 2180 }
2175 2181
2182 mutex_unlock(&sc->mutex);
2183
2176 return 0; 2184 return 0;
2177} 2185}
2178 2186
@@ -2180,24 +2188,28 @@ static void ath9k_remove_interface(struct ieee80211_hw *hw,
2180 struct ieee80211_if_init_conf *conf) 2188 struct ieee80211_if_init_conf *conf)
2181{ 2189{
2182 struct ath_softc *sc = hw->priv; 2190 struct ath_softc *sc = hw->priv;
2183 struct ath_vap *avp = (void *)conf->vif->drv_priv; 2191 struct ath_vif *avp = (void *)conf->vif->drv_priv;
2184 2192
2185 DPRINTF(sc, ATH_DBG_CONFIG, "Detach Interface\n"); 2193 DPRINTF(sc, ATH_DBG_CONFIG, "Detach Interface\n");
2186 2194
2195 mutex_lock(&sc->mutex);
2196
2187 /* Stop ANI */ 2197 /* Stop ANI */
2188 del_timer_sync(&sc->sc_ani.timer); 2198 del_timer_sync(&sc->ani.timer);
2189 2199
2190 /* Reclaim beacon resources */ 2200 /* Reclaim beacon resources */
2191 if (sc->sc_ah->ah_opmode == NL80211_IFTYPE_AP || 2201 if (sc->sc_ah->opmode == NL80211_IFTYPE_AP ||
2192 sc->sc_ah->ah_opmode == NL80211_IFTYPE_ADHOC) { 2202 sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC) {
2193 ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq); 2203 ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq);
2194 ath_beacon_return(sc, avp); 2204 ath_beacon_return(sc, avp);
2195 } 2205 }
2196 2206
2197 sc->sc_flags &= ~SC_OP_BEACONS; 2207 sc->sc_flags &= ~SC_OP_BEACONS;
2198 2208
2199 sc->sc_vaps[0] = NULL; 2209 sc->vifs[0] = NULL;
2200 sc->sc_nvaps--; 2210 sc->nvifs--;
2211
2212 mutex_unlock(&sc->mutex);
2201} 2213}
2202 2214
2203static int ath9k_config(struct ieee80211_hw *hw, u32 changed) 2215static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
@@ -2206,12 +2218,13 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
2206 struct ieee80211_conf *conf = &hw->conf; 2218 struct ieee80211_conf *conf = &hw->conf;
2207 2219
2208 mutex_lock(&sc->mutex); 2220 mutex_lock(&sc->mutex);
2221
2209 if (changed & IEEE80211_CONF_CHANGE_PS) { 2222 if (changed & IEEE80211_CONF_CHANGE_PS) {
2210 if (conf->flags & IEEE80211_CONF_PS) { 2223 if (conf->flags & IEEE80211_CONF_PS) {
2211 if ((sc->sc_imask & ATH9K_INT_TIM_TIMER) == 0) { 2224 if ((sc->imask & ATH9K_INT_TIM_TIMER) == 0) {
2212 sc->sc_imask |= ATH9K_INT_TIM_TIMER; 2225 sc->imask |= ATH9K_INT_TIM_TIMER;
2213 ath9k_hw_set_interrupts(sc->sc_ah, 2226 ath9k_hw_set_interrupts(sc->sc_ah,
2214 sc->sc_imask); 2227 sc->imask);
2215 } 2228 }
2216 ath9k_hw_setrxabort(sc->sc_ah, 1); 2229 ath9k_hw_setrxabort(sc->sc_ah, 1);
2217 ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_NETWORK_SLEEP); 2230 ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_NETWORK_SLEEP);
@@ -2219,10 +2232,10 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
2219 ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_AWAKE); 2232 ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_AWAKE);
2220 ath9k_hw_setrxabort(sc->sc_ah, 0); 2233 ath9k_hw_setrxabort(sc->sc_ah, 0);
2221 sc->sc_flags &= ~SC_OP_WAIT_FOR_BEACON; 2234 sc->sc_flags &= ~SC_OP_WAIT_FOR_BEACON;
2222 if (sc->sc_imask & ATH9K_INT_TIM_TIMER) { 2235 if (sc->imask & ATH9K_INT_TIM_TIMER) {
2223 sc->sc_imask &= ~ATH9K_INT_TIM_TIMER; 2236 sc->imask &= ~ATH9K_INT_TIM_TIMER;
2224 ath9k_hw_set_interrupts(sc->sc_ah, 2237 ath9k_hw_set_interrupts(sc->sc_ah,
2225 sc->sc_imask); 2238 sc->imask);
2226 } 2239 }
2227 } 2240 }
2228 } 2241 }
@@ -2235,11 +2248,11 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
2235 curchan->center_freq); 2248 curchan->center_freq);
2236 2249
2237 /* XXX: remove me eventualy */ 2250 /* XXX: remove me eventualy */
2238 ath9k_update_ichannel(sc, &sc->sc_ah->ah_channels[pos]); 2251 ath9k_update_ichannel(sc, &sc->sc_ah->channels[pos]);
2239 2252
2240 ath_update_chainmask(sc, conf_is_ht(conf)); 2253 ath_update_chainmask(sc, conf_is_ht(conf));
2241 2254
2242 if (ath_set_channel(sc, &sc->sc_ah->ah_channels[pos]) < 0) { 2255 if (ath_set_channel(sc, &sc->sc_ah->channels[pos]) < 0) {
2243 DPRINTF(sc, ATH_DBG_FATAL, "Unable to set channel\n"); 2256 DPRINTF(sc, ATH_DBG_FATAL, "Unable to set channel\n");
2244 mutex_unlock(&sc->mutex); 2257 mutex_unlock(&sc->mutex);
2245 return -EINVAL; 2258 return -EINVAL;
@@ -2247,9 +2260,10 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
2247 } 2260 }
2248 2261
2249 if (changed & IEEE80211_CONF_CHANGE_POWER) 2262 if (changed & IEEE80211_CONF_CHANGE_POWER)
2250 sc->sc_config.txpowlimit = 2 * conf->power_level; 2263 sc->config.txpowlimit = 2 * conf->power_level;
2251 2264
2252 mutex_unlock(&sc->mutex); 2265 mutex_unlock(&sc->mutex);
2266
2253 return 0; 2267 return 0;
2254} 2268}
2255 2269
@@ -2258,18 +2272,20 @@ static int ath9k_config_interface(struct ieee80211_hw *hw,
2258 struct ieee80211_if_conf *conf) 2272 struct ieee80211_if_conf *conf)
2259{ 2273{
2260 struct ath_softc *sc = hw->priv; 2274 struct ath_softc *sc = hw->priv;
2261 struct ath_hal *ah = sc->sc_ah; 2275 struct ath_hw *ah = sc->sc_ah;
2262 struct ath_vap *avp = (void *)vif->drv_priv; 2276 struct ath_vif *avp = (void *)vif->drv_priv;
2263 u32 rfilt = 0; 2277 u32 rfilt = 0;
2264 int error, i; 2278 int error, i;
2265 2279
2266 /* TODO: Need to decide which hw opmode to use for multi-interface 2280 /* TODO: Need to decide which hw opmode to use for multi-interface
2267 * cases */ 2281 * cases */
2268 if (vif->type == NL80211_IFTYPE_AP && 2282 if (vif->type == NL80211_IFTYPE_AP &&
2269 ah->ah_opmode != NL80211_IFTYPE_AP) { 2283 ah->opmode != NL80211_IFTYPE_AP) {
2270 ah->ah_opmode = NL80211_IFTYPE_STATION; 2284 ah->opmode = NL80211_IFTYPE_STATION;
2271 ath9k_hw_setopmode(ah); 2285 ath9k_hw_setopmode(ah);
2272 ath9k_hw_write_associd(ah, sc->sc_myaddr, 0); 2286 memcpy(sc->curbssid, sc->sc_ah->macaddr, ETH_ALEN);
2287 sc->curaid = 0;
2288 ath9k_hw_write_associd(sc);
2273 /* Request full reset to get hw opmode changed properly */ 2289 /* Request full reset to get hw opmode changed properly */
2274 sc->sc_flags |= SC_OP_FULL_RESET; 2290 sc->sc_flags |= SC_OP_FULL_RESET;
2275 } 2291 }
@@ -2280,17 +2296,16 @@ static int ath9k_config_interface(struct ieee80211_hw *hw,
2280 case NL80211_IFTYPE_STATION: 2296 case NL80211_IFTYPE_STATION:
2281 case NL80211_IFTYPE_ADHOC: 2297 case NL80211_IFTYPE_ADHOC:
2282 /* Set BSSID */ 2298 /* Set BSSID */
2283 memcpy(sc->sc_curbssid, conf->bssid, ETH_ALEN); 2299 memcpy(sc->curbssid, conf->bssid, ETH_ALEN);
2284 sc->sc_curaid = 0; 2300 sc->curaid = 0;
2285 ath9k_hw_write_associd(sc->sc_ah, sc->sc_curbssid, 2301 ath9k_hw_write_associd(sc);
2286 sc->sc_curaid);
2287 2302
2288 /* Set aggregation protection mode parameters */ 2303 /* Set aggregation protection mode parameters */
2289 sc->sc_config.ath_aggr_prot = 0; 2304 sc->config.ath_aggr_prot = 0;
2290 2305
2291 DPRINTF(sc, ATH_DBG_CONFIG, 2306 DPRINTF(sc, ATH_DBG_CONFIG,
2292 "RX filter 0x%x bssid %pM aid 0x%x\n", 2307 "RX filter 0x%x bssid %pM aid 0x%x\n",
2293 rfilt, sc->sc_curbssid, sc->sc_curaid); 2308 rfilt, sc->curbssid, sc->curaid);
2294 2309
2295 /* need to reconfigure the beacon */ 2310 /* need to reconfigure the beacon */
2296 sc->sc_flags &= ~SC_OP_BEACONS ; 2311 sc->sc_flags &= ~SC_OP_BEACONS ;
@@ -2330,7 +2345,7 @@ static int ath9k_config_interface(struct ieee80211_hw *hw,
2330 if (ath9k_hw_keyisvalid(sc->sc_ah, (u16)i)) 2345 if (ath9k_hw_keyisvalid(sc->sc_ah, (u16)i))
2331 ath9k_hw_keysetmac(sc->sc_ah, 2346 ath9k_hw_keysetmac(sc->sc_ah,
2332 (u16)i, 2347 (u16)i,
2333 sc->sc_curbssid); 2348 sc->curbssid);
2334 } 2349 }
2335 2350
2336 /* Only legacy IBSS for now */ 2351 /* Only legacy IBSS for now */
@@ -2366,8 +2381,11 @@ static void ath9k_configure_filter(struct ieee80211_hw *hw,
2366 ath9k_hw_setrxfilter(sc->sc_ah, rfilt); 2381 ath9k_hw_setrxfilter(sc->sc_ah, rfilt);
2367 2382
2368 if (changed_flags & FIF_BCN_PRBRESP_PROMISC) { 2383 if (changed_flags & FIF_BCN_PRBRESP_PROMISC) {
2369 if (*total_flags & FIF_BCN_PRBRESP_PROMISC) 2384 if (*total_flags & FIF_BCN_PRBRESP_PROMISC) {
2370 ath9k_hw_write_associd(sc->sc_ah, ath_bcast_mac, 0); 2385 memcpy(sc->curbssid, ath_bcast_mac, ETH_ALEN);
2386 sc->curaid = 0;
2387 ath9k_hw_write_associd(sc);
2388 }
2371 } 2389 }
2372 2390
2373 DPRINTF(sc, ATH_DBG_CONFIG, "Set HW RX filter: 0x%x\n", sc->rx.rxfilter); 2391 DPRINTF(sc, ATH_DBG_CONFIG, "Set HW RX filter: 0x%x\n", sc->rx.rxfilter);
@@ -2392,8 +2410,7 @@ static void ath9k_sta_notify(struct ieee80211_hw *hw,
2392 } 2410 }
2393} 2411}
2394 2412
2395static int ath9k_conf_tx(struct ieee80211_hw *hw, 2413static int ath9k_conf_tx(struct ieee80211_hw *hw, u16 queue,
2396 u16 queue,
2397 const struct ieee80211_tx_queue_params *params) 2414 const struct ieee80211_tx_queue_params *params)
2398{ 2415{
2399 struct ath_softc *sc = hw->priv; 2416 struct ath_softc *sc = hw->priv;
@@ -2403,6 +2420,8 @@ static int ath9k_conf_tx(struct ieee80211_hw *hw,
2403 if (queue >= WME_NUM_AC) 2420 if (queue >= WME_NUM_AC)
2404 return 0; 2421 return 0;
2405 2422
2423 mutex_lock(&sc->mutex);
2424
2406 qi.tqi_aifs = params->aifs; 2425 qi.tqi_aifs = params->aifs;
2407 qi.tqi_cwmin = params->cw_min; 2426 qi.tqi_cwmin = params->cw_min;
2408 qi.tqi_cwmax = params->cw_max; 2427 qi.tqi_cwmax = params->cw_max;
@@ -2419,6 +2438,8 @@ static int ath9k_conf_tx(struct ieee80211_hw *hw,
2419 if (ret) 2438 if (ret)
2420 DPRINTF(sc, ATH_DBG_FATAL, "TXQ Update failed\n"); 2439 DPRINTF(sc, ATH_DBG_FATAL, "TXQ Update failed\n");
2421 2440
2441 mutex_unlock(&sc->mutex);
2442
2422 return ret; 2443 return ret;
2423} 2444}
2424 2445
@@ -2431,6 +2452,7 @@ static int ath9k_set_key(struct ieee80211_hw *hw,
2431 struct ath_softc *sc = hw->priv; 2452 struct ath_softc *sc = hw->priv;
2432 int ret = 0; 2453 int ret = 0;
2433 2454
2455 mutex_lock(&sc->mutex);
2434 ath9k_ps_wakeup(sc); 2456 ath9k_ps_wakeup(sc);
2435 DPRINTF(sc, ATH_DBG_KEYCACHE, "Set HW Key\n"); 2457 DPRINTF(sc, ATH_DBG_KEYCACHE, "Set HW Key\n");
2436 2458
@@ -2456,6 +2478,8 @@ static int ath9k_set_key(struct ieee80211_hw *hw,
2456 } 2478 }
2457 2479
2458 ath9k_ps_restore(sc); 2480 ath9k_ps_restore(sc);
2481 mutex_unlock(&sc->mutex);
2482
2459 return ret; 2483 return ret;
2460} 2484}
2461 2485
@@ -2466,6 +2490,8 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw,
2466{ 2490{
2467 struct ath_softc *sc = hw->priv; 2491 struct ath_softc *sc = hw->priv;
2468 2492
2493 mutex_lock(&sc->mutex);
2494
2469 if (changed & BSS_CHANGED_ERP_PREAMBLE) { 2495 if (changed & BSS_CHANGED_ERP_PREAMBLE) {
2470 DPRINTF(sc, ATH_DBG_CONFIG, "BSS Changed PREAMBLE %d\n", 2496 DPRINTF(sc, ATH_DBG_CONFIG, "BSS Changed PREAMBLE %d\n",
2471 bss_conf->use_short_preamble); 2497 bss_conf->use_short_preamble);
@@ -2490,15 +2516,18 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw,
2490 bss_conf->assoc); 2516 bss_conf->assoc);
2491 ath9k_bss_assoc_info(sc, vif, bss_conf); 2517 ath9k_bss_assoc_info(sc, vif, bss_conf);
2492 } 2518 }
2519
2520 mutex_unlock(&sc->mutex);
2493} 2521}
2494 2522
2495static u64 ath9k_get_tsf(struct ieee80211_hw *hw) 2523static u64 ath9k_get_tsf(struct ieee80211_hw *hw)
2496{ 2524{
2497 u64 tsf; 2525 u64 tsf;
2498 struct ath_softc *sc = hw->priv; 2526 struct ath_softc *sc = hw->priv;
2499 struct ath_hal *ah = sc->sc_ah;
2500 2527
2501 tsf = ath9k_hw_gettsf64(ah); 2528 mutex_lock(&sc->mutex);
2529 tsf = ath9k_hw_gettsf64(sc->sc_ah);
2530 mutex_unlock(&sc->mutex);
2502 2531
2503 return tsf; 2532 return tsf;
2504} 2533}
@@ -2506,23 +2535,25 @@ static u64 ath9k_get_tsf(struct ieee80211_hw *hw)
2506static void ath9k_set_tsf(struct ieee80211_hw *hw, u64 tsf) 2535static void ath9k_set_tsf(struct ieee80211_hw *hw, u64 tsf)
2507{ 2536{
2508 struct ath_softc *sc = hw->priv; 2537 struct ath_softc *sc = hw->priv;
2509 struct ath_hal *ah = sc->sc_ah;
2510 2538
2511 ath9k_hw_settsf64(ah, tsf); 2539 mutex_lock(&sc->mutex);
2540 ath9k_hw_settsf64(sc->sc_ah, tsf);
2541 mutex_unlock(&sc->mutex);
2512} 2542}
2513 2543
2514static void ath9k_reset_tsf(struct ieee80211_hw *hw) 2544static void ath9k_reset_tsf(struct ieee80211_hw *hw)
2515{ 2545{
2516 struct ath_softc *sc = hw->priv; 2546 struct ath_softc *sc = hw->priv;
2517 struct ath_hal *ah = sc->sc_ah;
2518 2547
2519 ath9k_hw_reset_tsf(ah); 2548 mutex_lock(&sc->mutex);
2549 ath9k_hw_reset_tsf(sc->sc_ah);
2550 mutex_unlock(&sc->mutex);
2520} 2551}
2521 2552
2522static int ath9k_ampdu_action(struct ieee80211_hw *hw, 2553static int ath9k_ampdu_action(struct ieee80211_hw *hw,
2523 enum ieee80211_ampdu_mlme_action action, 2554 enum ieee80211_ampdu_mlme_action action,
2524 struct ieee80211_sta *sta, 2555 struct ieee80211_sta *sta,
2525 u16 tid, u16 *ssn) 2556 u16 tid, u16 *ssn)
2526{ 2557{
2527 struct ath_softc *sc = hw->priv; 2558 struct ath_softc *sc = hw->priv;
2528 int ret = 0; 2559 int ret = 0;
diff --git a/drivers/net/wireless/ath9k/pci.c b/drivers/net/wireless/ath9k/pci.c
index 05612bf28360..c28afe42b269 100644
--- a/drivers/net/wireless/ath9k/pci.c
+++ b/drivers/net/wireless/ath9k/pci.c
@@ -16,9 +16,7 @@
16 16
17#include <linux/nl80211.h> 17#include <linux/nl80211.h>
18#include <linux/pci.h> 18#include <linux/pci.h>
19#include "core.h" 19#include "ath9k.h"
20#include "reg.h"
21#include "hw.h"
22 20
23static struct pci_device_id ath_pci_id_table[] __devinitdata = { 21static struct pci_device_id ath_pci_id_table[] __devinitdata = {
24 { PCI_VDEVICE(ATHEROS, 0x0023) }, /* PCI */ 22 { PCI_VDEVICE(ATHEROS, 0x0023) }, /* PCI */
@@ -58,7 +56,7 @@ static void ath_pci_cleanup(struct ath_softc *sc)
58 pci_disable_device(pdev); 56 pci_disable_device(pdev);
59} 57}
60 58
61static bool ath_pci_eeprom_read(struct ath_hal *ah, u32 off, u16 *data) 59static bool ath_pci_eeprom_read(struct ath_hw *ah, u32 off, u16 *data)
62{ 60{
63 (void)REG_READ(ah, AR5416_EEPROM_OFFSET + (off << AR5416_EEPROM_S)); 61 (void)REG_READ(ah, AR5416_EEPROM_OFFSET + (off << AR5416_EEPROM_S));
64 62
@@ -89,7 +87,7 @@ static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
89 u8 csz; 87 u8 csz;
90 u32 val; 88 u32 val;
91 int ret = 0; 89 int ret = 0;
92 struct ath_hal *ah; 90 struct ath_hw *ah;
93 91
94 if (pci_enable_device(pdev)) 92 if (pci_enable_device(pdev))
95 return -EIO; 93 return -EIO;
@@ -192,10 +190,10 @@ static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
192 "%s: Atheros AR%s MAC/BB Rev:%x " 190 "%s: Atheros AR%s MAC/BB Rev:%x "
193 "AR%s RF Rev:%x: mem=0x%lx, irq=%d\n", 191 "AR%s RF Rev:%x: mem=0x%lx, irq=%d\n",
194 wiphy_name(hw->wiphy), 192 wiphy_name(hw->wiphy),
195 ath_mac_bb_name(ah->ah_macVersion), 193 ath_mac_bb_name(ah->hw_version.macVersion),
196 ah->ah_macRev, 194 ah->hw_version.macRev,
197 ath_rf_name((ah->ah_analog5GhzRev & AR_RADIO_SREV_MAJOR)), 195 ath_rf_name((ah->hw_version.analog5GhzRev & AR_RADIO_SREV_MAJOR)),
198 ah->ah_phyRev, 196 ah->hw_version.phyRev,
199 (unsigned long)mem, pdev->irq); 197 (unsigned long)mem, pdev->irq);
200 198
201 return 0; 199 return 0;
@@ -230,7 +228,7 @@ static int ath_pci_suspend(struct pci_dev *pdev, pm_message_t state)
230 ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN, 1); 228 ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN, 1);
231 229
232#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE) 230#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
233 if (sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_RFSILENT) 231 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
234 cancel_delayed_work_sync(&sc->rf_kill.rfkill_poll); 232 cancel_delayed_work_sync(&sc->rf_kill.rfkill_poll);
235#endif 233#endif
236 234
@@ -271,7 +269,7 @@ static int ath_pci_resume(struct pci_dev *pdev)
271 * check the h/w rfkill state on resume 269 * check the h/w rfkill state on resume
272 * and start the rfkill poll timer 270 * and start the rfkill poll timer
273 */ 271 */
274 if (sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_RFSILENT) 272 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
275 queue_delayed_work(sc->hw->workqueue, 273 queue_delayed_work(sc->hw->workqueue,
276 &sc->rf_kill.rfkill_poll, 0); 274 &sc->rf_kill.rfkill_poll, 0);
277#endif 275#endif
diff --git a/drivers/net/wireless/ath9k/phy.c b/drivers/net/wireless/ath9k/phy.c
index 766982a8196e..52aa2a7abe7a 100644
--- a/drivers/net/wireless/ath9k/phy.c
+++ b/drivers/net/wireless/ath9k/phy.c
@@ -14,22 +14,17 @@
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */ 15 */
16 16
17#include "core.h" 17#include "ath9k.h"
18#include "hw.h"
19#include "reg.h"
20#include "phy.h"
21 18
22void 19void
23ath9k_hw_write_regs(struct ath_hal *ah, u32 modesIndex, u32 freqIndex, 20ath9k_hw_write_regs(struct ath_hw *ah, u32 modesIndex, u32 freqIndex,
24 int regWrites) 21 int regWrites)
25{ 22{
26 struct ath_hal_5416 *ahp = AH5416(ah); 23 REG_WRITE_ARRAY(&ah->iniBB_RfGain, freqIndex, regWrites);
27
28 REG_WRITE_ARRAY(&ahp->ah_iniBB_RfGain, freqIndex, regWrites);
29} 24}
30 25
31bool 26bool
32ath9k_hw_set_channel(struct ath_hal *ah, struct ath9k_channel *chan) 27ath9k_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan)
33{ 28{
34 u32 channelSel = 0; 29 u32 channelSel = 0;
35 u32 bModeSynth = 0; 30 u32 bModeSynth = 0;
@@ -95,15 +90,14 @@ ath9k_hw_set_channel(struct ath_hal *ah, struct ath9k_channel *chan)
95 90
96 REG_WRITE(ah, AR_PHY(0x37), reg32); 91 REG_WRITE(ah, AR_PHY(0x37), reg32);
97 92
98 ah->ah_curchan = chan; 93 ah->curchan = chan;
99 94 ah->curchan_rad_index = -1;
100 AH5416(ah)->ah_curchanRadIndex = -1;
101 95
102 return true; 96 return true;
103} 97}
104 98
105bool 99bool
106ath9k_hw_ar9280_set_channel(struct ath_hal *ah, 100ath9k_hw_ar9280_set_channel(struct ath_hw *ah,
107 struct ath9k_channel *chan) 101 struct ath9k_channel *chan)
108{ 102{
109 u16 bMode, fracMode, aModeRefSel = 0; 103 u16 bMode, fracMode, aModeRefSel = 0;
@@ -166,9 +160,8 @@ ath9k_hw_ar9280_set_channel(struct ath_hal *ah,
166 160
167 REG_WRITE(ah, AR_PHY_SYNTH_CONTROL, reg32); 161 REG_WRITE(ah, AR_PHY_SYNTH_CONTROL, reg32);
168 162
169 ah->ah_curchan = chan; 163 ah->curchan = chan;
170 164 ah->curchan_rad_index = -1;
171 AH5416(ah)->ah_curchanRadIndex = -1;
172 165
173 return true; 166 return true;
174} 167}
@@ -201,11 +194,9 @@ ath9k_phy_modify_rx_buffer(u32 *rfBuf, u32 reg32,
201} 194}
202 195
203bool 196bool
204ath9k_hw_set_rf_regs(struct ath_hal *ah, struct ath9k_channel *chan, 197ath9k_hw_set_rf_regs(struct ath_hw *ah, struct ath9k_channel *chan,
205 u16 modesIndex) 198 u16 modesIndex)
206{ 199{
207 struct ath_hal_5416 *ahp = AH5416(ah);
208
209 u32 eepMinorRev; 200 u32 eepMinorRev;
210 u32 ob5GHz = 0, db5GHz = 0; 201 u32 ob5GHz = 0, db5GHz = 0;
211 u32 ob2GHz = 0, db2GHz = 0; 202 u32 ob2GHz = 0, db2GHz = 0;
@@ -214,161 +205,156 @@ ath9k_hw_set_rf_regs(struct ath_hal *ah, struct ath9k_channel *chan,
214 if (AR_SREV_9280_10_OR_LATER(ah)) 205 if (AR_SREV_9280_10_OR_LATER(ah))
215 return true; 206 return true;
216 207
217 eepMinorRev = ath9k_hw_get_eeprom(ah, EEP_MINOR_REV); 208 eepMinorRev = ah->eep_ops->get_eeprom(ah, EEP_MINOR_REV);
218 209
219 RF_BANK_SETUP(ahp->ah_analogBank0Data, &ahp->ah_iniBank0, 1); 210 RF_BANK_SETUP(ah->analogBank0Data, &ah->iniBank0, 1);
220 211
221 RF_BANK_SETUP(ahp->ah_analogBank1Data, &ahp->ah_iniBank1, 1); 212 RF_BANK_SETUP(ah->analogBank1Data, &ah->iniBank1, 1);
222 213
223 RF_BANK_SETUP(ahp->ah_analogBank2Data, &ahp->ah_iniBank2, 1); 214 RF_BANK_SETUP(ah->analogBank2Data, &ah->iniBank2, 1);
224 215
225 RF_BANK_SETUP(ahp->ah_analogBank3Data, &ahp->ah_iniBank3, 216 RF_BANK_SETUP(ah->analogBank3Data, &ah->iniBank3,
226 modesIndex); 217 modesIndex);
227 { 218 {
228 int i; 219 int i;
229 for (i = 0; i < ahp->ah_iniBank6TPC.ia_rows; i++) { 220 for (i = 0; i < ah->iniBank6TPC.ia_rows; i++) {
230 ahp->ah_analogBank6Data[i] = 221 ah->analogBank6Data[i] =
231 INI_RA(&ahp->ah_iniBank6TPC, i, modesIndex); 222 INI_RA(&ah->iniBank6TPC, i, modesIndex);
232 } 223 }
233 } 224 }
234 225
235 if (eepMinorRev >= 2) { 226 if (eepMinorRev >= 2) {
236 if (IS_CHAN_2GHZ(chan)) { 227 if (IS_CHAN_2GHZ(chan)) {
237 ob2GHz = ath9k_hw_get_eeprom(ah, EEP_OB_2); 228 ob2GHz = ah->eep_ops->get_eeprom(ah, EEP_OB_2);
238 db2GHz = ath9k_hw_get_eeprom(ah, EEP_DB_2); 229 db2GHz = ah->eep_ops->get_eeprom(ah, EEP_DB_2);
239 ath9k_phy_modify_rx_buffer(ahp->ah_analogBank6Data, 230 ath9k_phy_modify_rx_buffer(ah->analogBank6Data,
240 ob2GHz, 3, 197, 0); 231 ob2GHz, 3, 197, 0);
241 ath9k_phy_modify_rx_buffer(ahp->ah_analogBank6Data, 232 ath9k_phy_modify_rx_buffer(ah->analogBank6Data,
242 db2GHz, 3, 194, 0); 233 db2GHz, 3, 194, 0);
243 } else { 234 } else {
244 ob5GHz = ath9k_hw_get_eeprom(ah, EEP_OB_5); 235 ob5GHz = ah->eep_ops->get_eeprom(ah, EEP_OB_5);
245 db5GHz = ath9k_hw_get_eeprom(ah, EEP_DB_5); 236 db5GHz = ah->eep_ops->get_eeprom(ah, EEP_DB_5);
246 ath9k_phy_modify_rx_buffer(ahp->ah_analogBank6Data, 237 ath9k_phy_modify_rx_buffer(ah->analogBank6Data,
247 ob5GHz, 3, 203, 0); 238 ob5GHz, 3, 203, 0);
248 ath9k_phy_modify_rx_buffer(ahp->ah_analogBank6Data, 239 ath9k_phy_modify_rx_buffer(ah->analogBank6Data,
249 db5GHz, 3, 200, 0); 240 db5GHz, 3, 200, 0);
250 } 241 }
251 } 242 }
252 243
253 RF_BANK_SETUP(ahp->ah_analogBank7Data, &ahp->ah_iniBank7, 1); 244 RF_BANK_SETUP(ah->analogBank7Data, &ah->iniBank7, 1);
254 245
255 REG_WRITE_RF_ARRAY(&ahp->ah_iniBank0, ahp->ah_analogBank0Data, 246 REG_WRITE_RF_ARRAY(&ah->iniBank0, ah->analogBank0Data,
256 regWrites); 247 regWrites);
257 REG_WRITE_RF_ARRAY(&ahp->ah_iniBank1, ahp->ah_analogBank1Data, 248 REG_WRITE_RF_ARRAY(&ah->iniBank1, ah->analogBank1Data,
258 regWrites); 249 regWrites);
259 REG_WRITE_RF_ARRAY(&ahp->ah_iniBank2, ahp->ah_analogBank2Data, 250 REG_WRITE_RF_ARRAY(&ah->iniBank2, ah->analogBank2Data,
260 regWrites); 251 regWrites);
261 REG_WRITE_RF_ARRAY(&ahp->ah_iniBank3, ahp->ah_analogBank3Data, 252 REG_WRITE_RF_ARRAY(&ah->iniBank3, ah->analogBank3Data,
262 regWrites); 253 regWrites);
263 REG_WRITE_RF_ARRAY(&ahp->ah_iniBank6TPC, ahp->ah_analogBank6Data, 254 REG_WRITE_RF_ARRAY(&ah->iniBank6TPC, ah->analogBank6Data,
264 regWrites); 255 regWrites);
265 REG_WRITE_RF_ARRAY(&ahp->ah_iniBank7, ahp->ah_analogBank7Data, 256 REG_WRITE_RF_ARRAY(&ah->iniBank7, ah->analogBank7Data,
266 regWrites); 257 regWrites);
267 258
268 return true; 259 return true;
269} 260}
270 261
271void 262void
272ath9k_hw_rfdetach(struct ath_hal *ah) 263ath9k_hw_rfdetach(struct ath_hw *ah)
273{ 264{
274 struct ath_hal_5416 *ahp = AH5416(ah); 265 if (ah->analogBank0Data != NULL) {
275 266 kfree(ah->analogBank0Data);
276 if (ahp->ah_analogBank0Data != NULL) { 267 ah->analogBank0Data = NULL;
277 kfree(ahp->ah_analogBank0Data);
278 ahp->ah_analogBank0Data = NULL;
279 } 268 }
280 if (ahp->ah_analogBank1Data != NULL) { 269 if (ah->analogBank1Data != NULL) {
281 kfree(ahp->ah_analogBank1Data); 270 kfree(ah->analogBank1Data);
282 ahp->ah_analogBank1Data = NULL; 271 ah->analogBank1Data = NULL;
283 } 272 }
284 if (ahp->ah_analogBank2Data != NULL) { 273 if (ah->analogBank2Data != NULL) {
285 kfree(ahp->ah_analogBank2Data); 274 kfree(ah->analogBank2Data);
286 ahp->ah_analogBank2Data = NULL; 275 ah->analogBank2Data = NULL;
287 } 276 }
288 if (ahp->ah_analogBank3Data != NULL) { 277 if (ah->analogBank3Data != NULL) {
289 kfree(ahp->ah_analogBank3Data); 278 kfree(ah->analogBank3Data);
290 ahp->ah_analogBank3Data = NULL; 279 ah->analogBank3Data = NULL;
291 } 280 }
292 if (ahp->ah_analogBank6Data != NULL) { 281 if (ah->analogBank6Data != NULL) {
293 kfree(ahp->ah_analogBank6Data); 282 kfree(ah->analogBank6Data);
294 ahp->ah_analogBank6Data = NULL; 283 ah->analogBank6Data = NULL;
295 } 284 }
296 if (ahp->ah_analogBank6TPCData != NULL) { 285 if (ah->analogBank6TPCData != NULL) {
297 kfree(ahp->ah_analogBank6TPCData); 286 kfree(ah->analogBank6TPCData);
298 ahp->ah_analogBank6TPCData = NULL; 287 ah->analogBank6TPCData = NULL;
299 } 288 }
300 if (ahp->ah_analogBank7Data != NULL) { 289 if (ah->analogBank7Data != NULL) {
301 kfree(ahp->ah_analogBank7Data); 290 kfree(ah->analogBank7Data);
302 ahp->ah_analogBank7Data = NULL; 291 ah->analogBank7Data = NULL;
303 } 292 }
304 if (ahp->ah_addac5416_21 != NULL) { 293 if (ah->addac5416_21 != NULL) {
305 kfree(ahp->ah_addac5416_21); 294 kfree(ah->addac5416_21);
306 ahp->ah_addac5416_21 = NULL; 295 ah->addac5416_21 = NULL;
307 } 296 }
308 if (ahp->ah_bank6Temp != NULL) { 297 if (ah->bank6Temp != NULL) {
309 kfree(ahp->ah_bank6Temp); 298 kfree(ah->bank6Temp);
310 ahp->ah_bank6Temp = NULL; 299 ah->bank6Temp = NULL;
311 } 300 }
312} 301}
313 302
314bool ath9k_hw_init_rf(struct ath_hal *ah, int *status) 303bool ath9k_hw_init_rf(struct ath_hw *ah, int *status)
315{ 304{
316 struct ath_hal_5416 *ahp = AH5416(ah);
317
318 if (!AR_SREV_9280_10_OR_LATER(ah)) { 305 if (!AR_SREV_9280_10_OR_LATER(ah)) {
319 306 ah->analogBank0Data =
320 ahp->ah_analogBank0Data =
321 kzalloc((sizeof(u32) * 307 kzalloc((sizeof(u32) *
322 ahp->ah_iniBank0.ia_rows), GFP_KERNEL); 308 ah->iniBank0.ia_rows), GFP_KERNEL);
323 ahp->ah_analogBank1Data = 309 ah->analogBank1Data =
324 kzalloc((sizeof(u32) * 310 kzalloc((sizeof(u32) *
325 ahp->ah_iniBank1.ia_rows), GFP_KERNEL); 311 ah->iniBank1.ia_rows), GFP_KERNEL);
326 ahp->ah_analogBank2Data = 312 ah->analogBank2Data =
327 kzalloc((sizeof(u32) * 313 kzalloc((sizeof(u32) *
328 ahp->ah_iniBank2.ia_rows), GFP_KERNEL); 314 ah->iniBank2.ia_rows), GFP_KERNEL);
329 ahp->ah_analogBank3Data = 315 ah->analogBank3Data =
330 kzalloc((sizeof(u32) * 316 kzalloc((sizeof(u32) *
331 ahp->ah_iniBank3.ia_rows), GFP_KERNEL); 317 ah->iniBank3.ia_rows), GFP_KERNEL);
332 ahp->ah_analogBank6Data = 318 ah->analogBank6Data =
333 kzalloc((sizeof(u32) * 319 kzalloc((sizeof(u32) *
334 ahp->ah_iniBank6.ia_rows), GFP_KERNEL); 320 ah->iniBank6.ia_rows), GFP_KERNEL);
335 ahp->ah_analogBank6TPCData = 321 ah->analogBank6TPCData =
336 kzalloc((sizeof(u32) * 322 kzalloc((sizeof(u32) *
337 ahp->ah_iniBank6TPC.ia_rows), GFP_KERNEL); 323 ah->iniBank6TPC.ia_rows), GFP_KERNEL);
338 ahp->ah_analogBank7Data = 324 ah->analogBank7Data =
339 kzalloc((sizeof(u32) * 325 kzalloc((sizeof(u32) *
340 ahp->ah_iniBank7.ia_rows), GFP_KERNEL); 326 ah->iniBank7.ia_rows), GFP_KERNEL);
341 327
342 if (ahp->ah_analogBank0Data == NULL 328 if (ah->analogBank0Data == NULL
343 || ahp->ah_analogBank1Data == NULL 329 || ah->analogBank1Data == NULL
344 || ahp->ah_analogBank2Data == NULL 330 || ah->analogBank2Data == NULL
345 || ahp->ah_analogBank3Data == NULL 331 || ah->analogBank3Data == NULL
346 || ahp->ah_analogBank6Data == NULL 332 || ah->analogBank6Data == NULL
347 || ahp->ah_analogBank6TPCData == NULL 333 || ah->analogBank6TPCData == NULL
348 || ahp->ah_analogBank7Data == NULL) { 334 || ah->analogBank7Data == NULL) {
349 DPRINTF(ah->ah_sc, ATH_DBG_FATAL, 335 DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
350 "Cannot allocate RF banks\n"); 336 "Cannot allocate RF banks\n");
351 *status = -ENOMEM; 337 *status = -ENOMEM;
352 return false; 338 return false;
353 } 339 }
354 340
355 ahp->ah_addac5416_21 = 341 ah->addac5416_21 =
356 kzalloc((sizeof(u32) * 342 kzalloc((sizeof(u32) *
357 ahp->ah_iniAddac.ia_rows * 343 ah->iniAddac.ia_rows *
358 ahp->ah_iniAddac.ia_columns), GFP_KERNEL); 344 ah->iniAddac.ia_columns), GFP_KERNEL);
359 if (ahp->ah_addac5416_21 == NULL) { 345 if (ah->addac5416_21 == NULL) {
360 DPRINTF(ah->ah_sc, ATH_DBG_FATAL, 346 DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
361 "Cannot allocate ah_addac5416_21\n"); 347 "Cannot allocate addac5416_21\n");
362 *status = -ENOMEM; 348 *status = -ENOMEM;
363 return false; 349 return false;
364 } 350 }
365 351
366 ahp->ah_bank6Temp = 352 ah->bank6Temp =
367 kzalloc((sizeof(u32) * 353 kzalloc((sizeof(u32) *
368 ahp->ah_iniBank6.ia_rows), GFP_KERNEL); 354 ah->iniBank6.ia_rows), GFP_KERNEL);
369 if (ahp->ah_bank6Temp == NULL) { 355 if (ah->bank6Temp == NULL) {
370 DPRINTF(ah->ah_sc, ATH_DBG_FATAL, 356 DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
371 "Cannot allocate ah_bank6Temp\n"); 357 "Cannot allocate bank6Temp\n");
372 *status = -ENOMEM; 358 *status = -ENOMEM;
373 return false; 359 return false;
374 } 360 }
@@ -378,24 +364,23 @@ bool ath9k_hw_init_rf(struct ath_hal *ah, int *status)
378} 364}
379 365
380void 366void
381ath9k_hw_decrease_chain_power(struct ath_hal *ah, struct ath9k_channel *chan) 367ath9k_hw_decrease_chain_power(struct ath_hw *ah, struct ath9k_channel *chan)
382{ 368{
383 int i, regWrites = 0; 369 int i, regWrites = 0;
384 struct ath_hal_5416 *ahp = AH5416(ah);
385 u32 bank6SelMask; 370 u32 bank6SelMask;
386 u32 *bank6Temp = ahp->ah_bank6Temp; 371 u32 *bank6Temp = ah->bank6Temp;
387 372
388 switch (ahp->ah_diversityControl) { 373 switch (ah->diversity_control) {
389 case ATH9K_ANT_FIXED_A: 374 case ATH9K_ANT_FIXED_A:
390 bank6SelMask = 375 bank6SelMask =
391 (ahp-> 376 (ah->
392 ah_antennaSwitchSwap & ANTSWAP_AB) ? REDUCE_CHAIN_0 : 377 antenna_switch_swap & ANTSWAP_AB) ? REDUCE_CHAIN_0 :
393 REDUCE_CHAIN_1; 378 REDUCE_CHAIN_1;
394 break; 379 break;
395 case ATH9K_ANT_FIXED_B: 380 case ATH9K_ANT_FIXED_B:
396 bank6SelMask = 381 bank6SelMask =
397 (ahp-> 382 (ah->
398 ah_antennaSwitchSwap & ANTSWAP_AB) ? REDUCE_CHAIN_1 : 383 antenna_switch_swap & ANTSWAP_AB) ? REDUCE_CHAIN_1 :
399 REDUCE_CHAIN_0; 384 REDUCE_CHAIN_0;
400 break; 385 break;
401 case ATH9K_ANT_VARIABLE: 386 case ATH9K_ANT_VARIABLE:
@@ -406,8 +391,8 @@ ath9k_hw_decrease_chain_power(struct ath_hal *ah, struct ath9k_channel *chan)
406 break; 391 break;
407 } 392 }
408 393
409 for (i = 0; i < ahp->ah_iniBank6.ia_rows; i++) 394 for (i = 0; i < ah->iniBank6.ia_rows; i++)
410 bank6Temp[i] = ahp->ah_analogBank6Data[i]; 395 bank6Temp[i] = ah->analogBank6Data[i];
411 396
412 REG_WRITE(ah, AR_PHY_BASE + 0xD8, bank6SelMask); 397 REG_WRITE(ah, AR_PHY_BASE + 0xD8, bank6SelMask);
413 398
@@ -421,7 +406,7 @@ ath9k_hw_decrease_chain_power(struct ath_hal *ah, struct ath9k_channel *chan)
421 ath9k_phy_modify_rx_buffer(bank6Temp, 1, 1, 246, 0); 406 ath9k_phy_modify_rx_buffer(bank6Temp, 1, 1, 246, 0);
422 ath9k_phy_modify_rx_buffer(bank6Temp, 1, 1, 247, 0); 407 ath9k_phy_modify_rx_buffer(bank6Temp, 1, 1, 247, 0);
423 408
424 REG_WRITE_RF_ARRAY(&ahp->ah_iniBank6, bank6Temp, regWrites); 409 REG_WRITE_RF_ARRAY(&ah->iniBank6, bank6Temp, regWrites);
425 410
426 REG_WRITE(ah, AR_PHY_BASE + 0xD8, 0x00000053); 411 REG_WRITE(ah, AR_PHY_BASE + 0xD8, 0x00000053);
427#ifdef ALTER_SWITCH 412#ifdef ALTER_SWITCH
diff --git a/drivers/net/wireless/ath9k/phy.h b/drivers/net/wireless/ath9k/phy.h
index 3a406a5c0593..837a598a7ae5 100644
--- a/drivers/net/wireless/ath9k/phy.h
+++ b/drivers/net/wireless/ath9k/phy.h
@@ -17,19 +17,19 @@
17#ifndef PHY_H 17#ifndef PHY_H
18#define PHY_H 18#define PHY_H
19 19
20bool ath9k_hw_ar9280_set_channel(struct ath_hal *ah, 20bool ath9k_hw_ar9280_set_channel(struct ath_hw *ah,
21 struct ath9k_channel 21 struct ath9k_channel
22 *chan); 22 *chan);
23bool ath9k_hw_set_channel(struct ath_hal *ah, 23bool ath9k_hw_set_channel(struct ath_hw *ah,
24 struct ath9k_channel *chan); 24 struct ath9k_channel *chan);
25void ath9k_hw_write_regs(struct ath_hal *ah, u32 modesIndex, 25void ath9k_hw_write_regs(struct ath_hw *ah, u32 modesIndex,
26 u32 freqIndex, int regWrites); 26 u32 freqIndex, int regWrites);
27bool ath9k_hw_set_rf_regs(struct ath_hal *ah, 27bool ath9k_hw_set_rf_regs(struct ath_hw *ah,
28 struct ath9k_channel *chan, 28 struct ath9k_channel *chan,
29 u16 modesIndex); 29 u16 modesIndex);
30void ath9k_hw_decrease_chain_power(struct ath_hal *ah, 30void ath9k_hw_decrease_chain_power(struct ath_hw *ah,
31 struct ath9k_channel *chan); 31 struct ath9k_channel *chan);
32bool ath9k_hw_init_rf(struct ath_hal *ah, 32bool ath9k_hw_init_rf(struct ath_hw *ah,
33 int *status); 33 int *status);
34 34
35#define AR_PHY_BASE 0x9800 35#define AR_PHY_BASE 0x9800
@@ -533,7 +533,7 @@ bool ath9k_hw_init_rf(struct ath_hal *ah,
533#define ATH9K_KEY_XOR 0xaa 533#define ATH9K_KEY_XOR 0xaa
534 534
535#define ATH9K_IS_MIC_ENABLED(ah) \ 535#define ATH9K_IS_MIC_ENABLED(ah) \
536 (AH5416(ah)->ah_staId1Defaults & AR_STA_ID1_CRPT_MIC_ENABLE) 536 ((ah)->sta_id1_defaults & AR_STA_ID1_CRPT_MIC_ENABLE)
537 537
538#define ANTSWAP_AB 0x0001 538#define ANTSWAP_AB 0x0001
539#define REDUCE_CHAIN_0 0x00000050 539#define REDUCE_CHAIN_0 0x00000050
diff --git a/drivers/net/wireless/ath9k/rc.c b/drivers/net/wireless/ath9k/rc.c
index 704b62778142..a4e863191766 100644
--- a/drivers/net/wireless/ath9k/rc.c
+++ b/drivers/net/wireless/ath9k/rc.c
@@ -15,7 +15,7 @@
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */ 16 */
17 17
18#include "core.h" 18#include "ath9k.h"
19 19
20static struct ath_rate_table ar5416_11na_ratetable = { 20static struct ath_rate_table ar5416_11na_ratetable = {
21 42, 21 42,
@@ -1267,6 +1267,8 @@ static void ath_rc_update_ht(struct ath_softc *sc,
1267 ath_rc_priv->per_down_time = now_msec; 1267 ath_rc_priv->per_down_time = now_msec;
1268 } 1268 }
1269 1269
1270 ath_debug_stat_retries(sc, tx_rate, xretries, retries);
1271
1270#undef CHK_RSSI 1272#undef CHK_RSSI
1271} 1273}
1272 1274
@@ -1392,13 +1394,13 @@ static void ath_rc_init(struct ath_softc *sc,
1392 u8 i, j, k, hi = 0, hthi = 0; 1394 u8 i, j, k, hi = 0, hthi = 0;
1393 1395
1394 /* FIXME: Adhoc */ 1396 /* FIXME: Adhoc */
1395 if ((sc->sc_ah->ah_opmode == NL80211_IFTYPE_STATION) || 1397 if ((sc->sc_ah->opmode == NL80211_IFTYPE_STATION) ||
1396 (sc->sc_ah->ah_opmode == NL80211_IFTYPE_ADHOC)) { 1398 (sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC)) {
1397 bool is_cw_40 = sta->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40; 1399 bool is_cw_40 = sta->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40;
1398 rate_table = ath_choose_rate_table(sc, sband->band, 1400 rate_table = ath_choose_rate_table(sc, sband->band,
1399 sta->ht_cap.ht_supported, 1401 sta->ht_cap.ht_supported,
1400 is_cw_40); 1402 is_cw_40);
1401 } else if (sc->sc_ah->ah_opmode == NL80211_IFTYPE_AP) { 1403 } else if (sc->sc_ah->opmode == NL80211_IFTYPE_AP) {
1402 /* cur_rate_table would be set on init through config() */ 1404 /* cur_rate_table would be set on init through config() */
1403 rate_table = sc->cur_rate_table; 1405 rate_table = sc->cur_rate_table;
1404 } 1406 }
@@ -1410,7 +1412,7 @@ static void ath_rc_init(struct ath_softc *sc,
1410 1412
1411 if (sta->ht_cap.ht_supported) { 1413 if (sta->ht_cap.ht_supported) {
1412 ath_rc_priv->ht_cap = WLAN_RC_HT_FLAG; 1414 ath_rc_priv->ht_cap = WLAN_RC_HT_FLAG;
1413 if (sc->sc_ah->ah_caps.tx_chainmask != 1) 1415 if (sc->sc_ah->caps.tx_chainmask != 1)
1414 ath_rc_priv->ht_cap |= WLAN_RC_DS_FLAG; 1416 ath_rc_priv->ht_cap |= WLAN_RC_DS_FLAG;
1415 if (sta->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) 1417 if (sta->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40)
1416 ath_rc_priv->ht_cap |= WLAN_RC_40_FLAG; 1418 ath_rc_priv->ht_cap |= WLAN_RC_40_FLAG;
@@ -1517,7 +1519,7 @@ static void ath_tx_status(void *priv, struct ieee80211_supported_band *sband,
1517 */ 1519 */
1518 if (tx_info_priv->tx.ts_flags & 1520 if (tx_info_priv->tx.ts_flags &
1519 (ATH9K_TX_DATA_UNDERRUN | ATH9K_TX_DELIM_UNDERRUN) && 1521 (ATH9K_TX_DATA_UNDERRUN | ATH9K_TX_DELIM_UNDERRUN) &&
1520 ((sc->sc_ah->ah_txTrigLevel) >= ath_rc_priv->tx_triglevel_max)) { 1522 ((sc->sc_ah->tx_trig_level) >= ath_rc_priv->tx_triglevel_max)) {
1521 tx_status = 1; 1523 tx_status = 1;
1522 is_underrun = 1; 1524 is_underrun = 1;
1523 } 1525 }
@@ -1626,7 +1628,7 @@ static void *ath_rate_alloc_sta(void *priv, struct ieee80211_sta *sta, gfp_t gfp
1626 } 1628 }
1627 1629
1628 rate_priv->rssi_down_time = jiffies_to_msecs(jiffies); 1630 rate_priv->rssi_down_time = jiffies_to_msecs(jiffies);
1629 rate_priv->tx_triglevel_max = sc->sc_ah->ah_caps.tx_triglevel_max; 1631 rate_priv->tx_triglevel_max = sc->sc_ah->caps.tx_triglevel_max;
1630 1632
1631 return rate_priv; 1633 return rate_priv;
1632} 1634}
diff --git a/drivers/net/wireless/ath9k/rc.h b/drivers/net/wireless/ath9k/rc.h
index a987cb9e74e2..d688ec51a14f 100644
--- a/drivers/net/wireless/ath9k/rc.h
+++ b/drivers/net/wireless/ath9k/rc.h
@@ -19,13 +19,12 @@
19#ifndef RC_H 19#ifndef RC_H
20#define RC_H 20#define RC_H
21 21
22#include "ath9k.h"
23
24struct ath_softc; 22struct ath_softc;
25 23
26#define ATH_RATE_MAX 30 24#define ATH_RATE_MAX 30
27#define RATE_TABLE_SIZE 64 25#define RATE_TABLE_SIZE 64
28#define MAX_TX_RATE_PHY 48 26#define MAX_TX_RATE_PHY 48
27#define WLAN_CTRL_FRAME_SIZE (2+2+6+4)
29 28
30/* VALID_ALL - valid for 20/40/Legacy, 29/* VALID_ALL - valid for 20/40/Legacy,
31 * VALID - Legacy only, 30 * VALID - Legacy only,
@@ -39,6 +38,20 @@ struct ath_softc;
39#define VALID_2040 (VALID_20|VALID_40) 38#define VALID_2040 (VALID_20|VALID_40)
40#define VALID_ALL (VALID_2040|VALID) 39#define VALID_ALL (VALID_2040|VALID)
41 40
41enum {
42 WLAN_RC_PHY_OFDM,
43 WLAN_RC_PHY_CCK,
44 WLAN_RC_PHY_HT_20_SS,
45 WLAN_RC_PHY_HT_20_DS,
46 WLAN_RC_PHY_HT_40_SS,
47 WLAN_RC_PHY_HT_40_DS,
48 WLAN_RC_PHY_HT_20_SS_HGI,
49 WLAN_RC_PHY_HT_20_DS_HGI,
50 WLAN_RC_PHY_HT_40_SS_HGI,
51 WLAN_RC_PHY_HT_40_DS_HGI,
52 WLAN_RC_PHY_MAX
53};
54
42#define WLAN_RC_PHY_DS(_phy) ((_phy == WLAN_RC_PHY_HT_20_DS) \ 55#define WLAN_RC_PHY_DS(_phy) ((_phy == WLAN_RC_PHY_HT_20_DS) \
43 || (_phy == WLAN_RC_PHY_HT_40_DS) \ 56 || (_phy == WLAN_RC_PHY_HT_40_DS) \
44 || (_phy == WLAN_RC_PHY_HT_20_DS_HGI) \ 57 || (_phy == WLAN_RC_PHY_HT_20_DS_HGI) \
diff --git a/drivers/net/wireless/ath9k/recv.c b/drivers/net/wireless/ath9k/recv.c
index 8da08f9b463c..08f676af894f 100644
--- a/drivers/net/wireless/ath9k/recv.c
+++ b/drivers/net/wireless/ath9k/recv.c
@@ -14,7 +14,7 @@
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */ 15 */
16 16
17#include "core.h" 17#include "ath9k.h"
18 18
19/* 19/*
20 * Setup and link descriptors. 20 * Setup and link descriptors.
@@ -26,7 +26,7 @@
26 */ 26 */
27static void ath_rx_buf_link(struct ath_softc *sc, struct ath_buf *bf) 27static void ath_rx_buf_link(struct ath_softc *sc, struct ath_buf *bf)
28{ 28{
29 struct ath_hal *ah = sc->sc_ah; 29 struct ath_hw *ah = sc->sc_ah;
30 struct ath_desc *ds; 30 struct ath_desc *ds;
31 struct sk_buff *skb; 31 struct sk_buff *skb;
32 32
@@ -97,11 +97,11 @@ static struct sk_buff *ath_rxbuf_alloc(struct ath_softc *sc, u32 len)
97 * Unfortunately this means we may get 8 KB here from the 97 * Unfortunately this means we may get 8 KB here from the
98 * kernel... and that is actually what is observed on some 98 * kernel... and that is actually what is observed on some
99 * systems :( */ 99 * systems :( */
100 skb = dev_alloc_skb(len + sc->sc_cachelsz - 1); 100 skb = dev_alloc_skb(len + sc->cachelsz - 1);
101 if (skb != NULL) { 101 if (skb != NULL) {
102 off = ((unsigned long) skb->data) % sc->sc_cachelsz; 102 off = ((unsigned long) skb->data) % sc->cachelsz;
103 if (off != 0) 103 if (off != 0)
104 skb_reserve(skb, sc->sc_cachelsz - off); 104 skb_reserve(skb, sc->cachelsz - off);
105 } else { 105 } else {
106 DPRINTF(sc, ATH_DBG_FATAL, 106 DPRINTF(sc, ATH_DBG_FATAL,
107 "skbuff alloc of size %u failed\n", len); 107 "skbuff alloc of size %u failed\n", len);
@@ -135,7 +135,7 @@ static int ath_rx_prepare(struct sk_buff *skb, struct ath_desc *ds,
135 * discard the frame. Enable this if you want to see 135 * discard the frame. Enable this if you want to see
136 * error frames in Monitor mode. 136 * error frames in Monitor mode.
137 */ 137 */
138 if (sc->sc_ah->ah_opmode != NL80211_IFTYPE_MONITOR) 138 if (sc->sc_ah->opmode != NL80211_IFTYPE_MONITOR)
139 goto rx_next; 139 goto rx_next;
140 } else if (ds->ds_rxstat.rs_status != 0) { 140 } else if (ds->ds_rxstat.rs_status != 0) {
141 if (ds->ds_rxstat.rs_status & ATH9K_RXERR_CRC) 141 if (ds->ds_rxstat.rs_status & ATH9K_RXERR_CRC)
@@ -161,7 +161,7 @@ static int ath_rx_prepare(struct sk_buff *skb, struct ath_desc *ds,
161 * decryption and MIC failures. For monitor mode, 161 * decryption and MIC failures. For monitor mode,
162 * we also ignore the CRC error. 162 * we also ignore the CRC error.
163 */ 163 */
164 if (sc->sc_ah->ah_opmode == NL80211_IFTYPE_MONITOR) { 164 if (sc->sc_ah->opmode == NL80211_IFTYPE_MONITOR) {
165 if (ds->ds_rxstat.rs_status & 165 if (ds->ds_rxstat.rs_status &
166 ~(ATH9K_RXERR_DECRYPT | ATH9K_RXERR_MIC | 166 ~(ATH9K_RXERR_DECRYPT | ATH9K_RXERR_MIC |
167 ATH9K_RXERR_CRC)) 167 ATH9K_RXERR_CRC))
@@ -210,7 +210,7 @@ static int ath_rx_prepare(struct sk_buff *skb, struct ath_desc *ds,
210 rx_status->mactime = ath_extend_tsf(sc, ds->ds_rxstat.rs_tstamp); 210 rx_status->mactime = ath_extend_tsf(sc, ds->ds_rxstat.rs_tstamp);
211 rx_status->band = sc->hw->conf.channel->band; 211 rx_status->band = sc->hw->conf.channel->band;
212 rx_status->freq = sc->hw->conf.channel->center_freq; 212 rx_status->freq = sc->hw->conf.channel->center_freq;
213 rx_status->noise = sc->sc_ani.sc_noise_floor; 213 rx_status->noise = sc->ani.noise_floor;
214 rx_status->signal = rx_status->noise + ds->ds_rxstat.rs_rssi; 214 rx_status->signal = rx_status->noise + ds->ds_rxstat.rs_rssi;
215 rx_status->antenna = ds->ds_rxstat.rs_antenna; 215 rx_status->antenna = ds->ds_rxstat.rs_antenna;
216 216
@@ -233,7 +233,7 @@ rx_next:
233 233
234static void ath_opmode_init(struct ath_softc *sc) 234static void ath_opmode_init(struct ath_softc *sc)
235{ 235{
236 struct ath_hal *ah = sc->sc_ah; 236 struct ath_hw *ah = sc->sc_ah;
237 u32 rfilt, mfilt[2]; 237 u32 rfilt, mfilt[2];
238 238
239 /* configure rx filter */ 239 /* configure rx filter */
@@ -241,14 +241,14 @@ static void ath_opmode_init(struct ath_softc *sc)
241 ath9k_hw_setrxfilter(ah, rfilt); 241 ath9k_hw_setrxfilter(ah, rfilt);
242 242
243 /* configure bssid mask */ 243 /* configure bssid mask */
244 if (ah->ah_caps.hw_caps & ATH9K_HW_CAP_BSSIDMASK) 244 if (ah->caps.hw_caps & ATH9K_HW_CAP_BSSIDMASK)
245 ath9k_hw_setbssidmask(ah, sc->sc_bssidmask); 245 ath9k_hw_setbssidmask(sc);
246 246
247 /* configure operational mode */ 247 /* configure operational mode */
248 ath9k_hw_setopmode(ah); 248 ath9k_hw_setopmode(ah);
249 249
250 /* Handle any link-level address change. */ 250 /* Handle any link-level address change. */
251 ath9k_hw_setmac(ah, sc->sc_myaddr); 251 ath9k_hw_setmac(ah, sc->sc_ah->macaddr);
252 252
253 /* calculate and install multicast filter */ 253 /* calculate and install multicast filter */
254 mfilt[0] = mfilt[1] = ~0; 254 mfilt[0] = mfilt[1] = ~0;
@@ -267,11 +267,11 @@ int ath_rx_init(struct ath_softc *sc, int nbufs)
267 spin_lock_init(&sc->rx.rxbuflock); 267 spin_lock_init(&sc->rx.rxbuflock);
268 268
269 sc->rx.bufsize = roundup(IEEE80211_MAX_MPDU_LEN, 269 sc->rx.bufsize = roundup(IEEE80211_MAX_MPDU_LEN,
270 min(sc->sc_cachelsz, 270 min(sc->cachelsz,
271 (u16)64)); 271 (u16)64));
272 272
273 DPRINTF(sc, ATH_DBG_CONFIG, "cachelsz %u rxbufsize %u\n", 273 DPRINTF(sc, ATH_DBG_CONFIG, "cachelsz %u rxbufsize %u\n",
274 sc->sc_cachelsz, sc->rx.bufsize); 274 sc->cachelsz, sc->rx.bufsize);
275 275
276 /* Initialize rx descriptors */ 276 /* Initialize rx descriptors */
277 277
@@ -360,25 +360,28 @@ u32 ath_calcrxfilter(struct ath_softc *sc)
360 | ATH9K_RX_FILTER_MCAST; 360 | ATH9K_RX_FILTER_MCAST;
361 361
362 /* If not a STA, enable processing of Probe Requests */ 362 /* If not a STA, enable processing of Probe Requests */
363 if (sc->sc_ah->ah_opmode != NL80211_IFTYPE_STATION) 363 if (sc->sc_ah->opmode != NL80211_IFTYPE_STATION)
364 rfilt |= ATH9K_RX_FILTER_PROBEREQ; 364 rfilt |= ATH9K_RX_FILTER_PROBEREQ;
365 365
366 /* Can't set HOSTAP into promiscous mode */ 366 /* Can't set HOSTAP into promiscous mode */
367 if (((sc->sc_ah->ah_opmode != NL80211_IFTYPE_AP) && 367 if (((sc->sc_ah->opmode != NL80211_IFTYPE_AP) &&
368 (sc->rx.rxfilter & FIF_PROMISC_IN_BSS)) || 368 (sc->rx.rxfilter & FIF_PROMISC_IN_BSS)) ||
369 (sc->sc_ah->ah_opmode == NL80211_IFTYPE_MONITOR)) { 369 (sc->sc_ah->opmode == NL80211_IFTYPE_MONITOR)) {
370 rfilt |= ATH9K_RX_FILTER_PROM; 370 rfilt |= ATH9K_RX_FILTER_PROM;
371 /* ??? To prevent from sending ACK */ 371 /* ??? To prevent from sending ACK */
372 rfilt &= ~ATH9K_RX_FILTER_UCAST; 372 rfilt &= ~ATH9K_RX_FILTER_UCAST;
373 } 373 }
374 374
375 if (sc->sc_ah->ah_opmode == NL80211_IFTYPE_STATION || 375 if (sc->rx.rxfilter & FIF_CONTROL)
376 sc->sc_ah->ah_opmode == NL80211_IFTYPE_ADHOC) 376 rfilt |= ATH9K_RX_FILTER_CONTROL;
377
378 if (sc->sc_ah->opmode == NL80211_IFTYPE_STATION ||
379 sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC)
377 rfilt |= ATH9K_RX_FILTER_BEACON; 380 rfilt |= ATH9K_RX_FILTER_BEACON;
378 381
379 /* If in HOSTAP mode, want to enable reception of PSPOLL frames 382 /* If in HOSTAP mode, want to enable reception of PSPOLL frames
380 & beacon frames */ 383 & beacon frames */
381 if (sc->sc_ah->ah_opmode == NL80211_IFTYPE_AP) 384 if (sc->sc_ah->opmode == NL80211_IFTYPE_AP)
382 rfilt |= (ATH9K_RX_FILTER_BEACON | ATH9K_RX_FILTER_PSPOLL); 385 rfilt |= (ATH9K_RX_FILTER_BEACON | ATH9K_RX_FILTER_PSPOLL);
383 386
384 return rfilt; 387 return rfilt;
@@ -388,7 +391,7 @@ u32 ath_calcrxfilter(struct ath_softc *sc)
388 391
389int ath_startrecv(struct ath_softc *sc) 392int ath_startrecv(struct ath_softc *sc)
390{ 393{
391 struct ath_hal *ah = sc->sc_ah; 394 struct ath_hw *ah = sc->sc_ah;
392 struct ath_buf *bf, *tbf; 395 struct ath_buf *bf, *tbf;
393 396
394 spin_lock_bh(&sc->rx.rxbuflock); 397 spin_lock_bh(&sc->rx.rxbuflock);
@@ -418,7 +421,7 @@ start_recv:
418 421
419bool ath_stoprecv(struct ath_softc *sc) 422bool ath_stoprecv(struct ath_softc *sc)
420{ 423{
421 struct ath_hal *ah = sc->sc_ah; 424 struct ath_hw *ah = sc->sc_ah;
422 bool stopped; 425 bool stopped;
423 426
424 ath9k_hw_stoppcurecv(ah); 427 ath9k_hw_stoppcurecv(ah);
@@ -449,7 +452,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
449 struct ath_desc *ds; 452 struct ath_desc *ds;
450 struct sk_buff *skb = NULL, *requeue_skb; 453 struct sk_buff *skb = NULL, *requeue_skb;
451 struct ieee80211_rx_status rx_status; 454 struct ieee80211_rx_status rx_status;
452 struct ath_hal *ah = sc->sc_ah; 455 struct ath_hw *ah = sc->sc_ah;
453 struct ieee80211_hdr *hdr; 456 struct ieee80211_hdr *hdr;
454 int hdrlen, padsize, retval; 457 int hdrlen, padsize, retval;
455 bool decrypt_error = false; 458 bool decrypt_error = false;
@@ -590,7 +593,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
590 && !decrypt_error && skb->len >= hdrlen + 4) { 593 && !decrypt_error && skb->len >= hdrlen + 4) {
591 keyix = skb->data[hdrlen + 3] >> 6; 594 keyix = skb->data[hdrlen + 3] >> 6;
592 595
593 if (test_bit(keyix, sc->sc_keymap)) 596 if (test_bit(keyix, sc->keymap))
594 rx_status.flag |= RX_FLAG_DECRYPTED; 597 rx_status.flag |= RX_FLAG_DECRYPTED;
595 } 598 }
596 if (ah->sw_mgmt_crypto && 599 if (ah->sw_mgmt_crypto &&
diff --git a/drivers/net/wireless/ath9k/reg.h b/drivers/net/wireless/ath9k/reg.h
index c967b7926e33..17ed190349a5 100644
--- a/drivers/net/wireless/ath9k/reg.h
+++ b/drivers/net/wireless/ath9k/reg.h
@@ -160,6 +160,7 @@
160 160
161#define AR_SREV_VERSION_9100 0x014 161#define AR_SREV_VERSION_9100 0x014
162 162
163#define AR_SREV_9100(ah) ((ah->hw_version.macVersion) == AR_SREV_VERSION_9100)
163#define AR_SREV_5416_V20_OR_LATER(_ah) \ 164#define AR_SREV_5416_V20_OR_LATER(_ah) \
164 (AR_SREV_9100((_ah)) || AR_SREV_5416_20_OR_LATER(_ah)) 165 (AR_SREV_9100((_ah)) || AR_SREV_5416_20_OR_LATER(_ah))
165#define AR_SREV_5416_V22_OR_LATER(_ah) \ 166#define AR_SREV_5416_V22_OR_LATER(_ah) \
@@ -746,44 +747,50 @@
746#define AR_SREV_REVISION_9285_12 2 747#define AR_SREV_REVISION_9285_12 2
747 748
748#define AR_SREV_9100_OR_LATER(_ah) \ 749#define AR_SREV_9100_OR_LATER(_ah) \
749 (((_ah)->ah_macVersion >= AR_SREV_VERSION_5416_PCIE)) 750 (((_ah)->hw_version.macVersion >= AR_SREV_VERSION_5416_PCIE))
750#define AR_SREV_5416_20_OR_LATER(_ah) \ 751#define AR_SREV_5416_20_OR_LATER(_ah) \
751 (((_ah)->ah_macVersion >= AR_SREV_VERSION_9160) || \ 752 (((_ah)->hw_version.macVersion >= AR_SREV_VERSION_9160) || \
752 ((_ah)->ah_macRev >= AR_SREV_REVISION_5416_20)) 753 ((_ah)->hw_version.macRev >= AR_SREV_REVISION_5416_20))
753#define AR_SREV_5416_22_OR_LATER(_ah) \ 754#define AR_SREV_5416_22_OR_LATER(_ah) \
754 (((_ah)->ah_macVersion >= AR_SREV_VERSION_9160) || \ 755 (((_ah)->hw_version.macVersion >= AR_SREV_VERSION_9160) || \
755 ((_ah)->ah_macRev >= AR_SREV_REVISION_5416_22)) 756 ((_ah)->hw_version.macRev >= AR_SREV_REVISION_5416_22))
756#define AR_SREV_9160(_ah) \ 757#define AR_SREV_9160(_ah) \
757 (((_ah)->ah_macVersion == AR_SREV_VERSION_9160)) 758 (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9160))
758#define AR_SREV_9160_10_OR_LATER(_ah) \ 759#define AR_SREV_9160_10_OR_LATER(_ah) \
759 (((_ah)->ah_macVersion >= AR_SREV_VERSION_9160)) 760 (((_ah)->hw_version.macVersion >= AR_SREV_VERSION_9160))
760#define AR_SREV_9160_11(_ah) \ 761#define AR_SREV_9160_11(_ah) \
761 (AR_SREV_9160(_ah) && ((_ah)->ah_macRev == AR_SREV_REVISION_9160_11)) 762 (AR_SREV_9160(_ah) && \
763 ((_ah)->hw_version.macRev == AR_SREV_REVISION_9160_11))
762#define AR_SREV_9280(_ah) \ 764#define AR_SREV_9280(_ah) \
763 (((_ah)->ah_macVersion == AR_SREV_VERSION_9280)) 765 (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9280))
764#define AR_SREV_9280_10_OR_LATER(_ah) \ 766#define AR_SREV_9280_10_OR_LATER(_ah) \
765 (((_ah)->ah_macVersion >= AR_SREV_VERSION_9280)) 767 (((_ah)->hw_version.macVersion >= AR_SREV_VERSION_9280))
766#define AR_SREV_9280_20(_ah) \ 768#define AR_SREV_9280_20(_ah) \
767 (((_ah)->ah_macVersion == AR_SREV_VERSION_9280) && \ 769 (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9280) && \
768 ((_ah)->ah_macRev >= AR_SREV_REVISION_9280_20)) 770 ((_ah)->hw_version.macRev >= AR_SREV_REVISION_9280_20))
769#define AR_SREV_9280_20_OR_LATER(_ah) \ 771#define AR_SREV_9280_20_OR_LATER(_ah) \
770 (((_ah)->ah_macVersion > AR_SREV_VERSION_9280) || \ 772 (((_ah)->hw_version.macVersion > AR_SREV_VERSION_9280) || \
771 (((_ah)->ah_macVersion == AR_SREV_VERSION_9280) && \ 773 (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9280) && \
772 ((_ah)->ah_macRev >= AR_SREV_REVISION_9280_20))) 774 ((_ah)->hw_version.macRev >= AR_SREV_REVISION_9280_20)))
773 775
774#define AR_SREV_9285(_ah) (((_ah)->ah_macVersion == AR_SREV_VERSION_9285)) 776#define AR_SREV_9285(_ah) \
777 (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9285))
775#define AR_SREV_9285_10_OR_LATER(_ah) \ 778#define AR_SREV_9285_10_OR_LATER(_ah) \
776 (((_ah)->ah_macVersion >= AR_SREV_VERSION_9285)) 779 (((_ah)->hw_version.macVersion >= AR_SREV_VERSION_9285))
777#define AR_SREV_9285_11(_ah) \ 780#define AR_SREV_9285_11(_ah) \
778 (AR_SREV_9280(ah) && ((_ah)->ah_macRev == AR_SREV_REVISION_9285_11)) 781 (AR_SREV_9280(ah) && \
782 ((_ah)->hw_version.macRev == AR_SREV_REVISION_9285_11))
779#define AR_SREV_9285_11_OR_LATER(_ah) \ 783#define AR_SREV_9285_11_OR_LATER(_ah) \
780 (((_ah)->ah_macVersion > AR_SREV_VERSION_9285) || \ 784 (((_ah)->hw_version.macVersion > AR_SREV_VERSION_9285) || \
781 (AR_SREV_9285(ah) && ((_ah)->ah_macRev >= AR_SREV_REVISION_9285_11))) 785 (AR_SREV_9285(ah) && ((_ah)->hw_version.macRev >= \
786 AR_SREV_REVISION_9285_11)))
782#define AR_SREV_9285_12(_ah) \ 787#define AR_SREV_9285_12(_ah) \
783 (AR_SREV_9280(ah) && ((_ah)->ah_macRev == AR_SREV_REVISION_9285_12)) 788 (AR_SREV_9280(ah) && \
789 ((_ah)->hw_version.macRev == AR_SREV_REVISION_9285_12))
784#define AR_SREV_9285_12_OR_LATER(_ah) \ 790#define AR_SREV_9285_12_OR_LATER(_ah) \
785 (((_ah)->ah_macVersion > AR_SREV_VERSION_9285) || \ 791 (((_ah)->hw_version.macVersion > AR_SREV_VERSION_9285) || \
786 (AR_SREV_9285(ah) && ((_ah)->ah_macRev >= AR_SREV_REVISION_9285_12))) 792 (AR_SREV_9285(ah) && ((_ah)->hw_version.macRev >= \
793 AR_SREV_REVISION_9285_12)))
787 794
788#define AR_RADIO_SREV_MAJOR 0xf0 795#define AR_RADIO_SREV_MAJOR 0xf0
789#define AR_RAD5133_SREV_MAJOR 0xc0 796#define AR_RAD5133_SREV_MAJOR 0xc0
diff --git a/drivers/net/wireless/ath9k/regd.c b/drivers/net/wireless/ath9k/regd.c
index fe08a4fdf770..8c2b56ac55ff 100644
--- a/drivers/net/wireless/ath9k/regd.c
+++ b/drivers/net/wireless/ath9k/regd.c
@@ -16,9 +16,7 @@
16 16
17#include <linux/kernel.h> 17#include <linux/kernel.h>
18#include <linux/slab.h> 18#include <linux/slab.h>
19#include "core.h" 19#include "ath9k.h"
20#include "hw.h"
21#include "regd.h"
22#include "regd_common.h" 20#include "regd_common.h"
23 21
24/* 22/*
@@ -108,17 +106,17 @@ static const struct ieee80211_regdomain ath9k_world_regdom_67_68_6A = {
108 } 106 }
109}; 107};
110 108
111static u16 ath9k_regd_get_eepromRD(struct ath_hal *ah) 109static u16 ath9k_regd_get_eepromRD(struct ath_hw *ah)
112{ 110{
113 return ah->ah_currentRD & ~WORLDWIDE_ROAMING_FLAG; 111 return ah->regulatory.current_rd & ~WORLDWIDE_ROAMING_FLAG;
114} 112}
115 113
116u16 ath9k_regd_get_rd(struct ath_hal *ah) 114u16 ath9k_regd_get_rd(struct ath_hw *ah)
117{ 115{
118 return ath9k_regd_get_eepromRD(ah); 116 return ath9k_regd_get_eepromRD(ah);
119} 117}
120 118
121bool ath9k_is_world_regd(struct ath_hal *ah) 119bool ath9k_is_world_regd(struct ath_hw *ah)
122{ 120{
123 return isWwrSKU(ah); 121 return isWwrSKU(ah);
124} 122}
@@ -129,9 +127,9 @@ const struct ieee80211_regdomain *ath9k_default_world_regdomain(void)
129 return &ath9k_world_regdom_64; 127 return &ath9k_world_regdom_64;
130} 128}
131 129
132const struct ieee80211_regdomain *ath9k_world_regdomain(struct ath_hal *ah) 130const struct ieee80211_regdomain *ath9k_world_regdomain(struct ath_hw *ah)
133{ 131{
134 switch (ah->regpair->regDmnEnum) { 132 switch (ah->regulatory.regpair->regDmnEnum) {
135 case 0x60: 133 case 0x60:
136 case 0x61: 134 case 0x61:
137 case 0x62: 135 case 0x62:
@@ -284,9 +282,9 @@ void ath9k_reg_apply_world_flags(struct wiphy *wiphy, enum reg_set_by setby)
284{ 282{
285 struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy); 283 struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
286 struct ath_softc *sc = hw->priv; 284 struct ath_softc *sc = hw->priv;
287 struct ath_hal *ah = sc->sc_ah; 285 struct ath_hw *ah = sc->sc_ah;
288 286
289 switch (ah->regpair->regDmnEnum) { 287 switch (ah->regulatory.regpair->regDmnEnum) {
290 case 0x60: 288 case 0x60:
291 case 0x63: 289 case 0x63:
292 case 0x66: 290 case 0x66:
@@ -324,7 +322,7 @@ int ath9k_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request)
324 return 0; 322 return 0;
325} 323}
326 324
327bool ath9k_regd_is_eeprom_valid(struct ath_hal *ah) 325bool ath9k_regd_is_eeprom_valid(struct ath_hw *ah)
328{ 326{
329 u16 rd = ath9k_regd_get_eepromRD(ah); 327 u16 rd = ath9k_regd_get_eepromRD(ah);
330 int i; 328 int i;
@@ -373,7 +371,7 @@ ath9k_regd_find_country_by_rd(int regdmn)
373} 371}
374 372
375/* Returns the map of the EEPROM set RD to a country code */ 373/* Returns the map of the EEPROM set RD to a country code */
376static u16 ath9k_regd_get_default_country(struct ath_hal *ah) 374static u16 ath9k_regd_get_default_country(struct ath_hw *ah)
377{ 375{
378 u16 rd; 376 u16 rd;
379 377
@@ -404,7 +402,7 @@ ath9k_get_regpair(int regdmn)
404 return NULL; 402 return NULL;
405} 403}
406 404
407int ath9k_regd_init(struct ath_hal *ah) 405int ath9k_regd_init(struct ath_hw *ah)
408{ 406{
409 struct country_code_to_enum_rd *country = NULL; 407 struct country_code_to_enum_rd *country = NULL;
410 int regdmn; 408 int regdmn;
@@ -415,30 +413,30 @@ int ath9k_regd_init(struct ath_hal *ah)
415 return -EINVAL; 413 return -EINVAL;
416 } 414 }
417 415
418 ah->ah_countryCode = ath9k_regd_get_default_country(ah); 416 ah->regulatory.country_code = ath9k_regd_get_default_country(ah);
419 417
420 if (ah->ah_countryCode == CTRY_DEFAULT && 418 if (ah->regulatory.country_code == CTRY_DEFAULT &&
421 ath9k_regd_get_eepromRD(ah) == CTRY_DEFAULT) 419 ath9k_regd_get_eepromRD(ah) == CTRY_DEFAULT)
422 ah->ah_countryCode = CTRY_UNITED_STATES; 420 ah->regulatory.country_code = CTRY_UNITED_STATES;
423 421
424 if (ah->ah_countryCode == CTRY_DEFAULT) { 422 if (ah->regulatory.country_code == CTRY_DEFAULT) {
425 regdmn = ath9k_regd_get_eepromRD(ah); 423 regdmn = ath9k_regd_get_eepromRD(ah);
426 country = NULL; 424 country = NULL;
427 } else { 425 } else {
428 country = ath9k_regd_find_country(ah->ah_countryCode); 426 country = ath9k_regd_find_country(ah->regulatory.country_code);
429 if (country == NULL) { 427 if (country == NULL) {
430 DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, 428 DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
431 "Country is NULL!!!!, cc= %d\n", 429 "Country is NULL!!!!, cc= %d\n",
432 ah->ah_countryCode); 430 ah->regulatory.country_code);
433 return -EINVAL; 431 return -EINVAL;
434 } else 432 } else
435 regdmn = country->regDmnEnum; 433 regdmn = country->regDmnEnum;
436 } 434 }
437 435
438 ah->ah_currentRDInUse = regdmn; 436 ah->regulatory.current_rd_inuse = regdmn;
439 ah->regpair = ath9k_get_regpair(regdmn); 437 ah->regulatory.regpair = ath9k_get_regpair(regdmn);
440 438
441 if (!ah->regpair) { 439 if (!ah->regulatory.regpair) {
442 DPRINTF(ah->ah_sc, ATH_DBG_FATAL, 440 DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
443 "No regulatory domain pair found, cannot continue\n"); 441 "No regulatory domain pair found, cannot continue\n");
444 return -EINVAL; 442 return -EINVAL;
@@ -448,28 +446,28 @@ int ath9k_regd_init(struct ath_hal *ah)
448 country = ath9k_regd_find_country_by_rd(regdmn); 446 country = ath9k_regd_find_country_by_rd(regdmn);
449 447
450 if (country) { 448 if (country) {
451 ah->alpha2[0] = country->isoName[0]; 449 ah->regulatory.alpha2[0] = country->isoName[0];
452 ah->alpha2[1] = country->isoName[1]; 450 ah->regulatory.alpha2[1] = country->isoName[1];
453 } else { 451 } else {
454 ah->alpha2[0] = '0'; 452 ah->regulatory.alpha2[0] = '0';
455 ah->alpha2[1] = '0'; 453 ah->regulatory.alpha2[1] = '0';
456 } 454 }
457 455
458 DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, 456 DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
459 "Country alpha2 being used: %c%c\n" 457 "Country alpha2 being used: %c%c\n"
460 "Regpair detected: 0x%0x\n", 458 "Regulatory.Regpair detected: 0x%0x\n",
461 ah->alpha2[0], ah->alpha2[1], 459 ah->regulatory.alpha2[0], ah->regulatory.alpha2[1],
462 ah->regpair->regDmnEnum); 460 ah->regulatory.regpair->regDmnEnum);
463 461
464 return 0; 462 return 0;
465} 463}
466 464
467u32 ath9k_regd_get_ctl(struct ath_hal *ah, struct ath9k_channel *chan) 465u32 ath9k_regd_get_ctl(struct ath_hw *ah, struct ath9k_channel *chan)
468{ 466{
469 u32 ctl = NO_CTL; 467 u32 ctl = NO_CTL;
470 468
471 if (!ah->regpair || 469 if (!ah->regulatory.regpair ||
472 (ah->ah_countryCode == CTRY_DEFAULT && isWwrSKU(ah))) { 470 (ah->regulatory.country_code == CTRY_DEFAULT && isWwrSKU(ah))) {
473 if (IS_CHAN_B(chan)) 471 if (IS_CHAN_B(chan))
474 ctl = SD_NO_CTL | CTL_11B; 472 ctl = SD_NO_CTL | CTL_11B;
475 else if (IS_CHAN_G(chan)) 473 else if (IS_CHAN_G(chan))
@@ -480,11 +478,11 @@ u32 ath9k_regd_get_ctl(struct ath_hal *ah, struct ath9k_channel *chan)
480 } 478 }
481 479
482 if (IS_CHAN_B(chan)) 480 if (IS_CHAN_B(chan))
483 ctl = ah->regpair->reg_2ghz_ctl | CTL_11B; 481 ctl = ah->regulatory.regpair->reg_2ghz_ctl | CTL_11B;
484 else if (IS_CHAN_G(chan)) 482 else if (IS_CHAN_G(chan))
485 ctl = ah->regpair->reg_5ghz_ctl | CTL_11G; 483 ctl = ah->regulatory.regpair->reg_5ghz_ctl | CTL_11G;
486 else 484 else
487 ctl = ah->regpair->reg_5ghz_ctl | CTL_11A; 485 ctl = ah->regulatory.regpair->reg_5ghz_ctl | CTL_11A;
488 486
489 return ctl; 487 return ctl;
490} 488}
diff --git a/drivers/net/wireless/ath9k/regd.h b/drivers/net/wireless/ath9k/regd.h
index ba2d2dfb0d1f..39420de818f8 100644
--- a/drivers/net/wireless/ath9k/regd.h
+++ b/drivers/net/wireless/ath9k/regd.h
@@ -17,8 +17,6 @@
17#ifndef REGD_H 17#ifndef REGD_H
18#define REGD_H 18#define REGD_H
19 19
20#include "ath9k.h"
21
22#define COUNTRY_ERD_FLAG 0x8000 20#define COUNTRY_ERD_FLAG 0x8000
23#define WORLDWIDE_ROAMING_FLAG 0x4000 21#define WORLDWIDE_ROAMING_FLAG 0x4000
24 22
@@ -47,6 +45,18 @@ struct country_code_to_enum_rd {
47 const char *isoName; 45 const char *isoName;
48}; 46};
49 47
48struct ath9k_regulatory {
49 char alpha2[2];
50 u16 country_code;
51 u16 max_power_level;
52 u32 tp_scale;
53 u16 current_rd;
54 u16 current_rd_ext;
55 u16 current_rd_inuse;
56 int16_t power_limit;
57 struct reg_dmn_pair_mapping *regpair;
58};
59
50enum CountryCode { 60enum CountryCode {
51 CTRY_ALBANIA = 8, 61 CTRY_ALBANIA = 8,
52 CTRY_ALGERIA = 12, 62 CTRY_ALGERIA = 12,
@@ -229,7 +239,17 @@ enum CountryCode {
229 CTRY_BELGIUM2 = 5002 239 CTRY_BELGIUM2 = 5002
230}; 240};
231 241
232void ath9k_regd_get_current_country(struct ath_hal *ah, 242u16 ath9k_regd_get_rd(struct ath_hw *ah);
243bool ath9k_is_world_regd(struct ath_hw *ah);
244const struct ieee80211_regdomain *ath9k_world_regdomain(struct ath_hw *ah);
245const struct ieee80211_regdomain *ath9k_default_world_regdomain(void);
246void ath9k_reg_apply_world_flags(struct wiphy *wiphy, enum reg_set_by setby);
247void ath9k_reg_apply_radar_flags(struct wiphy *wiphy);
248int ath9k_regd_init(struct ath_hw *ah);
249bool ath9k_regd_is_eeprom_valid(struct ath_hw *ah);
250u32 ath9k_regd_get_ctl(struct ath_hw *ah, struct ath9k_channel *chan);
251int ath9k_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request);
252void ath9k_regd_get_current_country(struct ath_hw *ah,
233 struct ath9k_country_entry *ctry); 253 struct ath9k_country_entry *ctry);
234 254
235#endif 255#endif
diff --git a/drivers/net/wireless/ath9k/xmit.c b/drivers/net/wireless/ath9k/xmit.c
index e14bceaef125..3f70b1e58ae4 100644
--- a/drivers/net/wireless/ath9k/xmit.c
+++ b/drivers/net/wireless/ath9k/xmit.c
@@ -14,7 +14,7 @@
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */ 15 */
16 16
17#include "core.h" 17#include "ath9k.h"
18 18
19#define BITS_PER_BYTE 8 19#define BITS_PER_BYTE 8
20#define OFDM_PLCP_BITS 22 20#define OFDM_PLCP_BITS 22
@@ -308,7 +308,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
308 * when perform internal reset in this routine. 308 * when perform internal reset in this routine.
309 * Only enable reset in STA mode for now. 309 * Only enable reset in STA mode for now.
310 */ 310 */
311 if (sc->sc_ah->ah_opmode == NL80211_IFTYPE_STATION) 311 if (sc->sc_ah->opmode == NL80211_IFTYPE_STATION)
312 needreset = 1; 312 needreset = 1;
313 } 313 }
314 } 314 }
@@ -809,7 +809,7 @@ static void ath_txq_drain_pending_buffers(struct ath_softc *sc,
809 809
810struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype) 810struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype)
811{ 811{
812 struct ath_hal *ah = sc->sc_ah; 812 struct ath_hw *ah = sc->sc_ah;
813 struct ath9k_tx_queue_info qi; 813 struct ath9k_tx_queue_info qi;
814 int qnum; 814 int qnum;
815 815
@@ -926,7 +926,7 @@ struct ath_txq *ath_test_get_txq(struct ath_softc *sc, struct sk_buff *skb)
926int ath_txq_update(struct ath_softc *sc, int qnum, 926int ath_txq_update(struct ath_softc *sc, int qnum,
927 struct ath9k_tx_queue_info *qinfo) 927 struct ath9k_tx_queue_info *qinfo)
928{ 928{
929 struct ath_hal *ah = sc->sc_ah; 929 struct ath_hw *ah = sc->sc_ah;
930 int error = 0; 930 int error = 0;
931 struct ath9k_tx_queue_info qi; 931 struct ath9k_tx_queue_info qi;
932 932
@@ -970,14 +970,14 @@ int ath_cabq_update(struct ath_softc *sc)
970 /* 970 /*
971 * Ensure the readytime % is within the bounds. 971 * Ensure the readytime % is within the bounds.
972 */ 972 */
973 if (sc->sc_config.cabqReadytime < ATH9K_READY_TIME_LO_BOUND) 973 if (sc->config.cabqReadytime < ATH9K_READY_TIME_LO_BOUND)
974 sc->sc_config.cabqReadytime = ATH9K_READY_TIME_LO_BOUND; 974 sc->config.cabqReadytime = ATH9K_READY_TIME_LO_BOUND;
975 else if (sc->sc_config.cabqReadytime > ATH9K_READY_TIME_HI_BOUND) 975 else if (sc->config.cabqReadytime > ATH9K_READY_TIME_HI_BOUND)
976 sc->sc_config.cabqReadytime = ATH9K_READY_TIME_HI_BOUND; 976 sc->config.cabqReadytime = ATH9K_READY_TIME_HI_BOUND;
977 977
978 ath_get_beaconconfig(sc, ATH_IF_ID_ANY, &conf); 978 ath_get_beaconconfig(sc, ATH_IF_ID_ANY, &conf);
979 qi.tqi_readyTime = 979 qi.tqi_readyTime =
980 (conf.beacon_interval * sc->sc_config.cabqReadytime) / 100; 980 (conf.beacon_interval * sc->config.cabqReadytime) / 100;
981 ath_txq_update(sc, qnum, &qi); 981 ath_txq_update(sc, qnum, &qi);
982 982
983 return 0; 983 return 0;
@@ -1047,7 +1047,7 @@ void ath_draintxq(struct ath_softc *sc, struct ath_txq *txq, bool retry_tx)
1047 1047
1048void ath_drain_all_txq(struct ath_softc *sc, bool retry_tx) 1048void ath_drain_all_txq(struct ath_softc *sc, bool retry_tx)
1049{ 1049{
1050 struct ath_hal *ah = sc->sc_ah; 1050 struct ath_hw *ah = sc->sc_ah;
1051 struct ath_txq *txq; 1051 struct ath_txq *txq;
1052 int i, npend = 0; 1052 int i, npend = 0;
1053 1053
@@ -1072,7 +1072,7 @@ void ath_drain_all_txq(struct ath_softc *sc, bool retry_tx)
1072 DPRINTF(sc, ATH_DBG_XMIT, "Unable to stop TxDMA. Reset HAL!\n"); 1072 DPRINTF(sc, ATH_DBG_XMIT, "Unable to stop TxDMA. Reset HAL!\n");
1073 1073
1074 spin_lock_bh(&sc->sc_resetlock); 1074 spin_lock_bh(&sc->sc_resetlock);
1075 r = ath9k_hw_reset(ah, sc->sc_ah->ah_curchan, true); 1075 r = ath9k_hw_reset(ah, sc->sc_ah->curchan, true);
1076 if (r) 1076 if (r)
1077 DPRINTF(sc, ATH_DBG_FATAL, 1077 DPRINTF(sc, ATH_DBG_FATAL,
1078 "Unable to reset hardware; reset status %u\n", 1078 "Unable to reset hardware; reset status %u\n",
@@ -1165,7 +1165,7 @@ int ath_tx_setup(struct ath_softc *sc, int haltype)
1165static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq, 1165static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq,
1166 struct list_head *head) 1166 struct list_head *head)
1167{ 1167{
1168 struct ath_hal *ah = sc->sc_ah; 1168 struct ath_hw *ah = sc->sc_ah;
1169 struct ath_buf *bf; 1169 struct ath_buf *bf;
1170 1170
1171 /* 1171 /*
@@ -1436,14 +1436,18 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf)
1436 struct sk_buff *skb; 1436 struct sk_buff *skb;
1437 struct ieee80211_tx_info *tx_info; 1437 struct ieee80211_tx_info *tx_info;
1438 struct ieee80211_tx_rate *rates; 1438 struct ieee80211_tx_rate *rates;
1439 struct ieee80211_hdr *hdr;
1439 int i, flags = 0; 1440 int i, flags = 0;
1440 u8 rix = 0, ctsrate = 0; 1441 u8 rix = 0, ctsrate = 0;
1442 bool is_pspoll;
1441 1443
1442 memset(series, 0, sizeof(struct ath9k_11n_rate_series) * 4); 1444 memset(series, 0, sizeof(struct ath9k_11n_rate_series) * 4);
1443 1445
1444 skb = (struct sk_buff *)bf->bf_mpdu; 1446 skb = (struct sk_buff *)bf->bf_mpdu;
1445 tx_info = IEEE80211_SKB_CB(skb); 1447 tx_info = IEEE80211_SKB_CB(skb);
1446 rates = tx_info->control.rates; 1448 rates = tx_info->control.rates;
1449 hdr = (struct ieee80211_hdr *)skb->data;
1450 is_pspoll = ieee80211_is_pspoll(hdr->frame_control);
1447 1451
1448 /* 1452 /*
1449 * We check if Short Preamble is needed for the CTS rate by 1453 * We check if Short Preamble is needed for the CTS rate by
@@ -1467,13 +1471,13 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf)
1467 flags = ATH9K_TXDESC_RTSENA; 1471 flags = ATH9K_TXDESC_RTSENA;
1468 1472
1469 /* FIXME: Handle aggregation protection */ 1473 /* FIXME: Handle aggregation protection */
1470 if (sc->sc_config.ath_aggr_prot && 1474 if (sc->config.ath_aggr_prot &&
1471 (!bf_isaggr(bf) || (bf_isaggr(bf) && bf->bf_al < 8192))) { 1475 (!bf_isaggr(bf) || (bf_isaggr(bf) && bf->bf_al < 8192))) {
1472 flags = ATH9K_TXDESC_RTSENA; 1476 flags = ATH9K_TXDESC_RTSENA;
1473 } 1477 }
1474 1478
1475 /* For AR5416 - RTS cannot be followed by a frame larger than 8K */ 1479 /* For AR5416 - RTS cannot be followed by a frame larger than 8K */
1476 if (bf_isaggr(bf) && (bf->bf_al > sc->sc_ah->ah_caps.rts_aggr_limit)) 1480 if (bf_isaggr(bf) && (bf->bf_al > sc->sc_ah->caps.rts_aggr_limit))
1477 flags &= ~(ATH9K_TXDESC_RTSENA); 1481 flags &= ~(ATH9K_TXDESC_RTSENA);
1478 1482
1479 for (i = 0; i < 4; i++) { 1483 for (i = 0; i < 4; i++) {
@@ -1482,7 +1486,7 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf)
1482 1486
1483 rix = rates[i].idx; 1487 rix = rates[i].idx;
1484 series[i].Tries = rates[i].count; 1488 series[i].Tries = rates[i].count;
1485 series[i].ChSel = sc->sc_tx_chainmask; 1489 series[i].ChSel = sc->tx_chainmask;
1486 1490
1487 if (rates[i].flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE) 1491 if (rates[i].flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)
1488 series[i].Rate = rt->info[rix].ratecode | 1492 series[i].Rate = rt->info[rix].ratecode |
@@ -1506,10 +1510,10 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf)
1506 /* set dur_update_en for l-sig computation except for PS-Poll frames */ 1510 /* set dur_update_en for l-sig computation except for PS-Poll frames */
1507 ath9k_hw_set11n_ratescenario(sc->sc_ah, bf->bf_desc, 1511 ath9k_hw_set11n_ratescenario(sc->sc_ah, bf->bf_desc,
1508 bf->bf_lastbf->bf_desc, 1512 bf->bf_lastbf->bf_desc,
1509 !bf_ispspoll(bf), ctsrate, 1513 !is_pspoll, ctsrate,
1510 0, series, 4, flags); 1514 0, series, 4, flags);
1511 1515
1512 if (sc->sc_config.ath_aggr_prot && flags) 1516 if (sc->config.ath_aggr_prot && flags)
1513 ath9k_hw_set11n_burstduration(sc->sc_ah, bf->bf_desc, 8192); 1517 ath9k_hw_set11n_burstduration(sc->sc_ah, bf->bf_desc, 8192);
1514} 1518}
1515 1519
@@ -1534,12 +1538,6 @@ static int ath_tx_setup_buffer(struct ath_softc *sc, struct ath_buf *bf,
1534 1538
1535 bf->bf_frmlen = skb->len + FCS_LEN - (hdrlen & 3); 1539 bf->bf_frmlen = skb->len + FCS_LEN - (hdrlen & 3);
1536 1540
1537 if (ieee80211_is_data(fc))
1538 bf->bf_state.bf_type |= BUF_DATA;
1539 if (ieee80211_is_back_req(fc))
1540 bf->bf_state.bf_type |= BUF_BAR;
1541 if (ieee80211_is_pspoll(fc))
1542 bf->bf_state.bf_type |= BUF_PSPOLL;
1543 if ((conf_is_ht(&sc->hw->conf) && !is_pae(skb) && 1541 if ((conf_is_ht(&sc->hw->conf) && !is_pae(skb) &&
1544 (tx_info->flags & IEEE80211_TX_CTL_AMPDU))) 1542 (tx_info->flags & IEEE80211_TX_CTL_AMPDU)))
1545 bf->bf_state.bf_type |= BUF_HT; 1543 bf->bf_state.bf_type |= BUF_HT;
@@ -1582,7 +1580,7 @@ static void ath_tx_start_dma(struct ath_softc *sc, struct ath_buf *bf,
1582 struct list_head bf_head; 1580 struct list_head bf_head;
1583 struct ath_desc *ds; 1581 struct ath_desc *ds;
1584 struct ath_atx_tid *tid; 1582 struct ath_atx_tid *tid;
1585 struct ath_hal *ah = sc->sc_ah; 1583 struct ath_hw *ah = sc->sc_ah;
1586 int frm_type; 1584 int frm_type;
1587 1585
1588 frm_type = get_hw_packet_type(skb); 1586 frm_type = get_hw_packet_type(skb);
@@ -1843,6 +1841,7 @@ static int ath_tx_num_badfrms(struct ath_softc *sc, struct ath_buf *bf,
1843static void ath_tx_rc_status(struct ath_buf *bf, struct ath_desc *ds, int nbad) 1841static void ath_tx_rc_status(struct ath_buf *bf, struct ath_desc *ds, int nbad)
1844{ 1842{
1845 struct sk_buff *skb = (struct sk_buff *)bf->bf_mpdu; 1843 struct sk_buff *skb = (struct sk_buff *)bf->bf_mpdu;
1844 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
1846 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); 1845 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
1847 struct ath_tx_info_priv *tx_info_priv = ATH_TX_INFO_PRIV(tx_info); 1846 struct ath_tx_info_priv *tx_info_priv = ATH_TX_INFO_PRIV(tx_info);
1848 1847
@@ -1852,7 +1851,7 @@ static void ath_tx_rc_status(struct ath_buf *bf, struct ath_desc *ds, int nbad)
1852 1851
1853 if ((ds->ds_txstat.ts_status & ATH9K_TXERR_FILT) == 0 && 1852 if ((ds->ds_txstat.ts_status & ATH9K_TXERR_FILT) == 0 &&
1854 (bf->bf_flags & ATH9K_TXDESC_NOACK) == 0) { 1853 (bf->bf_flags & ATH9K_TXDESC_NOACK) == 0) {
1855 if (bf_isdata(bf)) { 1854 if (ieee80211_is_data(hdr->frame_control)) {
1856 memcpy(&tx_info_priv->tx, &ds->ds_txstat, 1855 memcpy(&tx_info_priv->tx, &ds->ds_txstat,
1857 sizeof(tx_info_priv->tx)); 1856 sizeof(tx_info_priv->tx));
1858 tx_info_priv->n_frames = bf->bf_nframes; 1857 tx_info_priv->n_frames = bf->bf_nframes;
@@ -1880,7 +1879,7 @@ static void ath_wake_mac80211_queue(struct ath_softc *sc, struct ath_txq *txq)
1880 1879
1881static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq) 1880static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
1882{ 1881{
1883 struct ath_hal *ah = sc->sc_ah; 1882 struct ath_hw *ah = sc->sc_ah;
1884 struct ath_buf *bf, *lastbf, *bf_held = NULL; 1883 struct ath_buf *bf, *lastbf, *bf_held = NULL;
1885 struct list_head bf_head; 1884 struct list_head bf_head;
1886 struct ath_desc *ds; 1885 struct ath_desc *ds;
diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h
index e9d60f0910be..b45731012782 100644
--- a/drivers/net/wireless/b43/b43.h
+++ b/drivers/net/wireless/b43/b43.h
@@ -120,6 +120,9 @@
120#define B43_MMIO_IFSCTL 0x688 /* Interframe space control */ 120#define B43_MMIO_IFSCTL 0x688 /* Interframe space control */
121#define B43_MMIO_IFSCTL_USE_EDCF 0x0004 121#define B43_MMIO_IFSCTL_USE_EDCF 0x0004
122#define B43_MMIO_POWERUP_DELAY 0x6A8 122#define B43_MMIO_POWERUP_DELAY 0x6A8
123#define B43_MMIO_BTCOEX_CTL 0x6B4 /* Bluetooth Coexistence Control */
124#define B43_MMIO_BTCOEX_STAT 0x6B6 /* Bluetooth Coexistence Status */
125#define B43_MMIO_BTCOEX_TXCTL 0x6B8 /* Bluetooth Coexistence Transmit Control */
123 126
124/* SPROM boardflags_lo values */ 127/* SPROM boardflags_lo values */
125#define B43_BFL_BTCOEXIST 0x0001 /* implements Bluetooth coexistance */ 128#define B43_BFL_BTCOEXIST 0x0001 /* implements Bluetooth coexistance */
diff --git a/drivers/net/wireless/b43/phy_lp.c b/drivers/net/wireless/b43/phy_lp.c
index 94d9e8b215e3..58e319d6b1ed 100644
--- a/drivers/net/wireless/b43/phy_lp.c
+++ b/drivers/net/wireless/b43/phy_lp.c
@@ -23,6 +23,7 @@
23*/ 23*/
24 24
25#include "b43.h" 25#include "b43.h"
26#include "main.h"
26#include "phy_lp.h" 27#include "phy_lp.h"
27#include "phy_common.h" 28#include "phy_common.h"
28#include "tables_lpphy.h" 29#include "tables_lpphy.h"
@@ -267,13 +268,185 @@ static void lpphy_radio_init(struct b43_wldev *dev)
267 } 268 }
268} 269}
269 270
271/* Read the TX power control mode from hardware. */
272static void lpphy_read_tx_pctl_mode_from_hardware(struct b43_wldev *dev)
273{
274 struct b43_phy_lp *lpphy = dev->phy.lp;
275 u16 ctl;
276
277 ctl = b43_phy_read(dev, B43_LPPHY_TX_PWR_CTL_CMD);
278 switch (ctl & B43_LPPHY_TX_PWR_CTL_CMD_MODE) {
279 case B43_LPPHY_TX_PWR_CTL_CMD_MODE_OFF:
280 lpphy->txpctl_mode = B43_LPPHY_TXPCTL_OFF;
281 break;
282 case B43_LPPHY_TX_PWR_CTL_CMD_MODE_SW:
283 lpphy->txpctl_mode = B43_LPPHY_TXPCTL_SW;
284 break;
285 case B43_LPPHY_TX_PWR_CTL_CMD_MODE_HW:
286 lpphy->txpctl_mode = B43_LPPHY_TXPCTL_HW;
287 break;
288 default:
289 lpphy->txpctl_mode = B43_LPPHY_TXPCTL_UNKNOWN;
290 B43_WARN_ON(1);
291 break;
292 }
293}
294
295/* Set the TX power control mode in hardware. */
296static void lpphy_write_tx_pctl_mode_to_hardware(struct b43_wldev *dev)
297{
298 struct b43_phy_lp *lpphy = dev->phy.lp;
299 u16 ctl;
300
301 switch (lpphy->txpctl_mode) {
302 case B43_LPPHY_TXPCTL_OFF:
303 ctl = B43_LPPHY_TX_PWR_CTL_CMD_MODE_OFF;
304 break;
305 case B43_LPPHY_TXPCTL_HW:
306 ctl = B43_LPPHY_TX_PWR_CTL_CMD_MODE_HW;
307 break;
308 case B43_LPPHY_TXPCTL_SW:
309 ctl = B43_LPPHY_TX_PWR_CTL_CMD_MODE_SW;
310 break;
311 default:
312 ctl = 0;
313 B43_WARN_ON(1);
314 }
315 b43_phy_maskset(dev, B43_LPPHY_TX_PWR_CTL_CMD,
316 (u16)~B43_LPPHY_TX_PWR_CTL_CMD_MODE, ctl);
317}
318
319static void lpphy_set_tx_power_control(struct b43_wldev *dev,
320 enum b43_lpphy_txpctl_mode mode)
321{
322 struct b43_phy_lp *lpphy = dev->phy.lp;
323 enum b43_lpphy_txpctl_mode oldmode;
324
325 oldmode = lpphy->txpctl_mode;
326 lpphy_read_tx_pctl_mode_from_hardware(dev);
327 if (lpphy->txpctl_mode == mode)
328 return;
329 lpphy->txpctl_mode = mode;
330
331 if (oldmode == B43_LPPHY_TXPCTL_HW) {
332 //TODO Update TX Power NPT
333 //TODO Clear all TX Power offsets
334 } else {
335 if (mode == B43_LPPHY_TXPCTL_HW) {
336 //TODO Recalculate target TX power
337 b43_phy_maskset(dev, B43_LPPHY_TX_PWR_CTL_CMD,
338 0xFF80, lpphy->tssi_idx);
339 b43_phy_maskset(dev, B43_LPPHY_TX_PWR_CTL_NNUM,
340 0x8FFF, ((u16)lpphy->tssi_npt << 16));
341 //TODO Set "TSSI Transmit Count" variable to total transmitted frame count
342 //TODO Disable TX gain override
343 lpphy->tx_pwr_idx_over = -1;
344 }
345 }
346 if (dev->phy.rev >= 2) {
347 if (mode == B43_LPPHY_TXPCTL_HW)
348 b43_phy_maskset(dev, B43_PHY_OFDM(0xD0), 0xFD, 0x2);
349 else
350 b43_phy_maskset(dev, B43_PHY_OFDM(0xD0), 0xFD, 0);
351 }
352 lpphy_write_tx_pctl_mode_to_hardware(dev);
353}
354
355static void lpphy_set_tx_power_by_index(struct b43_wldev *dev, u8 index)
356{
357 struct b43_phy_lp *lpphy = dev->phy.lp;
358
359 lpphy->tx_pwr_idx_over = index;
360 if (lpphy->txpctl_mode != B43_LPPHY_TXPCTL_OFF)
361 lpphy_set_tx_power_control(dev, B43_LPPHY_TXPCTL_SW);
362
363 //TODO
364}
365
366static void lpphy_btcoex_override(struct b43_wldev *dev)
367{
368 b43_write16(dev, B43_MMIO_BTCOEX_CTL, 0x3);
369 b43_write16(dev, B43_MMIO_BTCOEX_TXCTL, 0xFF);
370}
371
372static void lpphy_pr41573_workaround(struct b43_wldev *dev)
373{
374 struct b43_phy_lp *lpphy = dev->phy.lp;
375 u32 *saved_tab;
376 const unsigned int saved_tab_size = 256;
377 enum b43_lpphy_txpctl_mode txpctl_mode;
378 s8 tx_pwr_idx_over;
379 u16 tssi_npt, tssi_idx;
380
381 saved_tab = kcalloc(saved_tab_size, sizeof(saved_tab[0]), GFP_KERNEL);
382 if (!saved_tab) {
383 b43err(dev->wl, "PR41573 failed. Out of memory!\n");
384 return;
385 }
386
387 lpphy_read_tx_pctl_mode_from_hardware(dev);
388 txpctl_mode = lpphy->txpctl_mode;
389 tx_pwr_idx_over = lpphy->tx_pwr_idx_over;
390 tssi_npt = lpphy->tssi_npt;
391 tssi_idx = lpphy->tssi_idx;
392
393 if (dev->phy.rev < 2) {
394 b43_lptab_read_bulk(dev, B43_LPTAB32(10, 0x140),
395 saved_tab_size, saved_tab);
396 } else {
397 b43_lptab_read_bulk(dev, B43_LPTAB32(7, 0x140),
398 saved_tab_size, saved_tab);
399 }
400 //TODO
401
402 kfree(saved_tab);
403}
404
405static void lpphy_calibration(struct b43_wldev *dev)
406{
407 struct b43_phy_lp *lpphy = dev->phy.lp;
408 enum b43_lpphy_txpctl_mode saved_pctl_mode;
409
410 b43_mac_suspend(dev);
411
412 lpphy_btcoex_override(dev);
413 lpphy_read_tx_pctl_mode_from_hardware(dev);
414 saved_pctl_mode = lpphy->txpctl_mode;
415 lpphy_set_tx_power_control(dev, B43_LPPHY_TXPCTL_OFF);
416 //TODO Perform transmit power table I/Q LO calibration
417 if ((dev->phy.rev == 0) && (saved_pctl_mode != B43_LPPHY_TXPCTL_OFF))
418 lpphy_pr41573_workaround(dev);
419 //TODO If a full calibration has not been performed on this channel yet, perform PAPD TX-power calibration
420 lpphy_set_tx_power_control(dev, saved_pctl_mode);
421 //TODO Perform I/Q calibration with a single control value set
422
423 b43_mac_enable(dev);
424}
425
426/* Initialize TX power control */
427static void lpphy_tx_pctl_init(struct b43_wldev *dev)
428{
429 if (0/*FIXME HWPCTL capable */) {
430 //TODO
431 } else { /* This device is only software TX power control capable. */
432 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
433 //TODO
434 } else {
435 //TODO
436 }
437 //TODO set BB multiplier to 0x0096
438 }
439}
440
270static int b43_lpphy_op_init(struct b43_wldev *dev) 441static int b43_lpphy_op_init(struct b43_wldev *dev)
271{ 442{
272 /* TODO: band SPROM */ 443 /* TODO: band SPROM */
273 lpphy_baseband_init(dev); 444 lpphy_baseband_init(dev);
274 lpphy_radio_init(dev); 445 lpphy_radio_init(dev);
275 446 //TODO calibrate RC
276 //TODO 447 //TODO set channel
448 lpphy_tx_pctl_init(dev);
449 //TODO full calib
277 450
278 return 0; 451 return 0;
279} 452}
diff --git a/drivers/net/wireless/b43/phy_lp.h b/drivers/net/wireless/b43/phy_lp.h
index 80703c58102e..18370b4ac38e 100644
--- a/drivers/net/wireless/b43/phy_lp.h
+++ b/drivers/net/wireless/b43/phy_lp.h
@@ -247,6 +247,10 @@
247#define B43_LPPHY_FOURWIRE_CTL B43_PHY_OFDM(0xA2) /* fourwire Control */ 247#define B43_LPPHY_FOURWIRE_CTL B43_PHY_OFDM(0xA2) /* fourwire Control */
248#define B43_LPPHY_CPA_TAILCOUNT_VAL B43_PHY_OFDM(0xA3) /* CPA TailCount Value */ 248#define B43_LPPHY_CPA_TAILCOUNT_VAL B43_PHY_OFDM(0xA3) /* CPA TailCount Value */
249#define B43_LPPHY_TX_PWR_CTL_CMD B43_PHY_OFDM(0xA4) /* TX Power Control Cmd */ 249#define B43_LPPHY_TX_PWR_CTL_CMD B43_PHY_OFDM(0xA4) /* TX Power Control Cmd */
250#define B43_LPPHY_TX_PWR_CTL_CMD_MODE 0xE000 /* TX power control mode mask */
251#define B43_LPPHY_TX_PWR_CTL_CMD_MODE_OFF 0x0000 /* TX power control is OFF */
252#define B43_LPPHY_TX_PWR_CTL_CMD_MODE_SW 0x8000 /* TX power control is SOFTWARE */
253#define B43_LPPHY_TX_PWR_CTL_CMD_MODE_HW 0xE000 /* TX power control is HARDWARE */
250#define B43_LPPHY_TX_PWR_CTL_NNUM B43_PHY_OFDM(0xA5) /* TX Power Control Nnum */ 254#define B43_LPPHY_TX_PWR_CTL_NNUM B43_PHY_OFDM(0xA5) /* TX Power Control Nnum */
251#define B43_LPPHY_TX_PWR_CTL_IDLETSSI B43_PHY_OFDM(0xA6) /* TX Power Control IdleTssi */ 255#define B43_LPPHY_TX_PWR_CTL_IDLETSSI B43_PHY_OFDM(0xA6) /* TX Power Control IdleTssi */
252#define B43_LPPHY_TX_PWR_CTL_TARGETPWR B43_PHY_OFDM(0xA7) /* TX Power Control TargetPower */ 256#define B43_LPPHY_TX_PWR_CTL_TARGETPWR B43_PHY_OFDM(0xA7) /* TX Power Control TargetPower */
@@ -802,7 +806,17 @@
802 806
803 807
804 808
809enum b43_lpphy_txpctl_mode {
810 B43_LPPHY_TXPCTL_UNKNOWN = 0,
811 B43_LPPHY_TXPCTL_OFF, /* TX power control is OFF */
812 B43_LPPHY_TXPCTL_SW, /* TX power control is set to Software */
813 B43_LPPHY_TXPCTL_HW, /* TX power control is set to Hardware */
814};
815
805struct b43_phy_lp { 816struct b43_phy_lp {
817 /* Current TX power control mode. */
818 enum b43_lpphy_txpctl_mode txpctl_mode;
819
806 /* Transmit isolation medium band */ 820 /* Transmit isolation medium band */
807 u8 tx_isolation_med_band; /* FIXME initial value? */ 821 u8 tx_isolation_med_band; /* FIXME initial value? */
808 /* Transmit isolation low band */ 822 /* Transmit isolation low band */
@@ -814,7 +828,7 @@ struct b43_phy_lp {
814 u8 rx_pwr_offset; /* FIXME initial value? */ 828 u8 rx_pwr_offset; /* FIXME initial value? */
815 829
816 /* TSSI transmit count */ 830 /* TSSI transmit count */
817 u16 tssi_tx_count; /* FIXME initial value? */ 831 u16 tssi_tx_count;
818 /* TSSI index */ 832 /* TSSI index */
819 u16 tssi_idx; /* FIXME initial value? */ 833 u16 tssi_idx; /* FIXME initial value? */
820 /* TSSI npt */ 834 /* TSSI npt */
diff --git a/drivers/net/wireless/b43/tables_lpphy.c b/drivers/net/wireless/b43/tables_lpphy.c
index 18f6e3256766..4ea734dce218 100644
--- a/drivers/net/wireless/b43/tables_lpphy.c
+++ b/drivers/net/wireless/b43/tables_lpphy.c
@@ -303,6 +303,36 @@ u32 b43_lptab_read(struct b43_wldev *dev, u32 offset)
303 return value; 303 return value;
304} 304}
305 305
306void b43_lptab_read_bulk(struct b43_wldev *dev, u32 offset,
307 unsigned int nr_elements, void *_data)
308{
309 u32 type, value;
310 u8 *data = _data;
311 unsigned int i;
312
313 type = offset & B43_LPTAB_TYPEMASK;
314 for (i = 0; i < nr_elements; i++) {
315 value = b43_lptab_read(dev, offset);
316 switch (type) {
317 case B43_LPTAB_8BIT:
318 *data = value;
319 data++;
320 break;
321 case B43_LPTAB_16BIT:
322 *((u16 *)data) = value;
323 data += 2;
324 break;
325 case B43_LPTAB_32BIT:
326 *((u32 *)data) = value;
327 data += 4;
328 break;
329 default:
330 B43_WARN_ON(1);
331 }
332 offset++;
333 }
334}
335
306void b43_lptab_write(struct b43_wldev *dev, u32 offset, u32 value) 336void b43_lptab_write(struct b43_wldev *dev, u32 offset, u32 value)
307{ 337{
308 u32 type; 338 u32 type;
@@ -331,3 +361,34 @@ void b43_lptab_write(struct b43_wldev *dev, u32 offset, u32 value)
331 B43_WARN_ON(1); 361 B43_WARN_ON(1);
332 } 362 }
333} 363}
364
365void b43_lptab_write_bulk(struct b43_wldev *dev, u32 offset,
366 unsigned int nr_elements, const void *_data)
367{
368 u32 type, value;
369 const u8 *data = _data;
370 unsigned int i;
371
372 type = offset & B43_LPTAB_TYPEMASK;
373 for (i = 0; i < nr_elements; i++) {
374 switch (type) {
375 case B43_LPTAB_8BIT:
376 value = *data;
377 data++;
378 break;
379 case B43_LPTAB_16BIT:
380 value = *((u16 *)data);
381 data += 2;
382 break;
383 case B43_LPTAB_32BIT:
384 value = *((u32 *)data);
385 data += 4;
386 break;
387 default:
388 B43_WARN_ON(1);
389 value = 0;
390 }
391 b43_lptab_write(dev, offset, value);
392 offset++;
393 }
394}
diff --git a/drivers/net/wireless/b43/tables_lpphy.h b/drivers/net/wireless/b43/tables_lpphy.h
index 03ea2ff5d13a..0b8d02895a5d 100644
--- a/drivers/net/wireless/b43/tables_lpphy.h
+++ b/drivers/net/wireless/b43/tables_lpphy.h
@@ -17,6 +17,14 @@
17u32 b43_lptab_read(struct b43_wldev *dev, u32 offset); 17u32 b43_lptab_read(struct b43_wldev *dev, u32 offset);
18void b43_lptab_write(struct b43_wldev *dev, u32 offset, u32 value); 18void b43_lptab_write(struct b43_wldev *dev, u32 offset, u32 value);
19 19
20/* Bulk table access. Note that these functions return the bulk data in
21 * host endianness! The returned data is _not_ a bytearray, but an array
22 * consisting of nr_elements of the data type. */
23void b43_lptab_read_bulk(struct b43_wldev *dev, u32 offset,
24 unsigned int nr_elements, void *data);
25void b43_lptab_write_bulk(struct b43_wldev *dev, u32 offset,
26 unsigned int nr_elements, const void *data);
27
20void b2062_upload_init_table(struct b43_wldev *dev); 28void b2062_upload_init_table(struct b43_wldev *dev);
21 29
22 30
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-hw.h b/drivers/net/wireless/iwlwifi/iwl-3945-hw.h
index 1327b2ac1c53..205603d082aa 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945-hw.h
+++ b/drivers/net/wireless/iwlwifi/iwl-3945-hw.h
@@ -229,12 +229,6 @@ struct iwl3945_eeprom {
229 229
230/* End of EEPROM */ 230/* End of EEPROM */
231 231
232
233#define PCI_LINK_CTRL 0x0F0
234#define PCI_POWER_SOURCE 0x0C8
235#define PCI_REG_WUM8 0x0E8
236#define PCI_CFG_PMC_PME_FROM_D3COLD_SUPPORT (0x80000000)
237
238#define PCI_CFG_REV_ID_BIT_BASIC_SKU (0x40) /* bit 6 */ 232#define PCI_CFG_REV_ID_BIT_BASIC_SKU (0x40) /* bit 6 */
239#define PCI_CFG_REV_ID_BIT_RTP (0x80) /* bit 7 */ 233#define PCI_CFG_REV_ID_BIT_RTP (0x80) /* bit 7 */
240 234
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c
index cb6db4525dc3..d49e48b9b037 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.c
@@ -905,22 +905,18 @@ u8 iwl3945_sync_sta(struct iwl_priv *priv, int sta_id, u16 tx_rate, u8 flags)
905 905
906static int iwl3945_set_pwr_src(struct iwl_priv *priv, enum iwl_pwr_src src) 906static int iwl3945_set_pwr_src(struct iwl_priv *priv, enum iwl_pwr_src src)
907{ 907{
908 int rc; 908 int ret;
909 unsigned long flags; 909 unsigned long flags;
910 910
911 spin_lock_irqsave(&priv->lock, flags); 911 spin_lock_irqsave(&priv->lock, flags);
912 rc = iwl_grab_nic_access(priv); 912 ret = iwl_grab_nic_access(priv);
913 if (rc) { 913 if (ret) {
914 spin_unlock_irqrestore(&priv->lock, flags); 914 spin_unlock_irqrestore(&priv->lock, flags);
915 return rc; 915 return ret;
916 } 916 }
917 917
918 if (src == IWL_PWR_SRC_VAUX) { 918 if (src == IWL_PWR_SRC_VAUX) {
919 u32 val; 919 if (pci_pme_capable(priv->pci_dev, PCI_D3cold)) {
920
921 rc = pci_read_config_dword(priv->pci_dev,
922 PCI_POWER_SOURCE, &val);
923 if (val & PCI_CFG_PMC_PME_FROM_D3COLD_SUPPORT) {
924 iwl_set_bits_mask_prph(priv, APMG_PS_CTRL_REG, 920 iwl_set_bits_mask_prph(priv, APMG_PS_CTRL_REG,
925 APMG_PS_CTRL_VAL_PWR_SRC_VAUX, 921 APMG_PS_CTRL_VAL_PWR_SRC_VAUX,
926 ~APMG_PS_CTRL_MSK_PWR_SRC); 922 ~APMG_PS_CTRL_MSK_PWR_SRC);
@@ -929,8 +925,9 @@ static int iwl3945_set_pwr_src(struct iwl_priv *priv, enum iwl_pwr_src src)
929 iwl_poll_bit(priv, CSR_GPIO_IN, 925 iwl_poll_bit(priv, CSR_GPIO_IN,
930 CSR_GPIO_IN_VAL_VAUX_PWR_SRC, 926 CSR_GPIO_IN_VAL_VAUX_PWR_SRC,
931 CSR_GPIO_IN_BIT_AUX_POWER, 5000); 927 CSR_GPIO_IN_BIT_AUX_POWER, 5000);
932 } else 928 } else {
933 iwl_release_nic_access(priv); 929 iwl_release_nic_access(priv);
930 }
934 } else { 931 } else {
935 iwl_set_bits_mask_prph(priv, APMG_PS_CTRL_REG, 932 iwl_set_bits_mask_prph(priv, APMG_PS_CTRL_REG,
936 APMG_PS_CTRL_VAL_PWR_SRC_VMAIN, 933 APMG_PS_CTRL_VAL_PWR_SRC_VMAIN,
@@ -942,7 +939,7 @@ static int iwl3945_set_pwr_src(struct iwl_priv *priv, enum iwl_pwr_src src)
942 } 939 }
943 spin_unlock_irqrestore(&priv->lock, flags); 940 spin_unlock_irqrestore(&priv->lock, flags);
944 941
945 return rc; 942 return ret;
946} 943}
947 944
948static int iwl3945_rx_init(struct iwl_priv *priv, struct iwl_rx_queue *rxq) 945static int iwl3945_rx_init(struct iwl_priv *priv, struct iwl_rx_queue *rxq)
@@ -2741,8 +2738,8 @@ static struct iwl_lib_ops iwl3945_lib = {
2741 EEPROM_REGULATORY_BAND_3_CHANNELS, 2738 EEPROM_REGULATORY_BAND_3_CHANNELS,
2742 EEPROM_REGULATORY_BAND_4_CHANNELS, 2739 EEPROM_REGULATORY_BAND_4_CHANNELS,
2743 EEPROM_REGULATORY_BAND_5_CHANNELS, 2740 EEPROM_REGULATORY_BAND_5_CHANNELS,
2744 IWL3945_EEPROM_IMG_SIZE, 2741 EEPROM_REGULATORY_BAND_NO_FAT,
2745 IWL3945_EEPROM_IMG_SIZE, 2742 EEPROM_REGULATORY_BAND_NO_FAT,
2746 }, 2743 },
2747 .verify_signature = iwlcore_eeprom_verify_signature, 2744 .verify_signature = iwlcore_eeprom_verify_signature,
2748 .acquire_semaphore = iwl3945_eeprom_acquire_semaphore, 2745 .acquire_semaphore = iwl3945_eeprom_acquire_semaphore,
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965-hw.h b/drivers/net/wireless/iwlwifi/iwl-4965-hw.h
index af4c1bb0de14..a71a489096ff 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965-hw.h
+++ b/drivers/net/wireless/iwlwifi/iwl-4965-hw.h
@@ -92,19 +92,12 @@
92#define IWL49_RSSI_OFFSET 44 92#define IWL49_RSSI_OFFSET 44
93 93
94 94
95
96/* PCI registers */ 95/* PCI registers */
97#define PCI_CFG_RETRY_TIMEOUT 0x041 96#define PCI_CFG_RETRY_TIMEOUT 0x041
98#define PCI_CFG_POWER_SOURCE 0x0C8
99#define PCI_REG_WUM8 0x0E8
100#define PCI_CFG_LINK_CTRL 0x0F0
101 97
102/* PCI register values */ 98/* PCI register values */
103#define PCI_CFG_LINK_CTRL_VAL_L0S_EN 0x01 99#define PCI_CFG_LINK_CTRL_VAL_L0S_EN 0x01
104#define PCI_CFG_LINK_CTRL_VAL_L1_EN 0x02 100#define PCI_CFG_LINK_CTRL_VAL_L1_EN 0x02
105#define PCI_CFG_CMD_REG_INT_DIS_MSK 0x04
106#define PCI_CFG_PMC_PME_FROM_D3COLD_SUPPORT (0x80000000)
107
108 101
109#define IWL_NUM_SCAN_RATES (2) 102#define IWL_NUM_SCAN_RATES (2)
110 103
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c
index 0638f3e37602..bd0140be774e 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965.c
@@ -381,27 +381,20 @@ out:
381static void iwl4965_nic_config(struct iwl_priv *priv) 381static void iwl4965_nic_config(struct iwl_priv *priv)
382{ 382{
383 unsigned long flags; 383 unsigned long flags;
384 u32 val;
385 u16 radio_cfg; 384 u16 radio_cfg;
386 u16 link; 385 u16 lctl;
387 386
388 spin_lock_irqsave(&priv->lock, flags); 387 spin_lock_irqsave(&priv->lock, flags);
389 388
390 if ((priv->rev_id & 0x80) == 0x80 && (priv->rev_id & 0x7f) < 8) { 389 lctl = iwl_pcie_link_ctl(priv);
391 pci_read_config_dword(priv->pci_dev, PCI_REG_WUM8, &val);
392 /* Enable No Snoop field */
393 pci_write_config_dword(priv->pci_dev, PCI_REG_WUM8,
394 val & ~(1 << 11));
395 }
396
397 pci_read_config_word(priv->pci_dev, PCI_CFG_LINK_CTRL, &link);
398 390
399 /* L1 is enabled by BIOS */ 391 /* HW bug W/A - negligible power consumption */
400 if ((link & PCI_CFG_LINK_CTRL_VAL_L1_EN) == PCI_CFG_LINK_CTRL_VAL_L1_EN) 392 /* L1-ASPM is enabled by BIOS */
401 /* disable L0S disabled L1A enabled */ 393 if ((lctl & PCI_CFG_LINK_CTRL_VAL_L1_EN) == PCI_CFG_LINK_CTRL_VAL_L1_EN)
394 /* L1-ASPM enabled: disable L0S */
402 iwl_set_bit(priv, CSR_GIO_REG, CSR_GIO_REG_VAL_L0S_ENABLED); 395 iwl_set_bit(priv, CSR_GIO_REG, CSR_GIO_REG_VAL_L0S_ENABLED);
403 else 396 else
404 /* L0S enabled L1A disabled */ 397 /* L1-ASPM disabled: enable L0S */
405 iwl_clear_bit(priv, CSR_GIO_REG, CSR_GIO_REG_VAL_L0S_ENABLED); 398 iwl_clear_bit(priv, CSR_GIO_REG, CSR_GIO_REG_VAL_L0S_ENABLED);
406 399
407 radio_cfg = iwl_eeprom_query16(priv, EEPROM_RADIO_CONFIG); 400 radio_cfg = iwl_eeprom_query16(priv, EEPROM_RADIO_CONFIG);
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c
index e3cba61d1543..ab39f4ae8e32 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
@@ -219,18 +219,19 @@ static void iwl5000_nic_config(struct iwl_priv *priv)
219{ 219{
220 unsigned long flags; 220 unsigned long flags;
221 u16 radio_cfg; 221 u16 radio_cfg;
222 u16 link; 222 u16 lctl;
223 223
224 spin_lock_irqsave(&priv->lock, flags); 224 spin_lock_irqsave(&priv->lock, flags);
225 225
226 pci_read_config_word(priv->pci_dev, PCI_CFG_LINK_CTRL, &link); 226 lctl = iwl_pcie_link_ctl(priv);
227 227
228 /* L1 is enabled by BIOS */ 228 /* HW bug W/A */
229 if ((link & PCI_CFG_LINK_CTRL_VAL_L1_EN) == PCI_CFG_LINK_CTRL_VAL_L1_EN) 229 /* L1-ASPM is enabled by BIOS */
230 /* disable L0S disabled L1A enabled */ 230 if ((lctl & PCI_CFG_LINK_CTRL_VAL_L1_EN) == PCI_CFG_LINK_CTRL_VAL_L1_EN)
231 /* L1-APSM enabled: disable L0S */
231 iwl_set_bit(priv, CSR_GIO_REG, CSR_GIO_REG_VAL_L0S_ENABLED); 232 iwl_set_bit(priv, CSR_GIO_REG, CSR_GIO_REG_VAL_L0S_ENABLED);
232 else 233 else
233 /* L0S enabled L1A disabled */ 234 /* L1-ASPM disabled: enable L0S */
234 iwl_clear_bit(priv, CSR_GIO_REG, CSR_GIO_REG_VAL_L0S_ENABLED); 235 iwl_clear_bit(priv, CSR_GIO_REG, CSR_GIO_REG_VAL_L0S_ENABLED);
235 236
236 radio_cfg = iwl_eeprom_query16(priv, EEPROM_RADIO_CONFIG); 237 radio_cfg = iwl_eeprom_query16(priv, EEPROM_RADIO_CONFIG);
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index c196abc6db7a..397577c06c92 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -940,11 +940,7 @@ int iwl_set_pwr_src(struct iwl_priv *priv, enum iwl_pwr_src src)
940 goto err; 940 goto err;
941 941
942 if (src == IWL_PWR_SRC_VAUX) { 942 if (src == IWL_PWR_SRC_VAUX) {
943 u32 val; 943 if (pci_pme_capable(priv->pci_dev, PCI_D3cold))
944 ret = pci_read_config_dword(priv->pci_dev, PCI_CFG_POWER_SOURCE,
945 &val);
946
947 if (val & PCI_CFG_PMC_PME_FROM_D3COLD_SUPPORT)
948 iwl_set_bits_mask_prph(priv, APMG_PS_CTRL_REG, 944 iwl_set_bits_mask_prph(priv, APMG_PS_CTRL_REG,
949 APMG_PS_CTRL_VAL_PWR_SRC_VAUX, 945 APMG_PS_CTRL_VAL_PWR_SRC_VAUX,
950 ~APMG_PS_CTRL_MSK_PWR_SRC); 946 ~APMG_PS_CTRL_MSK_PWR_SRC);
@@ -2678,11 +2674,19 @@ static void iwl_bss_info_changed(struct ieee80211_hw *hw,
2678 2674
2679} 2675}
2680 2676
2681static int iwl_mac_hw_scan(struct ieee80211_hw *hw, u8 *ssid, size_t ssid_len) 2677static int iwl_mac_hw_scan(struct ieee80211_hw *hw,
2678 struct cfg80211_scan_request *req)
2682{ 2679{
2683 unsigned long flags; 2680 unsigned long flags;
2684 struct iwl_priv *priv = hw->priv; 2681 struct iwl_priv *priv = hw->priv;
2685 int ret; 2682 int ret;
2683 u8 *ssid = NULL;
2684 size_t ssid_len = 0;
2685
2686 if (req->n_ssids) {
2687 ssid = req->ssids[0].ssid;
2688 ssid_len = req->ssids[0].ssid_len;
2689 }
2686 2690
2687 IWL_DEBUG_MAC80211(priv, "enter\n"); 2691 IWL_DEBUG_MAC80211(priv, "enter\n");
2688 2692
@@ -2718,7 +2722,7 @@ static int iwl_mac_hw_scan(struct ieee80211_hw *hw, u8 *ssid, size_t ssid_len)
2718 2722
2719 if (ssid_len) { 2723 if (ssid_len) {
2720 priv->one_direct_scan = 1; 2724 priv->one_direct_scan = 1;
2721 priv->direct_ssid_len = min_t(u8, ssid_len, IW_ESSID_MAX_SIZE); 2725 priv->direct_ssid_len = ssid_len;
2722 memcpy(priv->direct_ssid, ssid, priv->direct_ssid_len); 2726 memcpy(priv->direct_ssid, ssid, priv->direct_ssid_len);
2723 } else { 2727 } else {
2724 priv->one_direct_scan = 0; 2728 priv->one_direct_scan = 0;
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index e18c3f326f71..260bf903cb71 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -1271,6 +1271,7 @@ int iwl_setup_mac(struct iwl_priv *priv)
1271 BIT(NL80211_IFTYPE_ADHOC); 1271 BIT(NL80211_IFTYPE_ADHOC);
1272 1272
1273 hw->wiphy->custom_regulatory = true; 1273 hw->wiphy->custom_regulatory = true;
1274 hw->wiphy->max_scan_ssids = 1;
1274 1275
1275 /* Default value; 4 EDCA QOS priorities */ 1276 /* Default value; 4 EDCA QOS priorities */
1276 hw->queues = 4; 1277 hw->queues = 4;
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index d79912ba6a2f..9d464ec99dd5 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -410,6 +410,14 @@ int iwl_send_card_state(struct iwl_priv *priv, u32 flags,
410 *****************************************************/ 410 *****************************************************/
411void iwl_disable_interrupts(struct iwl_priv *priv); 411void iwl_disable_interrupts(struct iwl_priv *priv);
412void iwl_enable_interrupts(struct iwl_priv *priv); 412void iwl_enable_interrupts(struct iwl_priv *priv);
413static inline u16 iwl_pcie_link_ctl(struct iwl_priv *priv)
414{
415 int pos;
416 u16 pci_lnk_ctl;
417 pos = pci_find_capability(priv->pci_dev, PCI_CAP_ID_EXP);
418 pci_read_config_word(priv->pci_dev, pos + PCI_EXP_LNKCTL, &pci_lnk_ctl);
419 return pci_lnk_ctl;
420}
413 421
414/***************************************************** 422/*****************************************************
415* Error Handling Debugging 423* Error Handling Debugging
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-eeprom.c
index d1d1d9bcfeae..75517d05df08 100644
--- a/drivers/net/wireless/iwlwifi/iwl-eeprom.c
+++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.c
@@ -532,10 +532,10 @@ int iwl_init_channel_map(struct iwl_priv *priv)
532 } 532 }
533 533
534 /* Check if we do have FAT channels */ 534 /* Check if we do have FAT channels */
535 if (priv->cfg->ops->lib->eeprom_ops.regulatory_bands[5] >= 535 if (priv->cfg->ops->lib->eeprom_ops.regulatory_bands[5] ==
536 priv->cfg->eeprom_size && 536 EEPROM_REGULATORY_BAND_NO_FAT &&
537 priv->cfg->ops->lib->eeprom_ops.regulatory_bands[6] >= 537 priv->cfg->ops->lib->eeprom_ops.regulatory_bands[6] ==
538 priv->cfg->eeprom_size) 538 EEPROM_REGULATORY_BAND_NO_FAT)
539 return 0; 539 return 0;
540 540
541 /* Two additional EEPROM bands for 2.4 and 5 GHz FAT channels */ 541 /* Two additional EEPROM bands for 2.4 and 5 GHz FAT channels */
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.h b/drivers/net/wireless/iwlwifi/iwl-eeprom.h
index 17fed49f9d96..3479153d96ca 100644
--- a/drivers/net/wireless/iwlwifi/iwl-eeprom.h
+++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.h
@@ -370,6 +370,8 @@ struct iwl_eeprom_calib_info {
370 */ 370 */
371#define EEPROM_4965_REGULATORY_BAND_52_FAT_CHANNELS (2*0xA8) /* 22 bytes */ 371#define EEPROM_4965_REGULATORY_BAND_52_FAT_CHANNELS (2*0xA8) /* 22 bytes */
372 372
373#define EEPROM_REGULATORY_BAND_NO_FAT (0)
374
373struct iwl_eeprom_ops { 375struct iwl_eeprom_ops {
374 const u32 regulatory_bands[7]; 376 const u32 regulatory_bands[7];
375 int (*verify_signature) (struct iwl_priv *priv); 377 int (*verify_signature) (struct iwl_priv *priv);
diff --git a/drivers/net/wireless/iwlwifi/iwl-power.c b/drivers/net/wireless/iwlwifi/iwl-power.c
index 4c5a775f48b7..18b7e4195ea1 100644
--- a/drivers/net/wireless/iwlwifi/iwl-power.c
+++ b/drivers/net/wireless/iwlwifi/iwl-power.c
@@ -141,7 +141,7 @@ static void iwl_power_init_handle(struct iwl_priv *priv)
141 int size = sizeof(struct iwl_power_vec_entry) * IWL_POWER_MAX; 141 int size = sizeof(struct iwl_power_vec_entry) * IWL_POWER_MAX;
142 struct iwl_powertable_cmd *cmd; 142 struct iwl_powertable_cmd *cmd;
143 int i; 143 int i;
144 u16 pci_pm; 144 u16 lctl;
145 145
146 IWL_DEBUG_POWER(priv, "Initialize power \n"); 146 IWL_DEBUG_POWER(priv, "Initialize power \n");
147 147
@@ -153,14 +153,14 @@ static void iwl_power_init_handle(struct iwl_priv *priv)
153 memcpy(&pow_data->pwr_range_1[0], &range_1[0], size); 153 memcpy(&pow_data->pwr_range_1[0], &range_1[0], size);
154 memcpy(&pow_data->pwr_range_2[0], &range_2[0], size); 154 memcpy(&pow_data->pwr_range_2[0], &range_2[0], size);
155 155
156 pci_read_config_word(priv->pci_dev, PCI_CFG_LINK_CTRL, &pci_pm); 156 lctl = iwl_pcie_link_ctl(priv);
157 157
158 IWL_DEBUG_POWER(priv, "adjust power command flags\n"); 158 IWL_DEBUG_POWER(priv, "adjust power command flags\n");
159 159
160 for (i = 0; i < IWL_POWER_MAX; i++) { 160 for (i = 0; i < IWL_POWER_MAX; i++) {
161 cmd = &pow_data->pwr_range_0[i].cmd; 161 cmd = &pow_data->pwr_range_0[i].cmd;
162 162
163 if (pci_pm & PCI_CFG_LINK_CTRL_VAL_L0S_EN) 163 if (lctl & PCI_CFG_LINK_CTRL_VAL_L0S_EN)
164 cmd->flags &= ~IWL_POWER_PCI_PM_MSK; 164 cmd->flags &= ~IWL_POWER_PCI_PM_MSK;
165 else 165 else
166 cmd->flags |= IWL_POWER_PCI_PM_MSK; 166 cmd->flags |= IWL_POWER_PCI_PM_MSK;
diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c
index 22bad3ce7d6a..1ec2b20eb37c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-scan.c
+++ b/drivers/net/wireless/iwlwifi/iwl-scan.c
@@ -860,7 +860,7 @@ void iwl_bg_scan_completed(struct work_struct *work)
860 if (test_bit(STATUS_EXIT_PENDING, &priv->status)) 860 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
861 return; 861 return;
862 862
863 ieee80211_scan_completed(priv->hw); 863 ieee80211_scan_completed(priv->hw, false);
864 864
865 /* Since setting the TXPOWER may have been deferred while 865 /* Since setting the TXPOWER may have been deferred while
866 * performing the scan, fire one off */ 866 * performing the scan, fire one off */
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index 42cc2884971c..0cd8cb96a5ef 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -4442,15 +4442,23 @@ static void iwl3945_bss_info_changed(struct ieee80211_hw *hw,
4442 4442
4443} 4443}
4444 4444
4445static int iwl3945_mac_hw_scan(struct ieee80211_hw *hw, u8 *ssid, size_t len) 4445static int iwl3945_mac_hw_scan(struct ieee80211_hw *hw,
4446 struct cfg80211_scan_request *req)
4446{ 4447{
4447 int rc = 0; 4448 int rc = 0;
4448 unsigned long flags; 4449 unsigned long flags;
4449 struct iwl_priv *priv = hw->priv; 4450 struct iwl_priv *priv = hw->priv;
4451 size_t len = 0;
4452 u8 *ssid = NULL;
4450 DECLARE_SSID_BUF(ssid_buf); 4453 DECLARE_SSID_BUF(ssid_buf);
4451 4454
4452 IWL_DEBUG_MAC80211(priv, "enter\n"); 4455 IWL_DEBUG_MAC80211(priv, "enter\n");
4453 4456
4457 if (req->n_ssids) {
4458 ssid = req->ssids[0].ssid;
4459 len = req->ssids[0].ssid_len;
4460 }
4461
4454 mutex_lock(&priv->mutex); 4462 mutex_lock(&priv->mutex);
4455 spin_lock_irqsave(&priv->lock, flags); 4463 spin_lock_irqsave(&priv->lock, flags);
4456 4464
@@ -4478,9 +4486,8 @@ static int iwl3945_mac_hw_scan(struct ieee80211_hw *hw, u8 *ssid, size_t len)
4478 print_ssid(ssid_buf, ssid, len), len); 4486 print_ssid(ssid_buf, ssid, len), len);
4479 4487
4480 priv->one_direct_scan = 1; 4488 priv->one_direct_scan = 1;
4481 priv->direct_ssid_len = (u8) 4489 priv->direct_ssid_len = len;
4482 min((u8) len, (u8) IW_ESSID_MAX_SIZE); 4490 memcpy(priv->direct_ssid, ssid, len);
4483 memcpy(priv->direct_ssid, ssid, priv->direct_ssid_len);
4484 } else 4491 } else
4485 priv->one_direct_scan = 0; 4492 priv->one_direct_scan = 0;
4486 4493
@@ -5412,6 +5419,8 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
5412 5419
5413 hw->wiphy->custom_regulatory = true; 5420 hw->wiphy->custom_regulatory = true;
5414 5421
5422 hw->wiphy->max_scan_ssids = 1;
5423
5415 /* 4 EDCA QOS priorities */ 5424 /* 4 EDCA QOS priorities */
5416 hw->queues = 4; 5425 hw->queues = 4;
5417 5426
diff --git a/drivers/net/wireless/orinoco/Makefile b/drivers/net/wireless/orinoco/Makefile
index 791366e08c50..1fc7409d6699 100644
--- a/drivers/net/wireless/orinoco/Makefile
+++ b/drivers/net/wireless/orinoco/Makefile
@@ -1,8 +1,9 @@
1# 1#
2# Makefile for the orinoco wireless device drivers. 2# Makefile for the orinoco wireless device drivers.
3# 3#
4orinoco-objs := main.o fw.o hw.o mic.o scan.o wext.o hermes_dld.o hermes.o
4 5
5obj-$(CONFIG_HERMES) += orinoco.o hermes.o hermes_dld.o 6obj-$(CONFIG_HERMES) += orinoco.o
6obj-$(CONFIG_PCMCIA_HERMES) += orinoco_cs.o 7obj-$(CONFIG_PCMCIA_HERMES) += orinoco_cs.o
7obj-$(CONFIG_APPLE_AIRPORT) += airport.o 8obj-$(CONFIG_APPLE_AIRPORT) += airport.o
8obj-$(CONFIG_PLX_HERMES) += orinoco_plx.o 9obj-$(CONFIG_PLX_HERMES) += orinoco_plx.o
diff --git a/drivers/net/wireless/orinoco/airport.c b/drivers/net/wireless/orinoco/airport.c
index 5582dca9f7f5..8c4065f1b0d0 100644
--- a/drivers/net/wireless/orinoco/airport.c
+++ b/drivers/net/wireless/orinoco/airport.c
@@ -3,7 +3,7 @@
3 * A driver for "Hermes" chipset based Apple Airport wireless 3 * A driver for "Hermes" chipset based Apple Airport wireless
4 * card. 4 * card.
5 * 5 *
6 * Copyright notice & release notes in file orinoco.c 6 * Copyright notice & release notes in file main.c
7 * 7 *
8 * Note specific to airport stub: 8 * Note specific to airport stub:
9 * 9 *
diff --git a/drivers/net/wireless/orinoco/fw.c b/drivers/net/wireless/orinoco/fw.c
new file mode 100644
index 000000000000..7d2292d6ce09
--- /dev/null
+++ b/drivers/net/wireless/orinoco/fw.c
@@ -0,0 +1,340 @@
1/* Firmware file reading and download helpers
2 *
3 * See copyright notice in main.c
4 */
5#include <linux/kernel.h>
6#include <linux/firmware.h>
7
8#include "hermes.h"
9#include "hermes_dld.h"
10#include "orinoco.h"
11
12#include "fw.h"
13
14/* End markers (for Symbol firmware only) */
15#define TEXT_END 0x1A /* End of text header */
16
17struct fw_info {
18 char *pri_fw;
19 char *sta_fw;
20 char *ap_fw;
21 u32 pda_addr;
22 u16 pda_size;
23};
24
25static const struct fw_info orinoco_fw[] = {
26 { NULL, "agere_sta_fw.bin", "agere_ap_fw.bin", 0x00390000, 1000 },
27 { NULL, "prism_sta_fw.bin", "prism_ap_fw.bin", 0, 1024 },
28 { "symbol_sp24t_prim_fw", "symbol_sp24t_sec_fw", NULL, 0x00003100, 512 }
29};
30
31/* Structure used to access fields in FW
32 * Make sure LE decoding macros are used
33 */
34struct orinoco_fw_header {
35 char hdr_vers[6]; /* ASCII string for header version */
36 __le16 headersize; /* Total length of header */
37 __le32 entry_point; /* NIC entry point */
38 __le32 blocks; /* Number of blocks to program */
39 __le32 block_offset; /* Offset of block data from eof header */
40 __le32 pdr_offset; /* Offset to PDR data from eof header */
41 __le32 pri_offset; /* Offset to primary plug data */
42 __le32 compat_offset; /* Offset to compatibility data*/
43 char signature[0]; /* FW signature length headersize-20 */
44} __attribute__ ((packed));
45
46/* Download either STA or AP firmware into the card. */
47static int
48orinoco_dl_firmware(struct orinoco_private *priv,
49 const struct fw_info *fw,
50 int ap)
51{
52 /* Plug Data Area (PDA) */
53 __le16 *pda;
54
55 hermes_t *hw = &priv->hw;
56 const struct firmware *fw_entry;
57 const struct orinoco_fw_header *hdr;
58 const unsigned char *first_block;
59 const unsigned char *end;
60 const char *firmware;
61 struct net_device *dev = priv->ndev;
62 int err = 0;
63
64 pda = kzalloc(fw->pda_size, GFP_KERNEL);
65 if (!pda)
66 return -ENOMEM;
67
68 if (ap)
69 firmware = fw->ap_fw;
70 else
71 firmware = fw->sta_fw;
72
73 printk(KERN_DEBUG "%s: Attempting to download firmware %s\n",
74 dev->name, firmware);
75
76 /* Read current plug data */
77 err = hermes_read_pda(hw, pda, fw->pda_addr, fw->pda_size, 0);
78 printk(KERN_DEBUG "%s: Read PDA returned %d\n", dev->name, err);
79 if (err)
80 goto free;
81
82 if (!priv->cached_fw) {
83 err = request_firmware(&fw_entry, firmware, priv->dev);
84
85 if (err) {
86 printk(KERN_ERR "%s: Cannot find firmware %s\n",
87 dev->name, firmware);
88 err = -ENOENT;
89 goto free;
90 }
91 } else
92 fw_entry = priv->cached_fw;
93
94 hdr = (const struct orinoco_fw_header *) fw_entry->data;
95
96 /* Enable aux port to allow programming */
97 err = hermesi_program_init(hw, le32_to_cpu(hdr->entry_point));
98 printk(KERN_DEBUG "%s: Program init returned %d\n", dev->name, err);
99 if (err != 0)
100 goto abort;
101
102 /* Program data */
103 first_block = (fw_entry->data +
104 le16_to_cpu(hdr->headersize) +
105 le32_to_cpu(hdr->block_offset));
106 end = fw_entry->data + fw_entry->size;
107
108 err = hermes_program(hw, first_block, end);
109 printk(KERN_DEBUG "%s: Program returned %d\n", dev->name, err);
110 if (err != 0)
111 goto abort;
112
113 /* Update production data */
114 first_block = (fw_entry->data +
115 le16_to_cpu(hdr->headersize) +
116 le32_to_cpu(hdr->pdr_offset));
117
118 err = hermes_apply_pda_with_defaults(hw, first_block, pda);
119 printk(KERN_DEBUG "%s: Apply PDA returned %d\n", dev->name, err);
120 if (err)
121 goto abort;
122
123 /* Tell card we've finished */
124 err = hermesi_program_end(hw);
125 printk(KERN_DEBUG "%s: Program end returned %d\n", dev->name, err);
126 if (err != 0)
127 goto abort;
128
129 /* Check if we're running */
130 printk(KERN_DEBUG "%s: hermes_present returned %d\n",
131 dev->name, hermes_present(hw));
132
133abort:
134 /* If we requested the firmware, release it. */
135 if (!priv->cached_fw)
136 release_firmware(fw_entry);
137
138free:
139 kfree(pda);
140 return err;
141}
142
143/*
144 * Process a firmware image - stop the card, load the firmware, reset
145 * the card and make sure it responds. For the secondary firmware take
146 * care of the PDA - read it and then write it on top of the firmware.
147 */
148static int
149symbol_dl_image(struct orinoco_private *priv, const struct fw_info *fw,
150 const unsigned char *image, const unsigned char *end,
151 int secondary)
152{
153 hermes_t *hw = &priv->hw;
154 int ret = 0;
155 const unsigned char *ptr;
156 const unsigned char *first_block;
157
158 /* Plug Data Area (PDA) */
159 __le16 *pda = NULL;
160
161 /* Binary block begins after the 0x1A marker */
162 ptr = image;
163 while (*ptr++ != TEXT_END);
164 first_block = ptr;
165
166 /* Read the PDA from EEPROM */
167 if (secondary) {
168 pda = kzalloc(fw->pda_size, GFP_KERNEL);
169 if (!pda)
170 return -ENOMEM;
171
172 ret = hermes_read_pda(hw, pda, fw->pda_addr, fw->pda_size, 1);
173 if (ret)
174 goto free;
175 }
176
177 /* Stop the firmware, so that it can be safely rewritten */
178 if (priv->stop_fw) {
179 ret = priv->stop_fw(priv, 1);
180 if (ret)
181 goto free;
182 }
183
184 /* Program the adapter with new firmware */
185 ret = hermes_program(hw, first_block, end);
186 if (ret)
187 goto free;
188
189 /* Write the PDA to the adapter */
190 if (secondary) {
191 size_t len = hermes_blocks_length(first_block);
192 ptr = first_block + len;
193 ret = hermes_apply_pda(hw, ptr, pda);
194 kfree(pda);
195 if (ret)
196 return ret;
197 }
198
199 /* Run the firmware */
200 if (priv->stop_fw) {
201 ret = priv->stop_fw(priv, 0);
202 if (ret)
203 return ret;
204 }
205
206 /* Reset hermes chip and make sure it responds */
207 ret = hermes_init(hw);
208
209 /* hermes_reset() should return 0 with the secondary firmware */
210 if (secondary && ret != 0)
211 return -ENODEV;
212
213 /* And this should work with any firmware */
214 if (!hermes_present(hw))
215 return -ENODEV;
216
217 return 0;
218
219free:
220 kfree(pda);
221 return ret;
222}
223
224
225/*
226 * Download the firmware into the card, this also does a PCMCIA soft
227 * reset on the card, to make sure it's in a sane state.
228 */
229static int
230symbol_dl_firmware(struct orinoco_private *priv,
231 const struct fw_info *fw)
232{
233 struct net_device *dev = priv->ndev;
234 int ret;
235 const struct firmware *fw_entry;
236
237 if (!priv->cached_pri_fw) {
238 if (request_firmware(&fw_entry, fw->pri_fw, priv->dev) != 0) {
239 printk(KERN_ERR "%s: Cannot find firmware: %s\n",
240 dev->name, fw->pri_fw);
241 return -ENOENT;
242 }
243 } else
244 fw_entry = priv->cached_pri_fw;
245
246 /* Load primary firmware */
247 ret = symbol_dl_image(priv, fw, fw_entry->data,
248 fw_entry->data + fw_entry->size, 0);
249
250 if (!priv->cached_pri_fw)
251 release_firmware(fw_entry);
252 if (ret) {
253 printk(KERN_ERR "%s: Primary firmware download failed\n",
254 dev->name);
255 return ret;
256 }
257
258 if (!priv->cached_fw) {
259 if (request_firmware(&fw_entry, fw->sta_fw, priv->dev) != 0) {
260 printk(KERN_ERR "%s: Cannot find firmware: %s\n",
261 dev->name, fw->sta_fw);
262 return -ENOENT;
263 }
264 } else
265 fw_entry = priv->cached_fw;
266
267 /* Load secondary firmware */
268 ret = symbol_dl_image(priv, fw, fw_entry->data,
269 fw_entry->data + fw_entry->size, 1);
270 if (!priv->cached_fw)
271 release_firmware(fw_entry);
272 if (ret) {
273 printk(KERN_ERR "%s: Secondary firmware download failed\n",
274 dev->name);
275 }
276
277 return ret;
278}
279
280int orinoco_download(struct orinoco_private *priv)
281{
282 int err = 0;
283 /* Reload firmware */
284 switch (priv->firmware_type) {
285 case FIRMWARE_TYPE_AGERE:
286 /* case FIRMWARE_TYPE_INTERSIL: */
287 err = orinoco_dl_firmware(priv,
288 &orinoco_fw[priv->firmware_type], 0);
289 break;
290
291 case FIRMWARE_TYPE_SYMBOL:
292 err = symbol_dl_firmware(priv,
293 &orinoco_fw[priv->firmware_type]);
294 break;
295 case FIRMWARE_TYPE_INTERSIL:
296 break;
297 }
298 /* TODO: if we fail we probably need to reinitialise
299 * the driver */
300
301 return err;
302}
303
304void orinoco_cache_fw(struct orinoco_private *priv, int ap)
305{
306#if defined(CONFIG_HERMES_CACHE_FW_ON_INIT) || defined(CONFIG_PM_SLEEP)
307 const struct firmware *fw_entry = NULL;
308 const char *pri_fw;
309 const char *fw;
310
311 pri_fw = orinoco_fw[priv->firmware_type].pri_fw;
312 if (ap)
313 fw = orinoco_fw[priv->firmware_type].ap_fw;
314 else
315 fw = orinoco_fw[priv->firmware_type].sta_fw;
316
317 if (pri_fw) {
318 if (request_firmware(&fw_entry, pri_fw, priv->dev) == 0)
319 priv->cached_pri_fw = fw_entry;
320 }
321
322 if (fw) {
323 if (request_firmware(&fw_entry, fw, priv->dev) == 0)
324 priv->cached_fw = fw_entry;
325 }
326#endif
327}
328
329void orinoco_uncache_fw(struct orinoco_private *priv)
330{
331#if defined(CONFIG_HERMES_CACHE_FW_ON_INIT) || defined(CONFIG_PM_SLEEP)
332 if (priv->cached_pri_fw)
333 release_firmware(priv->cached_pri_fw);
334 if (priv->cached_fw)
335 release_firmware(priv->cached_fw);
336
337 priv->cached_pri_fw = NULL;
338 priv->cached_fw = NULL;
339#endif
340}
diff --git a/drivers/net/wireless/orinoco/fw.h b/drivers/net/wireless/orinoco/fw.h
new file mode 100644
index 000000000000..2290f0845d59
--- /dev/null
+++ b/drivers/net/wireless/orinoco/fw.h
@@ -0,0 +1,16 @@
1/* Firmware file reading and download helpers
2 *
3 * See copyright notice in main.c
4 */
5#ifndef _ORINOCO_FW_H_
6#define _ORINOCO_FW_H_
7
8/* Forward declations */
9struct orinoco_private;
10
11int orinoco_download(struct orinoco_private *priv);
12
13void orinoco_cache_fw(struct orinoco_private *priv, int ap);
14void orinoco_uncache_fw(struct orinoco_private *priv);
15
16#endif /* _ORINOCO_FW_H_ */
diff --git a/drivers/net/wireless/orinoco/hermes.c b/drivers/net/wireless/orinoco/hermes.c
index f48358fed9f7..f2c918c2572d 100644
--- a/drivers/net/wireless/orinoco/hermes.c
+++ b/drivers/net/wireless/orinoco/hermes.c
@@ -45,12 +45,6 @@
45 45
46#include "hermes.h" 46#include "hermes.h"
47 47
48MODULE_DESCRIPTION("Low-level driver helper for Lucent Hermes chipset"
49 " and Prism II HFA384x wireless MAC controller");
50MODULE_AUTHOR("Pavel Roskin <proski@gnu.org>"
51 " & David Gibson <hermes@gibson.dropbear.id.au>");
52MODULE_LICENSE("Dual MPL/GPL");
53
54/* These are maximum timeouts. Most often, card wil react much faster */ 48/* These are maximum timeouts. Most often, card wil react much faster */
55#define CMD_BUSY_TIMEOUT (100) /* In iterations of ~1us */ 49#define CMD_BUSY_TIMEOUT (100) /* In iterations of ~1us */
56#define CMD_INIT_TIMEOUT (50000) /* in iterations of ~10us */ 50#define CMD_INIT_TIMEOUT (50000) /* in iterations of ~10us */
@@ -540,15 +534,3 @@ int hermes_write_ltv(hermes_t *hw, int bap, u16 rid,
540 return err; 534 return err;
541} 535}
542EXPORT_SYMBOL(hermes_write_ltv); 536EXPORT_SYMBOL(hermes_write_ltv);
543
544static int __init init_hermes(void)
545{
546 return 0;
547}
548
549static void __exit exit_hermes(void)
550{
551}
552
553module_init(init_hermes);
554module_exit(exit_hermes);
diff --git a/drivers/net/wireless/orinoco/hermes_dld.c b/drivers/net/wireless/orinoco/hermes_dld.c
index 45aed14bf110..5260ceb5cfec 100644
--- a/drivers/net/wireless/orinoco/hermes_dld.c
+++ b/drivers/net/wireless/orinoco/hermes_dld.c
@@ -1,13 +1,7 @@
1/* 1/*
2 * Hermes download helper driver. 2 * Hermes download helper.
3 * 3 *
4 * This could be entirely merged into hermes.c. 4 * This helper:
5 *
6 * I'm keeping it separate to minimise the amount of merging between
7 * kernel upgrades. It also means the memory overhead for drivers that
8 * don't need firmware download low.
9 *
10 * This driver:
11 * - is capable of writing to the volatile area of the hermes device 5 * - is capable of writing to the volatile area of the hermes device
12 * - is currently not capable of writing to non-volatile areas 6 * - is currently not capable of writing to non-volatile areas
13 * - provide helpers to identify and update plugin data 7 * - provide helpers to identify and update plugin data
@@ -50,10 +44,6 @@
50#include "hermes.h" 44#include "hermes.h"
51#include "hermes_dld.h" 45#include "hermes_dld.h"
52 46
53MODULE_DESCRIPTION("Download helper for Lucent Hermes chipset");
54MODULE_AUTHOR("David Kilroy <kilroyd@gmail.com>");
55MODULE_LICENSE("Dual MPL/GPL");
56
57#define PFX "hermes_dld: " 47#define PFX "hermes_dld: "
58 48
59/* 49/*
@@ -347,7 +337,6 @@ int hermes_read_pda(hermes_t *hw,
347 337
348 return 0; 338 return 0;
349} 339}
350EXPORT_SYMBOL(hermes_read_pda);
351 340
352/* Parse PDA and write the records into the adapter 341/* Parse PDA and write the records into the adapter
353 * 342 *
@@ -376,7 +365,6 @@ int hermes_apply_pda(hermes_t *hw,
376 } 365 }
377 return 0; 366 return 0;
378} 367}
379EXPORT_SYMBOL(hermes_apply_pda);
380 368
381/* Identify the total number of bytes in all blocks 369/* Identify the total number of bytes in all blocks
382 * including the header data. 370 * including the header data.
@@ -398,7 +386,6 @@ hermes_blocks_length(const char *first_block)
398 386
399 return total_len; 387 return total_len;
400} 388}
401EXPORT_SYMBOL(hermes_blocks_length);
402 389
403/*** Hermes programming ***/ 390/*** Hermes programming ***/
404 391
@@ -452,7 +439,6 @@ int hermesi_program_init(hermes_t *hw, u32 offset)
452 439
453 return err; 440 return err;
454} 441}
455EXPORT_SYMBOL(hermesi_program_init);
456 442
457/* Done programming data (Hermes I) 443/* Done programming data (Hermes I)
458 * 444 *
@@ -488,7 +474,6 @@ int hermesi_program_end(hermes_t *hw)
488 474
489 return rc ? rc : err; 475 return rc ? rc : err;
490} 476}
491EXPORT_SYMBOL(hermesi_program_end);
492 477
493/* Program the data blocks */ 478/* Program the data blocks */
494int hermes_program(hermes_t *hw, const char *first_block, const char *end) 479int hermes_program(hermes_t *hw, const char *first_block, const char *end)
@@ -550,19 +535,6 @@ int hermes_program(hermes_t *hw, const char *first_block, const char *end)
550 } 535 }
551 return 0; 536 return 0;
552} 537}
553EXPORT_SYMBOL(hermes_program);
554
555static int __init init_hermes_dld(void)
556{
557 return 0;
558}
559
560static void __exit exit_hermes_dld(void)
561{
562}
563
564module_init(init_hermes_dld);
565module_exit(exit_hermes_dld);
566 538
567/*** Default plugging data for Hermes I ***/ 539/*** Default plugging data for Hermes I ***/
568/* Values from wl_lkm_718/hcf/dhf.c */ 540/* Values from wl_lkm_718/hcf/dhf.c */
@@ -727,4 +699,3 @@ int hermes_apply_pda_with_defaults(hermes_t *hw,
727 } 699 }
728 return 0; 700 return 0;
729} 701}
730EXPORT_SYMBOL(hermes_apply_pda_with_defaults);
diff --git a/drivers/net/wireless/orinoco/hw.c b/drivers/net/wireless/orinoco/hw.c
new file mode 100644
index 000000000000..081428d9409e
--- /dev/null
+++ b/drivers/net/wireless/orinoco/hw.c
@@ -0,0 +1,586 @@
1/* Encapsulate basic setting changes and retrieval on Hermes hardware
2 *
3 * See copyright notice in main.c
4 */
5#include <linux/kernel.h>
6#include <linux/if_arp.h>
7#include <linux/ieee80211.h>
8#include <linux/wireless.h>
9
10#include "hermes.h"
11#include "hermes_rid.h"
12#include "orinoco.h"
13
14#include "hw.h"
15
16/********************************************************************/
17/* Data tables */
18/********************************************************************/
19
20/* This tables gives the actual meanings of the bitrate IDs returned
21 * by the firmware. */
22static const struct {
23 int bitrate; /* in 100s of kilobits */
24 int automatic;
25 u16 agere_txratectrl;
26 u16 intersil_txratectrl;
27} bitrate_table[] = {
28 {110, 1, 3, 15}, /* Entry 0 is the default */
29 {10, 0, 1, 1},
30 {10, 1, 1, 1},
31 {20, 0, 2, 2},
32 {20, 1, 6, 3},
33 {55, 0, 4, 4},
34 {55, 1, 7, 7},
35 {110, 0, 5, 8},
36};
37#define BITRATE_TABLE_SIZE ARRAY_SIZE(bitrate_table)
38
39int orinoco_get_bitratemode(int bitrate, int automatic)
40{
41 int ratemode = -1;
42 int i;
43
44 if ((bitrate != 10) && (bitrate != 20) &&
45 (bitrate != 55) && (bitrate != 110))
46 return ratemode;
47
48 for (i = 0; i < BITRATE_TABLE_SIZE; i++) {
49 if ((bitrate_table[i].bitrate == bitrate) &&
50 (bitrate_table[i].automatic == automatic)) {
51 ratemode = i;
52 break;
53 }
54 }
55 return ratemode;
56}
57
58void orinoco_get_ratemode_cfg(int ratemode, int *bitrate, int *automatic)
59{
60 BUG_ON((ratemode < 0) || (ratemode >= BITRATE_TABLE_SIZE));
61
62 *bitrate = bitrate_table[ratemode].bitrate * 100000;
63 *automatic = bitrate_table[ratemode].automatic;
64}
65
66/* Get tsc from the firmware */
67int orinoco_hw_get_tkip_iv(struct orinoco_private *priv, int key, u8 *tsc)
68{
69 hermes_t *hw = &priv->hw;
70 int err = 0;
71 u8 tsc_arr[4][IW_ENCODE_SEQ_MAX_SIZE];
72
73 if ((key < 0) || (key > 4))
74 return -EINVAL;
75
76 err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CURRENT_TKIP_IV,
77 sizeof(tsc_arr), NULL, &tsc_arr);
78 if (!err)
79 memcpy(tsc, &tsc_arr[key][0], sizeof(tsc_arr[0]));
80
81 return err;
82}
83
84int __orinoco_hw_set_bitrate(struct orinoco_private *priv)
85{
86 hermes_t *hw = &priv->hw;
87 int ratemode = priv->bitratemode;
88 int err = 0;
89
90 if (ratemode >= BITRATE_TABLE_SIZE) {
91 printk(KERN_ERR "%s: BUG: Invalid bitrate mode %d\n",
92 priv->ndev->name, ratemode);
93 return -EINVAL;
94 }
95
96 switch (priv->firmware_type) {
97 case FIRMWARE_TYPE_AGERE:
98 err = hermes_write_wordrec(hw, USER_BAP,
99 HERMES_RID_CNFTXRATECONTROL,
100 bitrate_table[ratemode].agere_txratectrl);
101 break;
102 case FIRMWARE_TYPE_INTERSIL:
103 case FIRMWARE_TYPE_SYMBOL:
104 err = hermes_write_wordrec(hw, USER_BAP,
105 HERMES_RID_CNFTXRATECONTROL,
106 bitrate_table[ratemode].intersil_txratectrl);
107 break;
108 default:
109 BUG();
110 }
111
112 return err;
113}
114
115int orinoco_hw_get_act_bitrate(struct orinoco_private *priv, int *bitrate)
116{
117 hermes_t *hw = &priv->hw;
118 int i;
119 int err = 0;
120 u16 val;
121
122 err = hermes_read_wordrec(hw, USER_BAP,
123 HERMES_RID_CURRENTTXRATE, &val);
124 if (err)
125 return err;
126
127 switch (priv->firmware_type) {
128 case FIRMWARE_TYPE_AGERE: /* Lucent style rate */
129 /* Note : in Lucent firmware, the return value of
130 * HERMES_RID_CURRENTTXRATE is the bitrate in Mb/s,
131 * and therefore is totally different from the
132 * encoding of HERMES_RID_CNFTXRATECONTROL.
133 * Don't forget that 6Mb/s is really 5.5Mb/s */
134 if (val == 6)
135 *bitrate = 5500000;
136 else
137 *bitrate = val * 1000000;
138 break;
139 case FIRMWARE_TYPE_INTERSIL: /* Intersil style rate */
140 case FIRMWARE_TYPE_SYMBOL: /* Symbol style rate */
141 for (i = 0; i < BITRATE_TABLE_SIZE; i++)
142 if (bitrate_table[i].intersil_txratectrl == val)
143 break;
144
145 if (i >= BITRATE_TABLE_SIZE)
146 printk(KERN_INFO "%s: Unable to determine current bitrate (0x%04hx)\n",
147 priv->ndev->name, val);
148
149 *bitrate = bitrate_table[i].bitrate * 100000;
150 break;
151 default:
152 BUG();
153 }
154
155 return err;
156}
157
158/* Set fixed AP address */
159int __orinoco_hw_set_wap(struct orinoco_private *priv)
160{
161 int roaming_flag;
162 int err = 0;
163 hermes_t *hw = &priv->hw;
164
165 switch (priv->firmware_type) {
166 case FIRMWARE_TYPE_AGERE:
167 /* not supported */
168 break;
169 case FIRMWARE_TYPE_INTERSIL:
170 if (priv->bssid_fixed)
171 roaming_flag = 2;
172 else
173 roaming_flag = 1;
174
175 err = hermes_write_wordrec(hw, USER_BAP,
176 HERMES_RID_CNFROAMINGMODE,
177 roaming_flag);
178 break;
179 case FIRMWARE_TYPE_SYMBOL:
180 err = HERMES_WRITE_RECORD(hw, USER_BAP,
181 HERMES_RID_CNFMANDATORYBSSID_SYMBOL,
182 &priv->desired_bssid);
183 break;
184 }
185 return err;
186}
187
188/* Change the WEP keys and/or the current keys. Can be called
189 * either from __orinoco_hw_setup_enc() or directly from
190 * orinoco_ioctl_setiwencode(). In the later case the association
191 * with the AP is not broken (if the firmware can handle it),
192 * which is needed for 802.1x implementations. */
193int __orinoco_hw_setup_wepkeys(struct orinoco_private *priv)
194{
195 hermes_t *hw = &priv->hw;
196 int err = 0;
197
198 switch (priv->firmware_type) {
199 case FIRMWARE_TYPE_AGERE:
200 err = HERMES_WRITE_RECORD(hw, USER_BAP,
201 HERMES_RID_CNFWEPKEYS_AGERE,
202 &priv->keys);
203 if (err)
204 return err;
205 err = hermes_write_wordrec(hw, USER_BAP,
206 HERMES_RID_CNFTXKEY_AGERE,
207 priv->tx_key);
208 if (err)
209 return err;
210 break;
211 case FIRMWARE_TYPE_INTERSIL:
212 case FIRMWARE_TYPE_SYMBOL:
213 {
214 int keylen;
215 int i;
216
217 /* Force uniform key length to work around
218 * firmware bugs */
219 keylen = le16_to_cpu(priv->keys[priv->tx_key].len);
220
221 if (keylen > LARGE_KEY_SIZE) {
222 printk(KERN_ERR "%s: BUG: Key %d has oversize length %d.\n",
223 priv->ndev->name, priv->tx_key, keylen);
224 return -E2BIG;
225 }
226
227 /* Write all 4 keys */
228 for (i = 0; i < ORINOCO_MAX_KEYS; i++) {
229 err = hermes_write_ltv(hw, USER_BAP,
230 HERMES_RID_CNFDEFAULTKEY0 + i,
231 HERMES_BYTES_TO_RECLEN(keylen),
232 priv->keys[i].data);
233 if (err)
234 return err;
235 }
236
237 /* Write the index of the key used in transmission */
238 err = hermes_write_wordrec(hw, USER_BAP,
239 HERMES_RID_CNFWEPDEFAULTKEYID,
240 priv->tx_key);
241 if (err)
242 return err;
243 }
244 break;
245 }
246
247 return 0;
248}
249
250int __orinoco_hw_setup_enc(struct orinoco_private *priv)
251{
252 hermes_t *hw = &priv->hw;
253 int err = 0;
254 int master_wep_flag;
255 int auth_flag;
256 int enc_flag;
257
258 /* Setup WEP keys for WEP and WPA */
259 if (priv->encode_alg)
260 __orinoco_hw_setup_wepkeys(priv);
261
262 if (priv->wep_restrict)
263 auth_flag = HERMES_AUTH_SHARED_KEY;
264 else
265 auth_flag = HERMES_AUTH_OPEN;
266
267 if (priv->wpa_enabled)
268 enc_flag = 2;
269 else if (priv->encode_alg == IW_ENCODE_ALG_WEP)
270 enc_flag = 1;
271 else
272 enc_flag = 0;
273
274 switch (priv->firmware_type) {
275 case FIRMWARE_TYPE_AGERE: /* Agere style WEP */
276 if (priv->encode_alg == IW_ENCODE_ALG_WEP) {
277 /* Enable the shared-key authentication. */
278 err = hermes_write_wordrec(hw, USER_BAP,
279 HERMES_RID_CNFAUTHENTICATION_AGERE,
280 auth_flag);
281 }
282 err = hermes_write_wordrec(hw, USER_BAP,
283 HERMES_RID_CNFWEPENABLED_AGERE,
284 enc_flag);
285 if (err)
286 return err;
287
288 if (priv->has_wpa) {
289 /* Set WPA key management */
290 err = hermes_write_wordrec(hw, USER_BAP,
291 HERMES_RID_CNFSETWPAAUTHMGMTSUITE_AGERE,
292 priv->key_mgmt);
293 if (err)
294 return err;
295 }
296
297 break;
298
299 case FIRMWARE_TYPE_INTERSIL: /* Intersil style WEP */
300 case FIRMWARE_TYPE_SYMBOL: /* Symbol style WEP */
301 if (priv->encode_alg == IW_ENCODE_ALG_WEP) {
302 if (priv->wep_restrict ||
303 (priv->firmware_type == FIRMWARE_TYPE_SYMBOL))
304 master_wep_flag = HERMES_WEP_PRIVACY_INVOKED |
305 HERMES_WEP_EXCL_UNENCRYPTED;
306 else
307 master_wep_flag = HERMES_WEP_PRIVACY_INVOKED;
308
309 err = hermes_write_wordrec(hw, USER_BAP,
310 HERMES_RID_CNFAUTHENTICATION,
311 auth_flag);
312 if (err)
313 return err;
314 } else
315 master_wep_flag = 0;
316
317 if (priv->iw_mode == IW_MODE_MONITOR)
318 master_wep_flag |= HERMES_WEP_HOST_DECRYPT;
319
320 /* Master WEP setting : on/off */
321 err = hermes_write_wordrec(hw, USER_BAP,
322 HERMES_RID_CNFWEPFLAGS_INTERSIL,
323 master_wep_flag);
324 if (err)
325 return err;
326
327 break;
328 }
329
330 return 0;
331}
332
333/* key must be 32 bytes, including the tx and rx MIC keys.
334 * rsc must be 8 bytes
335 * tsc must be 8 bytes or NULL
336 */
337int __orinoco_hw_set_tkip_key(hermes_t *hw, int key_idx, int set_tx,
338 u8 *key, u8 *rsc, u8 *tsc)
339{
340 struct {
341 __le16 idx;
342 u8 rsc[IW_ENCODE_SEQ_MAX_SIZE];
343 u8 key[TKIP_KEYLEN];
344 u8 tx_mic[MIC_KEYLEN];
345 u8 rx_mic[MIC_KEYLEN];
346 u8 tsc[IW_ENCODE_SEQ_MAX_SIZE];
347 } __attribute__ ((packed)) buf;
348 int ret;
349 int err;
350 int k;
351 u16 xmitting;
352
353 key_idx &= 0x3;
354
355 if (set_tx)
356 key_idx |= 0x8000;
357
358 buf.idx = cpu_to_le16(key_idx);
359 memcpy(buf.key, key,
360 sizeof(buf.key) + sizeof(buf.tx_mic) + sizeof(buf.rx_mic));
361
362 if (rsc == NULL)
363 memset(buf.rsc, 0, sizeof(buf.rsc));
364 else
365 memcpy(buf.rsc, rsc, sizeof(buf.rsc));
366
367 if (tsc == NULL) {
368 memset(buf.tsc, 0, sizeof(buf.tsc));
369 buf.tsc[4] = 0x10;
370 } else {
371 memcpy(buf.tsc, tsc, sizeof(buf.tsc));
372 }
373
374 /* Wait upto 100ms for tx queue to empty */
375 k = 100;
376 do {
377 k--;
378 udelay(1000);
379 ret = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_TXQUEUEEMPTY,
380 &xmitting);
381 if (ret)
382 break;
383 } while ((k > 0) && xmitting);
384
385 if (k == 0)
386 ret = -ETIMEDOUT;
387
388 err = HERMES_WRITE_RECORD(hw, USER_BAP,
389 HERMES_RID_CNFADDDEFAULTTKIPKEY_AGERE,
390 &buf);
391
392 return ret ? ret : err;
393}
394
395int orinoco_clear_tkip_key(struct orinoco_private *priv, int key_idx)
396{
397 hermes_t *hw = &priv->hw;
398 int err;
399
400 memset(&priv->tkip_key[key_idx], 0, sizeof(priv->tkip_key[key_idx]));
401 err = hermes_write_wordrec(hw, USER_BAP,
402 HERMES_RID_CNFREMDEFAULTTKIPKEY_AGERE,
403 key_idx);
404 if (err)
405 printk(KERN_WARNING "%s: Error %d clearing TKIP key %d\n",
406 priv->ndev->name, err, key_idx);
407 return err;
408}
409
410int __orinoco_hw_set_multicast_list(struct orinoco_private *priv,
411 struct dev_addr_list *mc_list,
412 int mc_count, int promisc)
413{
414 hermes_t *hw = &priv->hw;
415 int err = 0;
416
417 if (promisc != priv->promiscuous) {
418 err = hermes_write_wordrec(hw, USER_BAP,
419 HERMES_RID_CNFPROMISCUOUSMODE,
420 promisc);
421 if (err) {
422 printk(KERN_ERR "%s: Error %d setting PROMISCUOUSMODE to 1.\n",
423 priv->ndev->name, err);
424 } else
425 priv->promiscuous = promisc;
426 }
427
428 /* If we're not in promiscuous mode, then we need to set the
429 * group address if either we want to multicast, or if we were
430 * multicasting and want to stop */
431 if (!promisc && (mc_count || priv->mc_count)) {
432 struct dev_mc_list *p = mc_list;
433 struct hermes_multicast mclist;
434 int i;
435
436 for (i = 0; i < mc_count; i++) {
437 /* paranoia: is list shorter than mc_count? */
438 BUG_ON(!p);
439 /* paranoia: bad address size in list? */
440 BUG_ON(p->dmi_addrlen != ETH_ALEN);
441
442 memcpy(mclist.addr[i], p->dmi_addr, ETH_ALEN);
443 p = p->next;
444 }
445
446 if (p)
447 printk(KERN_WARNING "%s: Multicast list is "
448 "longer than mc_count\n", priv->ndev->name);
449
450 err = hermes_write_ltv(hw, USER_BAP,
451 HERMES_RID_CNFGROUPADDRESSES,
452 HERMES_BYTES_TO_RECLEN(mc_count * ETH_ALEN),
453 &mclist);
454 if (err)
455 printk(KERN_ERR "%s: Error %d setting multicast list.\n",
456 priv->ndev->name, err);
457 else
458 priv->mc_count = mc_count;
459 }
460 return err;
461}
462
463/* Return : < 0 -> error code ; >= 0 -> length */
464int orinoco_hw_get_essid(struct orinoco_private *priv, int *active,
465 char buf[IW_ESSID_MAX_SIZE+1])
466{
467 hermes_t *hw = &priv->hw;
468 int err = 0;
469 struct hermes_idstring essidbuf;
470 char *p = (char *)(&essidbuf.val);
471 int len;
472 unsigned long flags;
473
474 if (orinoco_lock(priv, &flags) != 0)
475 return -EBUSY;
476
477 if (strlen(priv->desired_essid) > 0) {
478 /* We read the desired SSID from the hardware rather
479 than from priv->desired_essid, just in case the
480 firmware is allowed to change it on us. I'm not
481 sure about this */
482 /* My guess is that the OWNSSID should always be whatever
483 * we set to the card, whereas CURRENT_SSID is the one that
484 * may change... - Jean II */
485 u16 rid;
486
487 *active = 1;
488
489 rid = (priv->port_type == 3) ? HERMES_RID_CNFOWNSSID :
490 HERMES_RID_CNFDESIREDSSID;
491
492 err = hermes_read_ltv(hw, USER_BAP, rid, sizeof(essidbuf),
493 NULL, &essidbuf);
494 if (err)
495 goto fail_unlock;
496 } else {
497 *active = 0;
498
499 err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CURRENTSSID,
500 sizeof(essidbuf), NULL, &essidbuf);
501 if (err)
502 goto fail_unlock;
503 }
504
505 len = le16_to_cpu(essidbuf.len);
506 BUG_ON(len > IW_ESSID_MAX_SIZE);
507
508 memset(buf, 0, IW_ESSID_MAX_SIZE);
509 memcpy(buf, p, len);
510 err = len;
511
512 fail_unlock:
513 orinoco_unlock(priv, &flags);
514
515 return err;
516}
517
518int orinoco_hw_get_freq(struct orinoco_private *priv)
519{
520 hermes_t *hw = &priv->hw;
521 int err = 0;
522 u16 channel;
523 int freq = 0;
524 unsigned long flags;
525
526 if (orinoco_lock(priv, &flags) != 0)
527 return -EBUSY;
528
529 err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CURRENTCHANNEL,
530 &channel);
531 if (err)
532 goto out;
533
534 /* Intersil firmware 1.3.5 returns 0 when the interface is down */
535 if (channel == 0) {
536 err = -EBUSY;
537 goto out;
538 }
539
540 if ((channel < 1) || (channel > NUM_CHANNELS)) {
541 printk(KERN_WARNING "%s: Channel out of range (%d)!\n",
542 priv->ndev->name, channel);
543 err = -EBUSY;
544 goto out;
545
546 }
547 freq = ieee80211_dsss_chan_to_freq(channel);
548
549 out:
550 orinoco_unlock(priv, &flags);
551
552 if (err > 0)
553 err = -EBUSY;
554 return err ? err : freq;
555}
556
557int orinoco_hw_get_bitratelist(struct orinoco_private *priv,
558 int *numrates, s32 *rates, int max)
559{
560 hermes_t *hw = &priv->hw;
561 struct hermes_idstring list;
562 unsigned char *p = (unsigned char *)&list.val;
563 int err = 0;
564 int num;
565 int i;
566 unsigned long flags;
567
568 if (orinoco_lock(priv, &flags) != 0)
569 return -EBUSY;
570
571 err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_SUPPORTEDDATARATES,
572 sizeof(list), NULL, &list);
573 orinoco_unlock(priv, &flags);
574
575 if (err)
576 return err;
577
578 num = le16_to_cpu(list.len);
579 *numrates = num;
580 num = min(num, max);
581
582 for (i = 0; i < num; i++)
583 rates[i] = (p[i] & 0x7f) * 500000; /* convert to bps */
584
585 return 0;
586}
diff --git a/drivers/net/wireless/orinoco/hw.h b/drivers/net/wireless/orinoco/hw.h
new file mode 100644
index 000000000000..dc3f23a9c1c7
--- /dev/null
+++ b/drivers/net/wireless/orinoco/hw.h
@@ -0,0 +1,47 @@
1/* Encapsulate basic setting changes on Hermes hardware
2 *
3 * See copyright notice in main.c
4 */
5#ifndef _ORINOCO_HW_H_
6#define _ORINOCO_HW_H_
7
8#include <linux/types.h>
9#include <linux/wireless.h>
10
11/* Hardware BAPs */
12#define USER_BAP 0
13#define IRQ_BAP 1
14
15/* WEP key sizes */
16#define SMALL_KEY_SIZE 5
17#define LARGE_KEY_SIZE 13
18
19/* Number of supported channels */
20#define NUM_CHANNELS 14
21
22/* Forward declarations */
23struct orinoco_private;
24struct dev_addr_list;
25
26int orinoco_get_bitratemode(int bitrate, int automatic);
27void orinoco_get_ratemode_cfg(int ratemode, int *bitrate, int *automatic);
28
29int orinoco_hw_get_tkip_iv(struct orinoco_private *priv, int key, u8 *tsc);
30int __orinoco_hw_set_bitrate(struct orinoco_private *priv);
31int orinoco_hw_get_act_bitrate(struct orinoco_private *priv, int *bitrate);
32int __orinoco_hw_set_wap(struct orinoco_private *priv);
33int __orinoco_hw_setup_wepkeys(struct orinoco_private *priv);
34int __orinoco_hw_setup_enc(struct orinoco_private *priv);
35int __orinoco_hw_set_tkip_key(hermes_t *hw, int key_idx, int set_tx,
36 u8 *key, u8 *rsc, u8 *tsc);
37int orinoco_clear_tkip_key(struct orinoco_private *priv, int key_idx);
38int __orinoco_hw_set_multicast_list(struct orinoco_private *priv,
39 struct dev_addr_list *mc_list,
40 int mc_count, int promisc);
41int orinoco_hw_get_essid(struct orinoco_private *priv, int *active,
42 char buf[IW_ESSID_MAX_SIZE+1]);
43int orinoco_hw_get_freq(struct orinoco_private *priv);
44int orinoco_hw_get_bitratelist(struct orinoco_private *priv,
45 int *numrates, s32 *rates, int max);
46
47#endif /* _ORINOCO_HW_H_ */
diff --git a/drivers/net/wireless/orinoco/main.c b/drivers/net/wireless/orinoco/main.c
new file mode 100644
index 000000000000..54dfc4540b82
--- /dev/null
+++ b/drivers/net/wireless/orinoco/main.c
@@ -0,0 +1,2654 @@
1/* main.c - (formerly known as dldwd_cs.c, orinoco_cs.c and orinoco.c)
2 *
3 * A driver for Hermes or Prism 2 chipset based PCMCIA wireless
4 * adaptors, with Lucent/Agere, Intersil or Symbol firmware.
5 *
6 * Current maintainers (as of 29 September 2003) are:
7 * Pavel Roskin <proski AT gnu.org>
8 * and David Gibson <hermes AT gibson.dropbear.id.au>
9 *
10 * (C) Copyright David Gibson, IBM Corporation 2001-2003.
11 * Copyright (C) 2000 David Gibson, Linuxcare Australia.
12 * With some help from :
13 * Copyright (C) 2001 Jean Tourrilhes, HP Labs
14 * Copyright (C) 2001 Benjamin Herrenschmidt
15 *
16 * Based on dummy_cs.c 1.27 2000/06/12 21:27:25
17 *
18 * Portions based on wvlan_cs.c 1.0.6, Copyright Andreas Neuhaus <andy
19 * AT fasta.fh-dortmund.de>
20 * http://www.stud.fh-dortmund.de/~andy/wvlan/
21 *
22 * The contents of this file are subject to the Mozilla Public License
23 * Version 1.1 (the "License"); you may not use this file except in
24 * compliance with the License. You may obtain a copy of the License
25 * at http://www.mozilla.org/MPL/
26 *
27 * Software distributed under the License is distributed on an "AS IS"
28 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
29 * the License for the specific language governing rights and
30 * limitations under the License.
31 *
32 * The initial developer of the original code is David A. Hinds
33 * <dahinds AT users.sourceforge.net>. Portions created by David
34 * A. Hinds are Copyright (C) 1999 David A. Hinds. All Rights
35 * Reserved.
36 *
37 * Alternatively, the contents of this file may be used under the
38 * terms of the GNU General Public License version 2 (the "GPL"), in
39 * which case the provisions of the GPL are applicable instead of the
40 * above. If you wish to allow the use of your version of this file
41 * only under the terms of the GPL and not to allow others to use your
42 * version of this file under the MPL, indicate your decision by
43 * deleting the provisions above and replace them with the notice and
44 * other provisions required by the GPL. If you do not delete the
45 * provisions above, a recipient may use your version of this file
46 * under either the MPL or the GPL. */
47
48/*
49 * TODO
50 * o Handle de-encapsulation within network layer, provide 802.11
51 * headers (patch from Thomas 'Dent' Mirlacher)
52 * o Fix possible races in SPY handling.
53 * o Disconnect wireless extensions from fundamental configuration.
54 * o (maybe) Software WEP support (patch from Stano Meduna).
55 * o (maybe) Use multiple Tx buffers - driver handling queue
56 * rather than firmware.
57 */
58
59/* Locking and synchronization:
60 *
61 * The basic principle is that everything is serialized through a
62 * single spinlock, priv->lock. The lock is used in user, bh and irq
63 * context, so when taken outside hardirq context it should always be
64 * taken with interrupts disabled. The lock protects both the
65 * hardware and the struct orinoco_private.
66 *
67 * Another flag, priv->hw_unavailable indicates that the hardware is
68 * unavailable for an extended period of time (e.g. suspended, or in
69 * the middle of a hard reset). This flag is protected by the
70 * spinlock. All code which touches the hardware should check the
71 * flag after taking the lock, and if it is set, give up on whatever
72 * they are doing and drop the lock again. The orinoco_lock()
73 * function handles this (it unlocks and returns -EBUSY if
74 * hw_unavailable is non-zero).
75 */
76
77#define DRIVER_NAME "orinoco"
78
79#include <linux/module.h>
80#include <linux/kernel.h>
81#include <linux/init.h>
82#include <linux/delay.h>
83#include <linux/netdevice.h>
84#include <linux/etherdevice.h>
85#include <linux/ethtool.h>
86#include <linux/suspend.h>
87#include <linux/if_arp.h>
88#include <linux/wireless.h>
89#include <linux/ieee80211.h>
90#include <net/iw_handler.h>
91
92#include "hermes_rid.h"
93#include "hermes_dld.h"
94#include "hw.h"
95#include "scan.h"
96#include "mic.h"
97#include "fw.h"
98#include "wext.h"
99#include "main.h"
100
101#include "orinoco.h"
102
103/********************************************************************/
104/* Module information */
105/********************************************************************/
106
107MODULE_AUTHOR("Pavel Roskin <proski@gnu.org> & "
108 "David Gibson <hermes@gibson.dropbear.id.au>");
109MODULE_DESCRIPTION("Driver for Lucent Orinoco, Prism II based "
110 "and similar wireless cards");
111MODULE_LICENSE("Dual MPL/GPL");
112
113/* Level of debugging. Used in the macros in orinoco.h */
114#ifdef ORINOCO_DEBUG
115int orinoco_debug = ORINOCO_DEBUG;
116EXPORT_SYMBOL(orinoco_debug);
117module_param(orinoco_debug, int, 0644);
118MODULE_PARM_DESC(orinoco_debug, "Debug level");
119#endif
120
121static int suppress_linkstatus; /* = 0 */
122module_param(suppress_linkstatus, bool, 0644);
123MODULE_PARM_DESC(suppress_linkstatus, "Don't log link status changes");
124
125static int ignore_disconnect; /* = 0 */
126module_param(ignore_disconnect, int, 0644);
127MODULE_PARM_DESC(ignore_disconnect,
128 "Don't report lost link to the network layer");
129
130int force_monitor; /* = 0 */
131module_param(force_monitor, int, 0644);
132MODULE_PARM_DESC(force_monitor, "Allow monitor mode for all firmware versions");
133
134/********************************************************************/
135/* Internal constants */
136/********************************************************************/
137
138/* 802.2 LLC/SNAP header used for Ethernet encapsulation over 802.11 */
139static const u8 encaps_hdr[] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00};
140#define ENCAPS_OVERHEAD (sizeof(encaps_hdr) + 2)
141
142#define ORINOCO_MIN_MTU 256
143#define ORINOCO_MAX_MTU (IEEE80211_MAX_DATA_LEN - ENCAPS_OVERHEAD)
144
145#define SYMBOL_MAX_VER_LEN (14)
146#define MAX_IRQLOOPS_PER_IRQ 10
147#define MAX_IRQLOOPS_PER_JIFFY (20000/HZ) /* Based on a guestimate of
148 * how many events the
149 * device could
150 * legitimately generate */
151#define TX_NICBUF_SIZE_BUG 1585 /* Bug in Symbol firmware */
152
153#define DUMMY_FID 0xFFFF
154
155/*#define MAX_MULTICAST(priv) (priv->firmware_type == FIRMWARE_TYPE_AGERE ? \
156 HERMES_MAX_MULTICAST : 0)*/
157#define MAX_MULTICAST(priv) (HERMES_MAX_MULTICAST)
158
159#define ORINOCO_INTEN (HERMES_EV_RX | HERMES_EV_ALLOC \
160 | HERMES_EV_TX | HERMES_EV_TXEXC \
161 | HERMES_EV_WTERR | HERMES_EV_INFO \
162 | HERMES_EV_INFDROP)
163
164static const struct ethtool_ops orinoco_ethtool_ops;
165
166/********************************************************************/
167/* Data types */
168/********************************************************************/
169
170/* Beginning of the Tx descriptor, used in TxExc handling */
171struct hermes_txexc_data {
172 struct hermes_tx_descriptor desc;
173 __le16 frame_ctl;
174 __le16 duration_id;
175 u8 addr1[ETH_ALEN];
176} __attribute__ ((packed));
177
178/* Rx frame header except compatibility 802.3 header */
179struct hermes_rx_descriptor {
180 /* Control */
181 __le16 status;
182 __le32 time;
183 u8 silence;
184 u8 signal;
185 u8 rate;
186 u8 rxflow;
187 __le32 reserved;
188
189 /* 802.11 header */
190 __le16 frame_ctl;
191 __le16 duration_id;
192 u8 addr1[ETH_ALEN];
193 u8 addr2[ETH_ALEN];
194 u8 addr3[ETH_ALEN];
195 __le16 seq_ctl;
196 u8 addr4[ETH_ALEN];
197
198 /* Data length */
199 __le16 data_len;
200} __attribute__ ((packed));
201
202struct orinoco_rx_data {
203 struct hermes_rx_descriptor *desc;
204 struct sk_buff *skb;
205 struct list_head list;
206};
207
208/********************************************************************/
209/* Function prototypes */
210/********************************************************************/
211
212static void __orinoco_set_multicast_list(struct net_device *dev);
213
214/********************************************************************/
215/* Internal helper functions */
216/********************************************************************/
217
218void set_port_type(struct orinoco_private *priv)
219{
220 switch (priv->iw_mode) {
221 case IW_MODE_INFRA:
222 priv->port_type = 1;
223 priv->createibss = 0;
224 break;
225 case IW_MODE_ADHOC:
226 if (priv->prefer_port3) {
227 priv->port_type = 3;
228 priv->createibss = 0;
229 } else {
230 priv->port_type = priv->ibss_port;
231 priv->createibss = 1;
232 }
233 break;
234 case IW_MODE_MONITOR:
235 priv->port_type = 3;
236 priv->createibss = 0;
237 break;
238 default:
239 printk(KERN_ERR "%s: Invalid priv->iw_mode in set_port_type()\n",
240 priv->ndev->name);
241 }
242}
243
244/********************************************************************/
245/* Device methods */
246/********************************************************************/
247
248static int orinoco_open(struct net_device *dev)
249{
250 struct orinoco_private *priv = netdev_priv(dev);
251 unsigned long flags;
252 int err;
253
254 if (orinoco_lock(priv, &flags) != 0)
255 return -EBUSY;
256
257 err = __orinoco_up(dev);
258
259 if (!err)
260 priv->open = 1;
261
262 orinoco_unlock(priv, &flags);
263
264 return err;
265}
266
267static int orinoco_stop(struct net_device *dev)
268{
269 struct orinoco_private *priv = netdev_priv(dev);
270 int err = 0;
271
272 /* We mustn't use orinoco_lock() here, because we need to be
273 able to close the interface even if hw_unavailable is set
274 (e.g. as we're released after a PC Card removal) */
275 spin_lock_irq(&priv->lock);
276
277 priv->open = 0;
278
279 err = __orinoco_down(dev);
280
281 spin_unlock_irq(&priv->lock);
282
283 return err;
284}
285
286static struct net_device_stats *orinoco_get_stats(struct net_device *dev)
287{
288 struct orinoco_private *priv = netdev_priv(dev);
289
290 return &priv->stats;
291}
292
293static void orinoco_set_multicast_list(struct net_device *dev)
294{
295 struct orinoco_private *priv = netdev_priv(dev);
296 unsigned long flags;
297
298 if (orinoco_lock(priv, &flags) != 0) {
299 printk(KERN_DEBUG "%s: orinoco_set_multicast_list() "
300 "called when hw_unavailable\n", dev->name);
301 return;
302 }
303
304 __orinoco_set_multicast_list(dev);
305 orinoco_unlock(priv, &flags);
306}
307
308static int orinoco_change_mtu(struct net_device *dev, int new_mtu)
309{
310 struct orinoco_private *priv = netdev_priv(dev);
311
312 if ((new_mtu < ORINOCO_MIN_MTU) || (new_mtu > ORINOCO_MAX_MTU))
313 return -EINVAL;
314
315 /* MTU + encapsulation + header length */
316 if ((new_mtu + ENCAPS_OVERHEAD + sizeof(struct ieee80211_hdr)) >
317 (priv->nicbuf_size - ETH_HLEN))
318 return -EINVAL;
319
320 dev->mtu = new_mtu;
321
322 return 0;
323}
324
325/********************************************************************/
326/* Tx path */
327/********************************************************************/
328
329static int orinoco_xmit(struct sk_buff *skb, struct net_device *dev)
330{
331 struct orinoco_private *priv = netdev_priv(dev);
332 struct net_device_stats *stats = &priv->stats;
333 hermes_t *hw = &priv->hw;
334 int err = 0;
335 u16 txfid = priv->txfid;
336 struct ethhdr *eh;
337 int tx_control;
338 unsigned long flags;
339
340 if (!netif_running(dev)) {
341 printk(KERN_ERR "%s: Tx on stopped device!\n",
342 dev->name);
343 return NETDEV_TX_BUSY;
344 }
345
346 if (netif_queue_stopped(dev)) {
347 printk(KERN_DEBUG "%s: Tx while transmitter busy!\n",
348 dev->name);
349 return NETDEV_TX_BUSY;
350 }
351
352 if (orinoco_lock(priv, &flags) != 0) {
353 printk(KERN_ERR "%s: orinoco_xmit() called while hw_unavailable\n",
354 dev->name);
355 return NETDEV_TX_BUSY;
356 }
357
358 if (!netif_carrier_ok(dev) || (priv->iw_mode == IW_MODE_MONITOR)) {
359 /* Oops, the firmware hasn't established a connection,
360 silently drop the packet (this seems to be the
361 safest approach). */
362 goto drop;
363 }
364
365 /* Check packet length */
366 if (skb->len < ETH_HLEN)
367 goto drop;
368
369 tx_control = HERMES_TXCTRL_TX_OK | HERMES_TXCTRL_TX_EX;
370
371 if (priv->encode_alg == IW_ENCODE_ALG_TKIP)
372 tx_control |= (priv->tx_key << HERMES_MIC_KEY_ID_SHIFT) |
373 HERMES_TXCTRL_MIC;
374
375 if (priv->has_alt_txcntl) {
376 /* WPA enabled firmwares have tx_cntl at the end of
377 * the 802.11 header. So write zeroed descriptor and
378 * 802.11 header at the same time
379 */
380 char desc[HERMES_802_3_OFFSET];
381 __le16 *txcntl = (__le16 *) &desc[HERMES_TXCNTL2_OFFSET];
382
383 memset(&desc, 0, sizeof(desc));
384
385 *txcntl = cpu_to_le16(tx_control);
386 err = hermes_bap_pwrite(hw, USER_BAP, &desc, sizeof(desc),
387 txfid, 0);
388 if (err) {
389 if (net_ratelimit())
390 printk(KERN_ERR "%s: Error %d writing Tx "
391 "descriptor to BAP\n", dev->name, err);
392 goto busy;
393 }
394 } else {
395 struct hermes_tx_descriptor desc;
396
397 memset(&desc, 0, sizeof(desc));
398
399 desc.tx_control = cpu_to_le16(tx_control);
400 err = hermes_bap_pwrite(hw, USER_BAP, &desc, sizeof(desc),
401 txfid, 0);
402 if (err) {
403 if (net_ratelimit())
404 printk(KERN_ERR "%s: Error %d writing Tx "
405 "descriptor to BAP\n", dev->name, err);
406 goto busy;
407 }
408
409 /* Clear the 802.11 header and data length fields - some
410 * firmwares (e.g. Lucent/Agere 8.xx) appear to get confused
411 * if this isn't done. */
412 hermes_clear_words(hw, HERMES_DATA0,
413 HERMES_802_3_OFFSET - HERMES_802_11_OFFSET);
414 }
415
416 eh = (struct ethhdr *)skb->data;
417
418 /* Encapsulate Ethernet-II frames */
419 if (ntohs(eh->h_proto) > ETH_DATA_LEN) { /* Ethernet-II frame */
420 struct header_struct {
421 struct ethhdr eth; /* 802.3 header */
422 u8 encap[6]; /* 802.2 header */
423 } __attribute__ ((packed)) hdr;
424
425 /* Strip destination and source from the data */
426 skb_pull(skb, 2 * ETH_ALEN);
427
428 /* And move them to a separate header */
429 memcpy(&hdr.eth, eh, 2 * ETH_ALEN);
430 hdr.eth.h_proto = htons(sizeof(encaps_hdr) + skb->len);
431 memcpy(hdr.encap, encaps_hdr, sizeof(encaps_hdr));
432
433 /* Insert the SNAP header */
434 if (skb_headroom(skb) < sizeof(hdr)) {
435 printk(KERN_ERR
436 "%s: Not enough headroom for 802.2 headers %d\n",
437 dev->name, skb_headroom(skb));
438 goto drop;
439 }
440 eh = (struct ethhdr *) skb_push(skb, sizeof(hdr));
441 memcpy(eh, &hdr, sizeof(hdr));
442 }
443
444 err = hermes_bap_pwrite(hw, USER_BAP, skb->data, skb->len,
445 txfid, HERMES_802_3_OFFSET);
446 if (err) {
447 printk(KERN_ERR "%s: Error %d writing packet to BAP\n",
448 dev->name, err);
449 goto busy;
450 }
451
452 /* Calculate Michael MIC */
453 if (priv->encode_alg == IW_ENCODE_ALG_TKIP) {
454 u8 mic_buf[MICHAEL_MIC_LEN + 1];
455 u8 *mic;
456 size_t offset;
457 size_t len;
458
459 if (skb->len % 2) {
460 /* MIC start is on an odd boundary */
461 mic_buf[0] = skb->data[skb->len - 1];
462 mic = &mic_buf[1];
463 offset = skb->len - 1;
464 len = MICHAEL_MIC_LEN + 1;
465 } else {
466 mic = &mic_buf[0];
467 offset = skb->len;
468 len = MICHAEL_MIC_LEN;
469 }
470
471 orinoco_mic(priv->tx_tfm_mic,
472 priv->tkip_key[priv->tx_key].tx_mic,
473 eh->h_dest, eh->h_source, 0 /* priority */,
474 skb->data + ETH_HLEN, skb->len - ETH_HLEN, mic);
475
476 /* Write the MIC */
477 err = hermes_bap_pwrite(hw, USER_BAP, &mic_buf[0], len,
478 txfid, HERMES_802_3_OFFSET + offset);
479 if (err) {
480 printk(KERN_ERR "%s: Error %d writing MIC to BAP\n",
481 dev->name, err);
482 goto busy;
483 }
484 }
485
486 /* Finally, we actually initiate the send */
487 netif_stop_queue(dev);
488
489 err = hermes_docmd_wait(hw, HERMES_CMD_TX | HERMES_CMD_RECL,
490 txfid, NULL);
491 if (err) {
492 netif_start_queue(dev);
493 if (net_ratelimit())
494 printk(KERN_ERR "%s: Error %d transmitting packet\n",
495 dev->name, err);
496 goto busy;
497 }
498
499 dev->trans_start = jiffies;
500 stats->tx_bytes += HERMES_802_3_OFFSET + skb->len;
501 goto ok;
502
503 drop:
504 stats->tx_errors++;
505 stats->tx_dropped++;
506
507 ok:
508 orinoco_unlock(priv, &flags);
509 dev_kfree_skb(skb);
510 return NETDEV_TX_OK;
511
512 busy:
513 if (err == -EIO)
514 schedule_work(&priv->reset_work);
515 orinoco_unlock(priv, &flags);
516 return NETDEV_TX_BUSY;
517}
518
519static void __orinoco_ev_alloc(struct net_device *dev, hermes_t *hw)
520{
521 struct orinoco_private *priv = netdev_priv(dev);
522 u16 fid = hermes_read_regn(hw, ALLOCFID);
523
524 if (fid != priv->txfid) {
525 if (fid != DUMMY_FID)
526 printk(KERN_WARNING "%s: Allocate event on unexpected fid (%04X)\n",
527 dev->name, fid);
528 return;
529 }
530
531 hermes_write_regn(hw, ALLOCFID, DUMMY_FID);
532}
533
534static void __orinoco_ev_tx(struct net_device *dev, hermes_t *hw)
535{
536 struct orinoco_private *priv = netdev_priv(dev);
537 struct net_device_stats *stats = &priv->stats;
538
539 stats->tx_packets++;
540
541 netif_wake_queue(dev);
542
543 hermes_write_regn(hw, TXCOMPLFID, DUMMY_FID);
544}
545
546static void __orinoco_ev_txexc(struct net_device *dev, hermes_t *hw)
547{
548 struct orinoco_private *priv = netdev_priv(dev);
549 struct net_device_stats *stats = &priv->stats;
550 u16 fid = hermes_read_regn(hw, TXCOMPLFID);
551 u16 status;
552 struct hermes_txexc_data hdr;
553 int err = 0;
554
555 if (fid == DUMMY_FID)
556 return; /* Nothing's really happened */
557
558 /* Read part of the frame header - we need status and addr1 */
559 err = hermes_bap_pread(hw, IRQ_BAP, &hdr,
560 sizeof(struct hermes_txexc_data),
561 fid, 0);
562
563 hermes_write_regn(hw, TXCOMPLFID, DUMMY_FID);
564 stats->tx_errors++;
565
566 if (err) {
567 printk(KERN_WARNING "%s: Unable to read descriptor on Tx error "
568 "(FID=%04X error %d)\n",
569 dev->name, fid, err);
570 return;
571 }
572
573 DEBUG(1, "%s: Tx error, err %d (FID=%04X)\n", dev->name,
574 err, fid);
575
576 /* We produce a TXDROP event only for retry or lifetime
577 * exceeded, because that's the only status that really mean
578 * that this particular node went away.
579 * Other errors means that *we* screwed up. - Jean II */
580 status = le16_to_cpu(hdr.desc.status);
581 if (status & (HERMES_TXSTAT_RETRYERR | HERMES_TXSTAT_AGEDERR)) {
582 union iwreq_data wrqu;
583
584 /* Copy 802.11 dest address.
585 * We use the 802.11 header because the frame may
586 * not be 802.3 or may be mangled...
587 * In Ad-Hoc mode, it will be the node address.
588 * In managed mode, it will be most likely the AP addr
589 * User space will figure out how to convert it to
590 * whatever it needs (IP address or else).
591 * - Jean II */
592 memcpy(wrqu.addr.sa_data, hdr.addr1, ETH_ALEN);
593 wrqu.addr.sa_family = ARPHRD_ETHER;
594
595 /* Send event to user space */
596 wireless_send_event(dev, IWEVTXDROP, &wrqu, NULL);
597 }
598
599 netif_wake_queue(dev);
600}
601
602static void orinoco_tx_timeout(struct net_device *dev)
603{
604 struct orinoco_private *priv = netdev_priv(dev);
605 struct net_device_stats *stats = &priv->stats;
606 struct hermes *hw = &priv->hw;
607
608 printk(KERN_WARNING "%s: Tx timeout! "
609 "ALLOCFID=%04x, TXCOMPLFID=%04x, EVSTAT=%04x\n",
610 dev->name, hermes_read_regn(hw, ALLOCFID),
611 hermes_read_regn(hw, TXCOMPLFID), hermes_read_regn(hw, EVSTAT));
612
613 stats->tx_errors++;
614
615 schedule_work(&priv->reset_work);
616}
617
618/********************************************************************/
619/* Rx path (data frames) */
620/********************************************************************/
621
622/* Does the frame have a SNAP header indicating it should be
623 * de-encapsulated to Ethernet-II? */
624static inline int is_ethersnap(void *_hdr)
625{
626 u8 *hdr = _hdr;
627
628 /* We de-encapsulate all packets which, a) have SNAP headers
629 * (i.e. SSAP=DSAP=0xaa and CTRL=0x3 in the 802.2 LLC header
630 * and where b) the OUI of the SNAP header is 00:00:00 or
631 * 00:00:f8 - we need both because different APs appear to use
632 * different OUIs for some reason */
633 return (memcmp(hdr, &encaps_hdr, 5) == 0)
634 && ((hdr[5] == 0x00) || (hdr[5] == 0xf8));
635}
636
637static inline void orinoco_spy_gather(struct net_device *dev, u_char *mac,
638 int level, int noise)
639{
640 struct iw_quality wstats;
641 wstats.level = level - 0x95;
642 wstats.noise = noise - 0x95;
643 wstats.qual = (level > noise) ? (level - noise) : 0;
644 wstats.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
645 /* Update spy records */
646 wireless_spy_update(dev, mac, &wstats);
647}
648
649static void orinoco_stat_gather(struct net_device *dev,
650 struct sk_buff *skb,
651 struct hermes_rx_descriptor *desc)
652{
653 struct orinoco_private *priv = netdev_priv(dev);
654
655 /* Using spy support with lots of Rx packets, like in an
656 * infrastructure (AP), will really slow down everything, because
657 * the MAC address must be compared to each entry of the spy list.
658 * If the user really asks for it (set some address in the
659 * spy list), we do it, but he will pay the price.
660 * Note that to get here, you need both WIRELESS_SPY
661 * compiled in AND some addresses in the list !!!
662 */
663 /* Note : gcc will optimise the whole section away if
664 * WIRELESS_SPY is not defined... - Jean II */
665 if (SPY_NUMBER(priv)) {
666 orinoco_spy_gather(dev, skb_mac_header(skb) + ETH_ALEN,
667 desc->signal, desc->silence);
668 }
669}
670
671/*
672 * orinoco_rx_monitor - handle received monitor frames.
673 *
674 * Arguments:
675 * dev network device
676 * rxfid received FID
677 * desc rx descriptor of the frame
678 *
679 * Call context: interrupt
680 */
681static void orinoco_rx_monitor(struct net_device *dev, u16 rxfid,
682 struct hermes_rx_descriptor *desc)
683{
684 u32 hdrlen = 30; /* return full header by default */
685 u32 datalen = 0;
686 u16 fc;
687 int err;
688 int len;
689 struct sk_buff *skb;
690 struct orinoco_private *priv = netdev_priv(dev);
691 struct net_device_stats *stats = &priv->stats;
692 hermes_t *hw = &priv->hw;
693
694 len = le16_to_cpu(desc->data_len);
695
696 /* Determine the size of the header and the data */
697 fc = le16_to_cpu(desc->frame_ctl);
698 switch (fc & IEEE80211_FCTL_FTYPE) {
699 case IEEE80211_FTYPE_DATA:
700 if ((fc & IEEE80211_FCTL_TODS)
701 && (fc & IEEE80211_FCTL_FROMDS))
702 hdrlen = 30;
703 else
704 hdrlen = 24;
705 datalen = len;
706 break;
707 case IEEE80211_FTYPE_MGMT:
708 hdrlen = 24;
709 datalen = len;
710 break;
711 case IEEE80211_FTYPE_CTL:
712 switch (fc & IEEE80211_FCTL_STYPE) {
713 case IEEE80211_STYPE_PSPOLL:
714 case IEEE80211_STYPE_RTS:
715 case IEEE80211_STYPE_CFEND:
716 case IEEE80211_STYPE_CFENDACK:
717 hdrlen = 16;
718 break;
719 case IEEE80211_STYPE_CTS:
720 case IEEE80211_STYPE_ACK:
721 hdrlen = 10;
722 break;
723 }
724 break;
725 default:
726 /* Unknown frame type */
727 break;
728 }
729
730 /* sanity check the length */
731 if (datalen > IEEE80211_MAX_DATA_LEN + 12) {
732 printk(KERN_DEBUG "%s: oversized monitor frame, "
733 "data length = %d\n", dev->name, datalen);
734 stats->rx_length_errors++;
735 goto update_stats;
736 }
737
738 skb = dev_alloc_skb(hdrlen + datalen);
739 if (!skb) {
740 printk(KERN_WARNING "%s: Cannot allocate skb for monitor frame\n",
741 dev->name);
742 goto update_stats;
743 }
744
745 /* Copy the 802.11 header to the skb */
746 memcpy(skb_put(skb, hdrlen), &(desc->frame_ctl), hdrlen);
747 skb_reset_mac_header(skb);
748
749 /* If any, copy the data from the card to the skb */
750 if (datalen > 0) {
751 err = hermes_bap_pread(hw, IRQ_BAP, skb_put(skb, datalen),
752 ALIGN(datalen, 2), rxfid,
753 HERMES_802_2_OFFSET);
754 if (err) {
755 printk(KERN_ERR "%s: error %d reading monitor frame\n",
756 dev->name, err);
757 goto drop;
758 }
759 }
760
761 skb->dev = dev;
762 skb->ip_summed = CHECKSUM_NONE;
763 skb->pkt_type = PACKET_OTHERHOST;
764 skb->protocol = cpu_to_be16(ETH_P_802_2);
765
766 stats->rx_packets++;
767 stats->rx_bytes += skb->len;
768
769 netif_rx(skb);
770 return;
771
772 drop:
773 dev_kfree_skb_irq(skb);
774 update_stats:
775 stats->rx_errors++;
776 stats->rx_dropped++;
777}
778
779static void __orinoco_ev_rx(struct net_device *dev, hermes_t *hw)
780{
781 struct orinoco_private *priv = netdev_priv(dev);
782 struct net_device_stats *stats = &priv->stats;
783 struct iw_statistics *wstats = &priv->wstats;
784 struct sk_buff *skb = NULL;
785 u16 rxfid, status;
786 int length;
787 struct hermes_rx_descriptor *desc;
788 struct orinoco_rx_data *rx_data;
789 int err;
790
791 desc = kmalloc(sizeof(*desc), GFP_ATOMIC);
792 if (!desc) {
793 printk(KERN_WARNING
794 "%s: Can't allocate space for RX descriptor\n",
795 dev->name);
796 goto update_stats;
797 }
798
799 rxfid = hermes_read_regn(hw, RXFID);
800
801 err = hermes_bap_pread(hw, IRQ_BAP, desc, sizeof(*desc),
802 rxfid, 0);
803 if (err) {
804 printk(KERN_ERR "%s: error %d reading Rx descriptor. "
805 "Frame dropped.\n", dev->name, err);
806 goto update_stats;
807 }
808
809 status = le16_to_cpu(desc->status);
810
811 if (status & HERMES_RXSTAT_BADCRC) {
812 DEBUG(1, "%s: Bad CRC on Rx. Frame dropped.\n",
813 dev->name);
814 stats->rx_crc_errors++;
815 goto update_stats;
816 }
817
818 /* Handle frames in monitor mode */
819 if (priv->iw_mode == IW_MODE_MONITOR) {
820 orinoco_rx_monitor(dev, rxfid, desc);
821 goto out;
822 }
823
824 if (status & HERMES_RXSTAT_UNDECRYPTABLE) {
825 DEBUG(1, "%s: Undecryptable frame on Rx. Frame dropped.\n",
826 dev->name);
827 wstats->discard.code++;
828 goto update_stats;
829 }
830
831 length = le16_to_cpu(desc->data_len);
832
833 /* Sanity checks */
834 if (length < 3) { /* No for even an 802.2 LLC header */
835 /* At least on Symbol firmware with PCF we get quite a
836 lot of these legitimately - Poll frames with no
837 data. */
838 goto out;
839 }
840 if (length > IEEE80211_MAX_DATA_LEN) {
841 printk(KERN_WARNING "%s: Oversized frame received (%d bytes)\n",
842 dev->name, length);
843 stats->rx_length_errors++;
844 goto update_stats;
845 }
846
847 /* Payload size does not include Michael MIC. Increase payload
848 * size to read it together with the data. */
849 if (status & HERMES_RXSTAT_MIC)
850 length += MICHAEL_MIC_LEN;
851
852 /* We need space for the packet data itself, plus an ethernet
853 header, plus 2 bytes so we can align the IP header on a
854 32bit boundary, plus 1 byte so we can read in odd length
855 packets from the card, which has an IO granularity of 16
856 bits */
857 skb = dev_alloc_skb(length+ETH_HLEN+2+1);
858 if (!skb) {
859 printk(KERN_WARNING "%s: Can't allocate skb for Rx\n",
860 dev->name);
861 goto update_stats;
862 }
863
864 /* We'll prepend the header, so reserve space for it. The worst
865 case is no decapsulation, when 802.3 header is prepended and
866 nothing is removed. 2 is for aligning the IP header. */
867 skb_reserve(skb, ETH_HLEN + 2);
868
869 err = hermes_bap_pread(hw, IRQ_BAP, skb_put(skb, length),
870 ALIGN(length, 2), rxfid,
871 HERMES_802_2_OFFSET);
872 if (err) {
873 printk(KERN_ERR "%s: error %d reading frame. "
874 "Frame dropped.\n", dev->name, err);
875 goto drop;
876 }
877
878 /* Add desc and skb to rx queue */
879 rx_data = kzalloc(sizeof(*rx_data), GFP_ATOMIC);
880 if (!rx_data) {
881 printk(KERN_WARNING "%s: Can't allocate RX packet\n",
882 dev->name);
883 goto drop;
884 }
885 rx_data->desc = desc;
886 rx_data->skb = skb;
887 list_add_tail(&rx_data->list, &priv->rx_list);
888 tasklet_schedule(&priv->rx_tasklet);
889
890 return;
891
892drop:
893 dev_kfree_skb_irq(skb);
894update_stats:
895 stats->rx_errors++;
896 stats->rx_dropped++;
897out:
898 kfree(desc);
899}
900
901static void orinoco_rx(struct net_device *dev,
902 struct hermes_rx_descriptor *desc,
903 struct sk_buff *skb)
904{
905 struct orinoco_private *priv = netdev_priv(dev);
906 struct net_device_stats *stats = &priv->stats;
907 u16 status, fc;
908 int length;
909 struct ethhdr *hdr;
910
911 status = le16_to_cpu(desc->status);
912 length = le16_to_cpu(desc->data_len);
913 fc = le16_to_cpu(desc->frame_ctl);
914
915 /* Calculate and check MIC */
916 if (status & HERMES_RXSTAT_MIC) {
917 int key_id = ((status & HERMES_RXSTAT_MIC_KEY_ID) >>
918 HERMES_MIC_KEY_ID_SHIFT);
919 u8 mic[MICHAEL_MIC_LEN];
920 u8 *rxmic;
921 u8 *src = (fc & IEEE80211_FCTL_FROMDS) ?
922 desc->addr3 : desc->addr2;
923
924 /* Extract Michael MIC from payload */
925 rxmic = skb->data + skb->len - MICHAEL_MIC_LEN;
926
927 skb_trim(skb, skb->len - MICHAEL_MIC_LEN);
928 length -= MICHAEL_MIC_LEN;
929
930 orinoco_mic(priv->rx_tfm_mic,
931 priv->tkip_key[key_id].rx_mic,
932 desc->addr1,
933 src,
934 0, /* priority or QoS? */
935 skb->data,
936 skb->len,
937 &mic[0]);
938
939 if (memcmp(mic, rxmic,
940 MICHAEL_MIC_LEN)) {
941 union iwreq_data wrqu;
942 struct iw_michaelmicfailure wxmic;
943
944 printk(KERN_WARNING "%s: "
945 "Invalid Michael MIC in data frame from %pM, "
946 "using key %i\n",
947 dev->name, src, key_id);
948
949 /* TODO: update stats */
950
951 /* Notify userspace */
952 memset(&wxmic, 0, sizeof(wxmic));
953 wxmic.flags = key_id & IW_MICFAILURE_KEY_ID;
954 wxmic.flags |= (desc->addr1[0] & 1) ?
955 IW_MICFAILURE_GROUP : IW_MICFAILURE_PAIRWISE;
956 wxmic.src_addr.sa_family = ARPHRD_ETHER;
957 memcpy(wxmic.src_addr.sa_data, src, ETH_ALEN);
958
959 (void) orinoco_hw_get_tkip_iv(priv, key_id,
960 &wxmic.tsc[0]);
961
962 memset(&wrqu, 0, sizeof(wrqu));
963 wrqu.data.length = sizeof(wxmic);
964 wireless_send_event(dev, IWEVMICHAELMICFAILURE, &wrqu,
965 (char *) &wxmic);
966
967 goto drop;
968 }
969 }
970
971 /* Handle decapsulation
972 * In most cases, the firmware tell us about SNAP frames.
973 * For some reason, the SNAP frames sent by LinkSys APs
974 * are not properly recognised by most firmwares.
975 * So, check ourselves */
976 if (length >= ENCAPS_OVERHEAD &&
977 (((status & HERMES_RXSTAT_MSGTYPE) == HERMES_RXSTAT_1042) ||
978 ((status & HERMES_RXSTAT_MSGTYPE) == HERMES_RXSTAT_TUNNEL) ||
979 is_ethersnap(skb->data))) {
980 /* These indicate a SNAP within 802.2 LLC within
981 802.11 frame which we'll need to de-encapsulate to
982 the original EthernetII frame. */
983 hdr = (struct ethhdr *)skb_push(skb,
984 ETH_HLEN - ENCAPS_OVERHEAD);
985 } else {
986 /* 802.3 frame - prepend 802.3 header as is */
987 hdr = (struct ethhdr *)skb_push(skb, ETH_HLEN);
988 hdr->h_proto = htons(length);
989 }
990 memcpy(hdr->h_dest, desc->addr1, ETH_ALEN);
991 if (fc & IEEE80211_FCTL_FROMDS)
992 memcpy(hdr->h_source, desc->addr3, ETH_ALEN);
993 else
994 memcpy(hdr->h_source, desc->addr2, ETH_ALEN);
995
996 skb->protocol = eth_type_trans(skb, dev);
997 skb->ip_summed = CHECKSUM_NONE;
998 if (fc & IEEE80211_FCTL_TODS)
999 skb->pkt_type = PACKET_OTHERHOST;
1000
1001 /* Process the wireless stats if needed */
1002 orinoco_stat_gather(dev, skb, desc);
1003
1004 /* Pass the packet to the networking stack */
1005 netif_rx(skb);
1006 stats->rx_packets++;
1007 stats->rx_bytes += length;
1008
1009 return;
1010
1011 drop:
1012 dev_kfree_skb(skb);
1013 stats->rx_errors++;
1014 stats->rx_dropped++;
1015}
1016
1017static void orinoco_rx_isr_tasklet(unsigned long data)
1018{
1019 struct net_device *dev = (struct net_device *) data;
1020 struct orinoco_private *priv = netdev_priv(dev);
1021 struct orinoco_rx_data *rx_data, *temp;
1022 struct hermes_rx_descriptor *desc;
1023 struct sk_buff *skb;
1024 unsigned long flags;
1025
1026 /* orinoco_rx requires the driver lock, and we also need to
1027 * protect priv->rx_list, so just hold the lock over the
1028 * lot.
1029 *
1030 * If orinoco_lock fails, we've unplugged the card. In this
1031 * case just abort. */
1032 if (orinoco_lock(priv, &flags) != 0)
1033 return;
1034
1035 /* extract desc and skb from queue */
1036 list_for_each_entry_safe(rx_data, temp, &priv->rx_list, list) {
1037 desc = rx_data->desc;
1038 skb = rx_data->skb;
1039 list_del(&rx_data->list);
1040 kfree(rx_data);
1041
1042 orinoco_rx(dev, desc, skb);
1043
1044 kfree(desc);
1045 }
1046
1047 orinoco_unlock(priv, &flags);
1048}
1049
1050/********************************************************************/
1051/* Rx path (info frames) */
1052/********************************************************************/
1053
1054static void print_linkstatus(struct net_device *dev, u16 status)
1055{
1056 char *s;
1057
1058 if (suppress_linkstatus)
1059 return;
1060
1061 switch (status) {
1062 case HERMES_LINKSTATUS_NOT_CONNECTED:
1063 s = "Not Connected";
1064 break;
1065 case HERMES_LINKSTATUS_CONNECTED:
1066 s = "Connected";
1067 break;
1068 case HERMES_LINKSTATUS_DISCONNECTED:
1069 s = "Disconnected";
1070 break;
1071 case HERMES_LINKSTATUS_AP_CHANGE:
1072 s = "AP Changed";
1073 break;
1074 case HERMES_LINKSTATUS_AP_OUT_OF_RANGE:
1075 s = "AP Out of Range";
1076 break;
1077 case HERMES_LINKSTATUS_AP_IN_RANGE:
1078 s = "AP In Range";
1079 break;
1080 case HERMES_LINKSTATUS_ASSOC_FAILED:
1081 s = "Association Failed";
1082 break;
1083 default:
1084 s = "UNKNOWN";
1085 }
1086
1087 printk(KERN_DEBUG "%s: New link status: %s (%04x)\n",
1088 dev->name, s, status);
1089}
1090
1091/* Search scan results for requested BSSID, join it if found */
1092static void orinoco_join_ap(struct work_struct *work)
1093{
1094 struct orinoco_private *priv =
1095 container_of(work, struct orinoco_private, join_work);
1096 struct net_device *dev = priv->ndev;
1097 struct hermes *hw = &priv->hw;
1098 int err;
1099 unsigned long flags;
1100 struct join_req {
1101 u8 bssid[ETH_ALEN];
1102 __le16 channel;
1103 } __attribute__ ((packed)) req;
1104 const int atom_len = offsetof(struct prism2_scan_apinfo, atim);
1105 struct prism2_scan_apinfo *atom = NULL;
1106 int offset = 4;
1107 int found = 0;
1108 u8 *buf;
1109 u16 len;
1110
1111 /* Allocate buffer for scan results */
1112 buf = kmalloc(MAX_SCAN_LEN, GFP_KERNEL);
1113 if (!buf)
1114 return;
1115
1116 if (orinoco_lock(priv, &flags) != 0)
1117 goto fail_lock;
1118
1119 /* Sanity checks in case user changed something in the meantime */
1120 if (!priv->bssid_fixed)
1121 goto out;
1122
1123 if (strlen(priv->desired_essid) == 0)
1124 goto out;
1125
1126 /* Read scan results from the firmware */
1127 err = hermes_read_ltv(hw, USER_BAP,
1128 HERMES_RID_SCANRESULTSTABLE,
1129 MAX_SCAN_LEN, &len, buf);
1130 if (err) {
1131 printk(KERN_ERR "%s: Cannot read scan results\n",
1132 dev->name);
1133 goto out;
1134 }
1135
1136 len = HERMES_RECLEN_TO_BYTES(len);
1137
1138 /* Go through the scan results looking for the channel of the AP
1139 * we were requested to join */
1140 for (; offset + atom_len <= len; offset += atom_len) {
1141 atom = (struct prism2_scan_apinfo *) (buf + offset);
1142 if (memcmp(&atom->bssid, priv->desired_bssid, ETH_ALEN) == 0) {
1143 found = 1;
1144 break;
1145 }
1146 }
1147
1148 if (!found) {
1149 DEBUG(1, "%s: Requested AP not found in scan results\n",
1150 dev->name);
1151 goto out;
1152 }
1153
1154 memcpy(req.bssid, priv->desired_bssid, ETH_ALEN);
1155 req.channel = atom->channel; /* both are little-endian */
1156 err = HERMES_WRITE_RECORD(hw, USER_BAP, HERMES_RID_CNFJOINREQUEST,
1157 &req);
1158 if (err)
1159 printk(KERN_ERR "%s: Error issuing join request\n", dev->name);
1160
1161 out:
1162 orinoco_unlock(priv, &flags);
1163
1164 fail_lock:
1165 kfree(buf);
1166}
1167
1168/* Send new BSSID to userspace */
1169static void orinoco_send_bssid_wevent(struct orinoco_private *priv)
1170{
1171 struct net_device *dev = priv->ndev;
1172 struct hermes *hw = &priv->hw;
1173 union iwreq_data wrqu;
1174 int err;
1175
1176 err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CURRENTBSSID,
1177 ETH_ALEN, NULL, wrqu.ap_addr.sa_data);
1178 if (err != 0)
1179 return;
1180
1181 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
1182
1183 /* Send event to user space */
1184 wireless_send_event(dev, SIOCGIWAP, &wrqu, NULL);
1185}
1186
1187static void orinoco_send_assocreqie_wevent(struct orinoco_private *priv)
1188{
1189 struct net_device *dev = priv->ndev;
1190 struct hermes *hw = &priv->hw;
1191 union iwreq_data wrqu;
1192 int err;
1193 u8 buf[88];
1194 u8 *ie;
1195
1196 if (!priv->has_wpa)
1197 return;
1198
1199 err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CURRENT_ASSOC_REQ_INFO,
1200 sizeof(buf), NULL, &buf);
1201 if (err != 0)
1202 return;
1203
1204 ie = orinoco_get_wpa_ie(buf, sizeof(buf));
1205 if (ie) {
1206 int rem = sizeof(buf) - (ie - &buf[0]);
1207 wrqu.data.length = ie[1] + 2;
1208 if (wrqu.data.length > rem)
1209 wrqu.data.length = rem;
1210
1211 if (wrqu.data.length)
1212 /* Send event to user space */
1213 wireless_send_event(dev, IWEVASSOCREQIE, &wrqu, ie);
1214 }
1215}
1216
1217static void orinoco_send_assocrespie_wevent(struct orinoco_private *priv)
1218{
1219 struct net_device *dev = priv->ndev;
1220 struct hermes *hw = &priv->hw;
1221 union iwreq_data wrqu;
1222 int err;
1223 u8 buf[88]; /* TODO: verify max size or IW_GENERIC_IE_MAX */
1224 u8 *ie;
1225
1226 if (!priv->has_wpa)
1227 return;
1228
1229 err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CURRENT_ASSOC_RESP_INFO,
1230 sizeof(buf), NULL, &buf);
1231 if (err != 0)
1232 return;
1233
1234 ie = orinoco_get_wpa_ie(buf, sizeof(buf));
1235 if (ie) {
1236 int rem = sizeof(buf) - (ie - &buf[0]);
1237 wrqu.data.length = ie[1] + 2;
1238 if (wrqu.data.length > rem)
1239 wrqu.data.length = rem;
1240
1241 if (wrqu.data.length)
1242 /* Send event to user space */
1243 wireless_send_event(dev, IWEVASSOCRESPIE, &wrqu, ie);
1244 }
1245}
1246
1247static void orinoco_send_wevents(struct work_struct *work)
1248{
1249 struct orinoco_private *priv =
1250 container_of(work, struct orinoco_private, wevent_work);
1251 unsigned long flags;
1252
1253 if (orinoco_lock(priv, &flags) != 0)
1254 return;
1255
1256 orinoco_send_assocreqie_wevent(priv);
1257 orinoco_send_assocrespie_wevent(priv);
1258 orinoco_send_bssid_wevent(priv);
1259
1260 orinoco_unlock(priv, &flags);
1261}
1262
1263static void __orinoco_ev_info(struct net_device *dev, hermes_t *hw)
1264{
1265 struct orinoco_private *priv = netdev_priv(dev);
1266 u16 infofid;
1267 struct {
1268 __le16 len;
1269 __le16 type;
1270 } __attribute__ ((packed)) info;
1271 int len, type;
1272 int err;
1273
1274 /* This is an answer to an INQUIRE command that we did earlier,
1275 * or an information "event" generated by the card
1276 * The controller return to us a pseudo frame containing
1277 * the information in question - Jean II */
1278 infofid = hermes_read_regn(hw, INFOFID);
1279
1280 /* Read the info frame header - don't try too hard */
1281 err = hermes_bap_pread(hw, IRQ_BAP, &info, sizeof(info),
1282 infofid, 0);
1283 if (err) {
1284 printk(KERN_ERR "%s: error %d reading info frame. "
1285 "Frame dropped.\n", dev->name, err);
1286 return;
1287 }
1288
1289 len = HERMES_RECLEN_TO_BYTES(le16_to_cpu(info.len));
1290 type = le16_to_cpu(info.type);
1291
1292 switch (type) {
1293 case HERMES_INQ_TALLIES: {
1294 struct hermes_tallies_frame tallies;
1295 struct iw_statistics *wstats = &priv->wstats;
1296
1297 if (len > sizeof(tallies)) {
1298 printk(KERN_WARNING "%s: Tallies frame too long (%d bytes)\n",
1299 dev->name, len);
1300 len = sizeof(tallies);
1301 }
1302
1303 err = hermes_bap_pread(hw, IRQ_BAP, &tallies, len,
1304 infofid, sizeof(info));
1305 if (err)
1306 break;
1307
1308 /* Increment our various counters */
1309 /* wstats->discard.nwid - no wrong BSSID stuff */
1310 wstats->discard.code +=
1311 le16_to_cpu(tallies.RxWEPUndecryptable);
1312 if (len == sizeof(tallies))
1313 wstats->discard.code +=
1314 le16_to_cpu(tallies.RxDiscards_WEPICVError) +
1315 le16_to_cpu(tallies.RxDiscards_WEPExcluded);
1316 wstats->discard.misc +=
1317 le16_to_cpu(tallies.TxDiscardsWrongSA);
1318 wstats->discard.fragment +=
1319 le16_to_cpu(tallies.RxMsgInBadMsgFragments);
1320 wstats->discard.retries +=
1321 le16_to_cpu(tallies.TxRetryLimitExceeded);
1322 /* wstats->miss.beacon - no match */
1323 }
1324 break;
1325 case HERMES_INQ_LINKSTATUS: {
1326 struct hermes_linkstatus linkstatus;
1327 u16 newstatus;
1328 int connected;
1329
1330 if (priv->iw_mode == IW_MODE_MONITOR)
1331 break;
1332
1333 if (len != sizeof(linkstatus)) {
1334 printk(KERN_WARNING "%s: Unexpected size for linkstatus frame (%d bytes)\n",
1335 dev->name, len);
1336 break;
1337 }
1338
1339 err = hermes_bap_pread(hw, IRQ_BAP, &linkstatus, len,
1340 infofid, sizeof(info));
1341 if (err)
1342 break;
1343 newstatus = le16_to_cpu(linkstatus.linkstatus);
1344
1345 /* Symbol firmware uses "out of range" to signal that
1346 * the hostscan frame can be requested. */
1347 if (newstatus == HERMES_LINKSTATUS_AP_OUT_OF_RANGE &&
1348 priv->firmware_type == FIRMWARE_TYPE_SYMBOL &&
1349 priv->has_hostscan && priv->scan_inprogress) {
1350 hermes_inquire(hw, HERMES_INQ_HOSTSCAN_SYMBOL);
1351 break;
1352 }
1353
1354 connected = (newstatus == HERMES_LINKSTATUS_CONNECTED)
1355 || (newstatus == HERMES_LINKSTATUS_AP_CHANGE)
1356 || (newstatus == HERMES_LINKSTATUS_AP_IN_RANGE);
1357
1358 if (connected)
1359 netif_carrier_on(dev);
1360 else if (!ignore_disconnect)
1361 netif_carrier_off(dev);
1362
1363 if (newstatus != priv->last_linkstatus) {
1364 priv->last_linkstatus = newstatus;
1365 print_linkstatus(dev, newstatus);
1366 /* The info frame contains only one word which is the
1367 * status (see hermes.h). The status is pretty boring
1368 * in itself, that's why we export the new BSSID...
1369 * Jean II */
1370 schedule_work(&priv->wevent_work);
1371 }
1372 }
1373 break;
1374 case HERMES_INQ_SCAN:
1375 if (!priv->scan_inprogress && priv->bssid_fixed &&
1376 priv->firmware_type == FIRMWARE_TYPE_INTERSIL) {
1377 schedule_work(&priv->join_work);
1378 break;
1379 }
1380 /* fall through */
1381 case HERMES_INQ_HOSTSCAN:
1382 case HERMES_INQ_HOSTSCAN_SYMBOL: {
1383 /* Result of a scanning. Contains information about
1384 * cells in the vicinity - Jean II */
1385 union iwreq_data wrqu;
1386 unsigned char *buf;
1387
1388 /* Scan is no longer in progress */
1389 priv->scan_inprogress = 0;
1390
1391 /* Sanity check */
1392 if (len > 4096) {
1393 printk(KERN_WARNING "%s: Scan results too large (%d bytes)\n",
1394 dev->name, len);
1395 break;
1396 }
1397
1398 /* Allocate buffer for results */
1399 buf = kmalloc(len, GFP_ATOMIC);
1400 if (buf == NULL)
1401 /* No memory, so can't printk()... */
1402 break;
1403
1404 /* Read scan data */
1405 err = hermes_bap_pread(hw, IRQ_BAP, (void *) buf, len,
1406 infofid, sizeof(info));
1407 if (err) {
1408 kfree(buf);
1409 break;
1410 }
1411
1412#ifdef ORINOCO_DEBUG
1413 {
1414 int i;
1415 printk(KERN_DEBUG "Scan result [%02X", buf[0]);
1416 for (i = 1; i < (len * 2); i++)
1417 printk(":%02X", buf[i]);
1418 printk("]\n");
1419 }
1420#endif /* ORINOCO_DEBUG */
1421
1422 if (orinoco_process_scan_results(priv, buf, len) == 0) {
1423 /* Send an empty event to user space.
1424 * We don't send the received data on the event because
1425 * it would require us to do complex transcoding, and
1426 * we want to minimise the work done in the irq handler
1427 * Use a request to extract the data - Jean II */
1428 wrqu.data.length = 0;
1429 wrqu.data.flags = 0;
1430 wireless_send_event(dev, SIOCGIWSCAN, &wrqu, NULL);
1431 }
1432 kfree(buf);
1433 }
1434 break;
1435 case HERMES_INQ_CHANNELINFO:
1436 {
1437 struct agere_ext_scan_info *bss;
1438
1439 if (!priv->scan_inprogress) {
1440 printk(KERN_DEBUG "%s: Got chaninfo without scan, "
1441 "len=%d\n", dev->name, len);
1442 break;
1443 }
1444
1445 /* An empty result indicates that the scan is complete */
1446 if (len == 0) {
1447 union iwreq_data wrqu;
1448
1449 /* Scan is no longer in progress */
1450 priv->scan_inprogress = 0;
1451
1452 wrqu.data.length = 0;
1453 wrqu.data.flags = 0;
1454 wireless_send_event(dev, SIOCGIWSCAN, &wrqu, NULL);
1455 break;
1456 }
1457
1458 /* Sanity check */
1459 else if (len > sizeof(*bss)) {
1460 printk(KERN_WARNING
1461 "%s: Ext scan results too large (%d bytes). "
1462 "Truncating results to %zd bytes.\n",
1463 dev->name, len, sizeof(*bss));
1464 len = sizeof(*bss);
1465 } else if (len < (offsetof(struct agere_ext_scan_info,
1466 data) + 2)) {
1467 /* Drop this result now so we don't have to
1468 * keep checking later */
1469 printk(KERN_WARNING
1470 "%s: Ext scan results too short (%d bytes)\n",
1471 dev->name, len);
1472 break;
1473 }
1474
1475 bss = kmalloc(sizeof(*bss), GFP_ATOMIC);
1476 if (bss == NULL)
1477 break;
1478
1479 /* Read scan data */
1480 err = hermes_bap_pread(hw, IRQ_BAP, (void *) bss, len,
1481 infofid, sizeof(info));
1482 if (err) {
1483 kfree(bss);
1484 break;
1485 }
1486
1487 orinoco_add_ext_scan_result(priv, bss);
1488
1489 kfree(bss);
1490 break;
1491 }
1492 case HERMES_INQ_SEC_STAT_AGERE:
1493 /* Security status (Agere specific) */
1494 /* Ignore this frame for now */
1495 if (priv->firmware_type == FIRMWARE_TYPE_AGERE)
1496 break;
1497 /* fall through */
1498 default:
1499 printk(KERN_DEBUG "%s: Unknown information frame received: "
1500 "type 0x%04x, length %d\n", dev->name, type, len);
1501 /* We don't actually do anything about it */
1502 break;
1503 }
1504}
1505
1506static void __orinoco_ev_infdrop(struct net_device *dev, hermes_t *hw)
1507{
1508 if (net_ratelimit())
1509 printk(KERN_DEBUG "%s: Information frame lost.\n", dev->name);
1510}
1511
1512/********************************************************************/
1513/* Internal hardware control routines */
1514/********************************************************************/
1515
1516int __orinoco_up(struct net_device *dev)
1517{
1518 struct orinoco_private *priv = netdev_priv(dev);
1519 struct hermes *hw = &priv->hw;
1520 int err;
1521
1522 netif_carrier_off(dev); /* just to make sure */
1523
1524 err = __orinoco_program_rids(dev);
1525 if (err) {
1526 printk(KERN_ERR "%s: Error %d configuring card\n",
1527 dev->name, err);
1528 return err;
1529 }
1530
1531 /* Fire things up again */
1532 hermes_set_irqmask(hw, ORINOCO_INTEN);
1533 err = hermes_enable_port(hw, 0);
1534 if (err) {
1535 printk(KERN_ERR "%s: Error %d enabling MAC port\n",
1536 dev->name, err);
1537 return err;
1538 }
1539
1540 netif_start_queue(dev);
1541
1542 return 0;
1543}
1544EXPORT_SYMBOL(__orinoco_up);
1545
1546int __orinoco_down(struct net_device *dev)
1547{
1548 struct orinoco_private *priv = netdev_priv(dev);
1549 struct hermes *hw = &priv->hw;
1550 int err;
1551
1552 netif_stop_queue(dev);
1553
1554 if (!priv->hw_unavailable) {
1555 if (!priv->broken_disableport) {
1556 err = hermes_disable_port(hw, 0);
1557 if (err) {
1558 /* Some firmwares (e.g. Intersil 1.3.x) seem
1559 * to have problems disabling the port, oh
1560 * well, too bad. */
1561 printk(KERN_WARNING "%s: Error %d disabling MAC port\n",
1562 dev->name, err);
1563 priv->broken_disableport = 1;
1564 }
1565 }
1566 hermes_set_irqmask(hw, 0);
1567 hermes_write_regn(hw, EVACK, 0xffff);
1568 }
1569
1570 /* firmware will have to reassociate */
1571 netif_carrier_off(dev);
1572 priv->last_linkstatus = 0xffff;
1573
1574 return 0;
1575}
1576EXPORT_SYMBOL(__orinoco_down);
1577
1578static int orinoco_allocate_fid(struct net_device *dev)
1579{
1580 struct orinoco_private *priv = netdev_priv(dev);
1581 struct hermes *hw = &priv->hw;
1582 int err;
1583
1584 err = hermes_allocate(hw, priv->nicbuf_size, &priv->txfid);
1585 if (err == -EIO && priv->nicbuf_size > TX_NICBUF_SIZE_BUG) {
1586 /* Try workaround for old Symbol firmware bug */
1587 priv->nicbuf_size = TX_NICBUF_SIZE_BUG;
1588 err = hermes_allocate(hw, priv->nicbuf_size, &priv->txfid);
1589
1590 printk(KERN_WARNING "%s: firmware ALLOC bug detected "
1591 "(old Symbol firmware?). Work around %s\n",
1592 dev->name, err ? "failed!" : "ok.");
1593 }
1594
1595 return err;
1596}
1597
1598int orinoco_reinit_firmware(struct net_device *dev)
1599{
1600 struct orinoco_private *priv = netdev_priv(dev);
1601 struct hermes *hw = &priv->hw;
1602 int err;
1603
1604 err = hermes_init(hw);
1605 if (priv->do_fw_download && !err) {
1606 err = orinoco_download(priv);
1607 if (err)
1608 priv->do_fw_download = 0;
1609 }
1610 if (!err)
1611 err = orinoco_allocate_fid(dev);
1612
1613 return err;
1614}
1615EXPORT_SYMBOL(orinoco_reinit_firmware);
1616
1617int __orinoco_program_rids(struct net_device *dev)
1618{
1619 struct orinoco_private *priv = netdev_priv(dev);
1620 hermes_t *hw = &priv->hw;
1621 int err;
1622 struct hermes_idstring idbuf;
1623
1624 /* Set the MAC address */
1625 err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFOWNMACADDR,
1626 HERMES_BYTES_TO_RECLEN(ETH_ALEN), dev->dev_addr);
1627 if (err) {
1628 printk(KERN_ERR "%s: Error %d setting MAC address\n",
1629 dev->name, err);
1630 return err;
1631 }
1632
1633 /* Set up the link mode */
1634 err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNFPORTTYPE,
1635 priv->port_type);
1636 if (err) {
1637 printk(KERN_ERR "%s: Error %d setting port type\n",
1638 dev->name, err);
1639 return err;
1640 }
1641 /* Set the channel/frequency */
1642 if (priv->channel != 0 && priv->iw_mode != IW_MODE_INFRA) {
1643 err = hermes_write_wordrec(hw, USER_BAP,
1644 HERMES_RID_CNFOWNCHANNEL,
1645 priv->channel);
1646 if (err) {
1647 printk(KERN_ERR "%s: Error %d setting channel %d\n",
1648 dev->name, err, priv->channel);
1649 return err;
1650 }
1651 }
1652
1653 if (priv->has_ibss) {
1654 u16 createibss;
1655
1656 if ((strlen(priv->desired_essid) == 0) && (priv->createibss)) {
1657 printk(KERN_WARNING "%s: This firmware requires an "
1658 "ESSID in IBSS-Ad-Hoc mode.\n", dev->name);
1659 /* With wvlan_cs, in this case, we would crash.
1660 * hopefully, this driver will behave better...
1661 * Jean II */
1662 createibss = 0;
1663 } else {
1664 createibss = priv->createibss;
1665 }
1666
1667 err = hermes_write_wordrec(hw, USER_BAP,
1668 HERMES_RID_CNFCREATEIBSS,
1669 createibss);
1670 if (err) {
1671 printk(KERN_ERR "%s: Error %d setting CREATEIBSS\n",
1672 dev->name, err);
1673 return err;
1674 }
1675 }
1676
1677 /* Set the desired BSSID */
1678 err = __orinoco_hw_set_wap(priv);
1679 if (err) {
1680 printk(KERN_ERR "%s: Error %d setting AP address\n",
1681 dev->name, err);
1682 return err;
1683 }
1684 /* Set the desired ESSID */
1685 idbuf.len = cpu_to_le16(strlen(priv->desired_essid));
1686 memcpy(&idbuf.val, priv->desired_essid, sizeof(idbuf.val));
1687 /* WinXP wants partner to configure OWNSSID even in IBSS mode. (jimc) */
1688 err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFOWNSSID,
1689 HERMES_BYTES_TO_RECLEN(strlen(priv->desired_essid)+2),
1690 &idbuf);
1691 if (err) {
1692 printk(KERN_ERR "%s: Error %d setting OWNSSID\n",
1693 dev->name, err);
1694 return err;
1695 }
1696 err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFDESIREDSSID,
1697 HERMES_BYTES_TO_RECLEN(strlen(priv->desired_essid)+2),
1698 &idbuf);
1699 if (err) {
1700 printk(KERN_ERR "%s: Error %d setting DESIREDSSID\n",
1701 dev->name, err);
1702 return err;
1703 }
1704
1705 /* Set the station name */
1706 idbuf.len = cpu_to_le16(strlen(priv->nick));
1707 memcpy(&idbuf.val, priv->nick, sizeof(idbuf.val));
1708 err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFOWNNAME,
1709 HERMES_BYTES_TO_RECLEN(strlen(priv->nick)+2),
1710 &idbuf);
1711 if (err) {
1712 printk(KERN_ERR "%s: Error %d setting nickname\n",
1713 dev->name, err);
1714 return err;
1715 }
1716
1717 /* Set AP density */
1718 if (priv->has_sensitivity) {
1719 err = hermes_write_wordrec(hw, USER_BAP,
1720 HERMES_RID_CNFSYSTEMSCALE,
1721 priv->ap_density);
1722 if (err) {
1723 printk(KERN_WARNING "%s: Error %d setting SYSTEMSCALE. "
1724 "Disabling sensitivity control\n",
1725 dev->name, err);
1726
1727 priv->has_sensitivity = 0;
1728 }
1729 }
1730
1731 /* Set RTS threshold */
1732 err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNFRTSTHRESHOLD,
1733 priv->rts_thresh);
1734 if (err) {
1735 printk(KERN_ERR "%s: Error %d setting RTS threshold\n",
1736 dev->name, err);
1737 return err;
1738 }
1739
1740 /* Set fragmentation threshold or MWO robustness */
1741 if (priv->has_mwo)
1742 err = hermes_write_wordrec(hw, USER_BAP,
1743 HERMES_RID_CNFMWOROBUST_AGERE,
1744 priv->mwo_robust);
1745 else
1746 err = hermes_write_wordrec(hw, USER_BAP,
1747 HERMES_RID_CNFFRAGMENTATIONTHRESHOLD,
1748 priv->frag_thresh);
1749 if (err) {
1750 printk(KERN_ERR "%s: Error %d setting fragmentation\n",
1751 dev->name, err);
1752 return err;
1753 }
1754
1755 /* Set bitrate */
1756 err = __orinoco_hw_set_bitrate(priv);
1757 if (err) {
1758 printk(KERN_ERR "%s: Error %d setting bitrate\n",
1759 dev->name, err);
1760 return err;
1761 }
1762
1763 /* Set power management */
1764 if (priv->has_pm) {
1765 err = hermes_write_wordrec(hw, USER_BAP,
1766 HERMES_RID_CNFPMENABLED,
1767 priv->pm_on);
1768 if (err) {
1769 printk(KERN_ERR "%s: Error %d setting up PM\n",
1770 dev->name, err);
1771 return err;
1772 }
1773
1774 err = hermes_write_wordrec(hw, USER_BAP,
1775 HERMES_RID_CNFMULTICASTRECEIVE,
1776 priv->pm_mcast);
1777 if (err) {
1778 printk(KERN_ERR "%s: Error %d setting up PM\n",
1779 dev->name, err);
1780 return err;
1781 }
1782 err = hermes_write_wordrec(hw, USER_BAP,
1783 HERMES_RID_CNFMAXSLEEPDURATION,
1784 priv->pm_period);
1785 if (err) {
1786 printk(KERN_ERR "%s: Error %d setting up PM\n",
1787 dev->name, err);
1788 return err;
1789 }
1790 err = hermes_write_wordrec(hw, USER_BAP,
1791 HERMES_RID_CNFPMHOLDOVERDURATION,
1792 priv->pm_timeout);
1793 if (err) {
1794 printk(KERN_ERR "%s: Error %d setting up PM\n",
1795 dev->name, err);
1796 return err;
1797 }
1798 }
1799
1800 /* Set preamble - only for Symbol so far... */
1801 if (priv->has_preamble) {
1802 err = hermes_write_wordrec(hw, USER_BAP,
1803 HERMES_RID_CNFPREAMBLE_SYMBOL,
1804 priv->preamble);
1805 if (err) {
1806 printk(KERN_ERR "%s: Error %d setting preamble\n",
1807 dev->name, err);
1808 return err;
1809 }
1810 }
1811
1812 /* Set up encryption */
1813 if (priv->has_wep || priv->has_wpa) {
1814 err = __orinoco_hw_setup_enc(priv);
1815 if (err) {
1816 printk(KERN_ERR "%s: Error %d activating encryption\n",
1817 dev->name, err);
1818 return err;
1819 }
1820 }
1821
1822 if (priv->iw_mode == IW_MODE_MONITOR) {
1823 /* Enable monitor mode */
1824 dev->type = ARPHRD_IEEE80211;
1825 err = hermes_docmd_wait(hw, HERMES_CMD_TEST |
1826 HERMES_TEST_MONITOR, 0, NULL);
1827 } else {
1828 /* Disable monitor mode */
1829 dev->type = ARPHRD_ETHER;
1830 err = hermes_docmd_wait(hw, HERMES_CMD_TEST |
1831 HERMES_TEST_STOP, 0, NULL);
1832 }
1833 if (err)
1834 return err;
1835
1836 /* Set promiscuity / multicast*/
1837 priv->promiscuous = 0;
1838 priv->mc_count = 0;
1839
1840 /* FIXME: what about netif_tx_lock */
1841 __orinoco_set_multicast_list(dev);
1842
1843 return 0;
1844}
1845
1846/* FIXME: return int? */
1847static void
1848__orinoco_set_multicast_list(struct net_device *dev)
1849{
1850 struct orinoco_private *priv = netdev_priv(dev);
1851 int err = 0;
1852 int promisc, mc_count;
1853
1854 /* The Hermes doesn't seem to have an allmulti mode, so we go
1855 * into promiscuous mode and let the upper levels deal. */
1856 if ((dev->flags & IFF_PROMISC) || (dev->flags & IFF_ALLMULTI) ||
1857 (dev->mc_count > MAX_MULTICAST(priv))) {
1858 promisc = 1;
1859 mc_count = 0;
1860 } else {
1861 promisc = 0;
1862 mc_count = dev->mc_count;
1863 }
1864
1865 err = __orinoco_hw_set_multicast_list(priv, dev->mc_list, mc_count,
1866 promisc);
1867}
1868
1869/* This must be called from user context, without locks held - use
1870 * schedule_work() */
1871void orinoco_reset(struct work_struct *work)
1872{
1873 struct orinoco_private *priv =
1874 container_of(work, struct orinoco_private, reset_work);
1875 struct net_device *dev = priv->ndev;
1876 struct hermes *hw = &priv->hw;
1877 int err;
1878 unsigned long flags;
1879
1880 if (orinoco_lock(priv, &flags) != 0)
1881 /* When the hardware becomes available again, whatever
1882 * detects that is responsible for re-initializing
1883 * it. So no need for anything further */
1884 return;
1885
1886 netif_stop_queue(dev);
1887
1888 /* Shut off interrupts. Depending on what state the hardware
1889 * is in, this might not work, but we'll try anyway */
1890 hermes_set_irqmask(hw, 0);
1891 hermes_write_regn(hw, EVACK, 0xffff);
1892
1893 priv->hw_unavailable++;
1894 priv->last_linkstatus = 0xffff; /* firmware will have to reassociate */
1895 netif_carrier_off(dev);
1896
1897 orinoco_unlock(priv, &flags);
1898
1899 /* Scanning support: Cleanup of driver struct */
1900 orinoco_clear_scan_results(priv, 0);
1901 priv->scan_inprogress = 0;
1902
1903 if (priv->hard_reset) {
1904 err = (*priv->hard_reset)(priv);
1905 if (err) {
1906 printk(KERN_ERR "%s: orinoco_reset: Error %d "
1907 "performing hard reset\n", dev->name, err);
1908 goto disable;
1909 }
1910 }
1911
1912 err = orinoco_reinit_firmware(dev);
1913 if (err) {
1914 printk(KERN_ERR "%s: orinoco_reset: Error %d re-initializing firmware\n",
1915 dev->name, err);
1916 goto disable;
1917 }
1918
1919 /* This has to be called from user context */
1920 spin_lock_irq(&priv->lock);
1921
1922 priv->hw_unavailable--;
1923
1924 /* priv->open or priv->hw_unavailable might have changed while
1925 * we dropped the lock */
1926 if (priv->open && (!priv->hw_unavailable)) {
1927 err = __orinoco_up(dev);
1928 if (err) {
1929 printk(KERN_ERR "%s: orinoco_reset: Error %d reenabling card\n",
1930 dev->name, err);
1931 } else
1932 dev->trans_start = jiffies;
1933 }
1934
1935 spin_unlock_irq(&priv->lock);
1936
1937 return;
1938 disable:
1939 hermes_set_irqmask(hw, 0);
1940 netif_device_detach(dev);
1941 printk(KERN_ERR "%s: Device has been disabled!\n", dev->name);
1942}
1943
1944/********************************************************************/
1945/* Interrupt handler */
1946/********************************************************************/
1947
1948static void __orinoco_ev_tick(struct net_device *dev, hermes_t *hw)
1949{
1950 printk(KERN_DEBUG "%s: TICK\n", dev->name);
1951}
1952
1953static void __orinoco_ev_wterr(struct net_device *dev, hermes_t *hw)
1954{
1955 /* This seems to happen a fair bit under load, but ignoring it
1956 seems to work fine...*/
1957 printk(KERN_DEBUG "%s: MAC controller error (WTERR). Ignoring.\n",
1958 dev->name);
1959}
1960
1961irqreturn_t orinoco_interrupt(int irq, void *dev_id)
1962{
1963 struct net_device *dev = dev_id;
1964 struct orinoco_private *priv = netdev_priv(dev);
1965 hermes_t *hw = &priv->hw;
1966 int count = MAX_IRQLOOPS_PER_IRQ;
1967 u16 evstat, events;
1968 /* These are used to detect a runaway interrupt situation.
1969 *
1970 * If we get more than MAX_IRQLOOPS_PER_JIFFY iterations in a jiffy,
1971 * we panic and shut down the hardware
1972 */
1973 /* jiffies value the last time we were called */
1974 static int last_irq_jiffy; /* = 0 */
1975 static int loops_this_jiffy; /* = 0 */
1976 unsigned long flags;
1977
1978 if (orinoco_lock(priv, &flags) != 0) {
1979 /* If hw is unavailable - we don't know if the irq was
1980 * for us or not */
1981 return IRQ_HANDLED;
1982 }
1983
1984 evstat = hermes_read_regn(hw, EVSTAT);
1985 events = evstat & hw->inten;
1986 if (!events) {
1987 orinoco_unlock(priv, &flags);
1988 return IRQ_NONE;
1989 }
1990
1991 if (jiffies != last_irq_jiffy)
1992 loops_this_jiffy = 0;
1993 last_irq_jiffy = jiffies;
1994
1995 while (events && count--) {
1996 if (++loops_this_jiffy > MAX_IRQLOOPS_PER_JIFFY) {
1997 printk(KERN_WARNING "%s: IRQ handler is looping too "
1998 "much! Resetting.\n", dev->name);
1999 /* Disable interrupts for now */
2000 hermes_set_irqmask(hw, 0);
2001 schedule_work(&priv->reset_work);
2002 break;
2003 }
2004
2005 /* Check the card hasn't been removed */
2006 if (!hermes_present(hw)) {
2007 DEBUG(0, "orinoco_interrupt(): card removed\n");
2008 break;
2009 }
2010
2011 if (events & HERMES_EV_TICK)
2012 __orinoco_ev_tick(dev, hw);
2013 if (events & HERMES_EV_WTERR)
2014 __orinoco_ev_wterr(dev, hw);
2015 if (events & HERMES_EV_INFDROP)
2016 __orinoco_ev_infdrop(dev, hw);
2017 if (events & HERMES_EV_INFO)
2018 __orinoco_ev_info(dev, hw);
2019 if (events & HERMES_EV_RX)
2020 __orinoco_ev_rx(dev, hw);
2021 if (events & HERMES_EV_TXEXC)
2022 __orinoco_ev_txexc(dev, hw);
2023 if (events & HERMES_EV_TX)
2024 __orinoco_ev_tx(dev, hw);
2025 if (events & HERMES_EV_ALLOC)
2026 __orinoco_ev_alloc(dev, hw);
2027
2028 hermes_write_regn(hw, EVACK, evstat);
2029
2030 evstat = hermes_read_regn(hw, EVSTAT);
2031 events = evstat & hw->inten;
2032 };
2033
2034 orinoco_unlock(priv, &flags);
2035 return IRQ_HANDLED;
2036}
2037EXPORT_SYMBOL(orinoco_interrupt);
2038
2039/********************************************************************/
2040/* Power management */
2041/********************************************************************/
2042#if defined(CONFIG_PM_SLEEP) && !defined(CONFIG_HERMES_CACHE_FW_ON_INIT)
2043static int orinoco_pm_notifier(struct notifier_block *notifier,
2044 unsigned long pm_event,
2045 void *unused)
2046{
2047 struct orinoco_private *priv = container_of(notifier,
2048 struct orinoco_private,
2049 pm_notifier);
2050
2051 /* All we need to do is cache the firmware before suspend, and
2052 * release it when we come out.
2053 *
2054 * Only need to do this if we're downloading firmware. */
2055 if (!priv->do_fw_download)
2056 return NOTIFY_DONE;
2057
2058 switch (pm_event) {
2059 case PM_HIBERNATION_PREPARE:
2060 case PM_SUSPEND_PREPARE:
2061 orinoco_cache_fw(priv, 0);
2062 break;
2063
2064 case PM_POST_RESTORE:
2065 /* Restore from hibernation failed. We need to clean
2066 * up in exactly the same way, so fall through. */
2067 case PM_POST_HIBERNATION:
2068 case PM_POST_SUSPEND:
2069 orinoco_uncache_fw(priv);
2070 break;
2071
2072 case PM_RESTORE_PREPARE:
2073 default:
2074 break;
2075 }
2076
2077 return NOTIFY_DONE;
2078}
2079#else /* !PM_SLEEP || HERMES_CACHE_FW_ON_INIT */
2080#define orinoco_pm_notifier NULL
2081#endif
2082
2083/********************************************************************/
2084/* Initialization */
2085/********************************************************************/
2086
2087struct comp_id {
2088 u16 id, variant, major, minor;
2089} __attribute__ ((packed));
2090
2091static inline fwtype_t determine_firmware_type(struct comp_id *nic_id)
2092{
2093 if (nic_id->id < 0x8000)
2094 return FIRMWARE_TYPE_AGERE;
2095 else if (nic_id->id == 0x8000 && nic_id->major == 0)
2096 return FIRMWARE_TYPE_SYMBOL;
2097 else
2098 return FIRMWARE_TYPE_INTERSIL;
2099}
2100
2101/* Set priv->firmware type, determine firmware properties */
2102static int determine_firmware(struct net_device *dev)
2103{
2104 struct orinoco_private *priv = netdev_priv(dev);
2105 hermes_t *hw = &priv->hw;
2106 int err;
2107 struct comp_id nic_id, sta_id;
2108 unsigned int firmver;
2109 char tmp[SYMBOL_MAX_VER_LEN+1] __attribute__((aligned(2)));
2110
2111 /* Get the hardware version */
2112 err = HERMES_READ_RECORD(hw, USER_BAP, HERMES_RID_NICID, &nic_id);
2113 if (err) {
2114 printk(KERN_ERR "%s: Cannot read hardware identity: error %d\n",
2115 dev->name, err);
2116 return err;
2117 }
2118
2119 le16_to_cpus(&nic_id.id);
2120 le16_to_cpus(&nic_id.variant);
2121 le16_to_cpus(&nic_id.major);
2122 le16_to_cpus(&nic_id.minor);
2123 printk(KERN_DEBUG "%s: Hardware identity %04x:%04x:%04x:%04x\n",
2124 dev->name, nic_id.id, nic_id.variant,
2125 nic_id.major, nic_id.minor);
2126
2127 priv->firmware_type = determine_firmware_type(&nic_id);
2128
2129 /* Get the firmware version */
2130 err = HERMES_READ_RECORD(hw, USER_BAP, HERMES_RID_STAID, &sta_id);
2131 if (err) {
2132 printk(KERN_ERR "%s: Cannot read station identity: error %d\n",
2133 dev->name, err);
2134 return err;
2135 }
2136
2137 le16_to_cpus(&sta_id.id);
2138 le16_to_cpus(&sta_id.variant);
2139 le16_to_cpus(&sta_id.major);
2140 le16_to_cpus(&sta_id.minor);
2141 printk(KERN_DEBUG "%s: Station identity %04x:%04x:%04x:%04x\n",
2142 dev->name, sta_id.id, sta_id.variant,
2143 sta_id.major, sta_id.minor);
2144
2145 switch (sta_id.id) {
2146 case 0x15:
2147 printk(KERN_ERR "%s: Primary firmware is active\n",
2148 dev->name);
2149 return -ENODEV;
2150 case 0x14b:
2151 printk(KERN_ERR "%s: Tertiary firmware is active\n",
2152 dev->name);
2153 return -ENODEV;
2154 case 0x1f: /* Intersil, Agere, Symbol Spectrum24 */
2155 case 0x21: /* Symbol Spectrum24 Trilogy */
2156 break;
2157 default:
2158 printk(KERN_NOTICE "%s: Unknown station ID, please report\n",
2159 dev->name);
2160 break;
2161 }
2162
2163 /* Default capabilities */
2164 priv->has_sensitivity = 1;
2165 priv->has_mwo = 0;
2166 priv->has_preamble = 0;
2167 priv->has_port3 = 1;
2168 priv->has_ibss = 1;
2169 priv->has_wep = 0;
2170 priv->has_big_wep = 0;
2171 priv->has_alt_txcntl = 0;
2172 priv->has_ext_scan = 0;
2173 priv->has_wpa = 0;
2174 priv->do_fw_download = 0;
2175
2176 /* Determine capabilities from the firmware version */
2177 switch (priv->firmware_type) {
2178 case FIRMWARE_TYPE_AGERE:
2179 /* Lucent Wavelan IEEE, Lucent Orinoco, Cabletron RoamAbout,
2180 ELSA, Melco, HP, IBM, Dell 1150, Compaq 110/210 */
2181 snprintf(priv->fw_name, sizeof(priv->fw_name) - 1,
2182 "Lucent/Agere %d.%02d", sta_id.major, sta_id.minor);
2183
2184 firmver = ((unsigned long)sta_id.major << 16) | sta_id.minor;
2185
2186 priv->has_ibss = (firmver >= 0x60006);
2187 priv->has_wep = (firmver >= 0x40020);
2188 priv->has_big_wep = 1; /* FIXME: this is wrong - how do we tell
2189 Gold cards from the others? */
2190 priv->has_mwo = (firmver >= 0x60000);
2191 priv->has_pm = (firmver >= 0x40020); /* Don't work in 7.52 ? */
2192 priv->ibss_port = 1;
2193 priv->has_hostscan = (firmver >= 0x8000a);
2194 priv->do_fw_download = 1;
2195 priv->broken_monitor = (firmver >= 0x80000);
2196 priv->has_alt_txcntl = (firmver >= 0x90000); /* All 9.x ? */
2197 priv->has_ext_scan = (firmver >= 0x90000); /* All 9.x ? */
2198 priv->has_wpa = (firmver >= 0x9002a);
2199 /* Tested with Agere firmware :
2200 * 1.16 ; 4.08 ; 4.52 ; 6.04 ; 6.16 ; 7.28 => Jean II
2201 * Tested CableTron firmware : 4.32 => Anton */
2202 break;
2203 case FIRMWARE_TYPE_SYMBOL:
2204 /* Symbol , 3Com AirConnect, Intel, Ericsson WLAN */
2205 /* Intel MAC : 00:02:B3:* */
2206 /* 3Com MAC : 00:50:DA:* */
2207 memset(tmp, 0, sizeof(tmp));
2208 /* Get the Symbol firmware version */
2209 err = hermes_read_ltv(hw, USER_BAP,
2210 HERMES_RID_SECONDARYVERSION_SYMBOL,
2211 SYMBOL_MAX_VER_LEN, NULL, &tmp);
2212 if (err) {
2213 printk(KERN_WARNING
2214 "%s: Error %d reading Symbol firmware info. "
2215 "Wildly guessing capabilities...\n",
2216 dev->name, err);
2217 firmver = 0;
2218 tmp[0] = '\0';
2219 } else {
2220 /* The firmware revision is a string, the format is
2221 * something like : "V2.20-01".
2222 * Quick and dirty parsing... - Jean II
2223 */
2224 firmver = ((tmp[1] - '0') << 16)
2225 | ((tmp[3] - '0') << 12)
2226 | ((tmp[4] - '0') << 8)
2227 | ((tmp[6] - '0') << 4)
2228 | (tmp[7] - '0');
2229
2230 tmp[SYMBOL_MAX_VER_LEN] = '\0';
2231 }
2232
2233 snprintf(priv->fw_name, sizeof(priv->fw_name) - 1,
2234 "Symbol %s", tmp);
2235
2236 priv->has_ibss = (firmver >= 0x20000);
2237 priv->has_wep = (firmver >= 0x15012);
2238 priv->has_big_wep = (firmver >= 0x20000);
2239 priv->has_pm = (firmver >= 0x20000 && firmver < 0x22000) ||
2240 (firmver >= 0x29000 && firmver < 0x30000) ||
2241 firmver >= 0x31000;
2242 priv->has_preamble = (firmver >= 0x20000);
2243 priv->ibss_port = 4;
2244
2245 /* Symbol firmware is found on various cards, but
2246 * there has been no attempt to check firmware
2247 * download on non-spectrum_cs based cards.
2248 *
2249 * Given that the Agere firmware download works
2250 * differently, we should avoid doing a firmware
2251 * download with the Symbol algorithm on non-spectrum
2252 * cards.
2253 *
2254 * For now we can identify a spectrum_cs based card
2255 * because it has a firmware reset function.
2256 */
2257 priv->do_fw_download = (priv->stop_fw != NULL);
2258
2259 priv->broken_disableport = (firmver == 0x25013) ||
2260 (firmver >= 0x30000 && firmver <= 0x31000);
2261 priv->has_hostscan = (firmver >= 0x31001) ||
2262 (firmver >= 0x29057 && firmver < 0x30000);
2263 /* Tested with Intel firmware : 0x20015 => Jean II */
2264 /* Tested with 3Com firmware : 0x15012 & 0x22001 => Jean II */
2265 break;
2266 case FIRMWARE_TYPE_INTERSIL:
2267 /* D-Link, Linksys, Adtron, ZoomAir, and many others...
2268 * Samsung, Compaq 100/200 and Proxim are slightly
2269 * different and less well tested */
2270 /* D-Link MAC : 00:40:05:* */
2271 /* Addtron MAC : 00:90:D1:* */
2272 snprintf(priv->fw_name, sizeof(priv->fw_name) - 1,
2273 "Intersil %d.%d.%d", sta_id.major, sta_id.minor,
2274 sta_id.variant);
2275
2276 firmver = ((unsigned long)sta_id.major << 16) |
2277 ((unsigned long)sta_id.minor << 8) | sta_id.variant;
2278
2279 priv->has_ibss = (firmver >= 0x000700); /* FIXME */
2280 priv->has_big_wep = priv->has_wep = (firmver >= 0x000800);
2281 priv->has_pm = (firmver >= 0x000700);
2282 priv->has_hostscan = (firmver >= 0x010301);
2283
2284 if (firmver >= 0x000800)
2285 priv->ibss_port = 0;
2286 else {
2287 printk(KERN_NOTICE "%s: Intersil firmware earlier "
2288 "than v0.8.x - several features not supported\n",
2289 dev->name);
2290 priv->ibss_port = 1;
2291 }
2292 break;
2293 }
2294 printk(KERN_DEBUG "%s: Firmware determined as %s\n", dev->name,
2295 priv->fw_name);
2296
2297 return 0;
2298}
2299
2300static int orinoco_init(struct net_device *dev)
2301{
2302 struct orinoco_private *priv = netdev_priv(dev);
2303 hermes_t *hw = &priv->hw;
2304 int err = 0;
2305 struct hermes_idstring nickbuf;
2306 u16 reclen;
2307 int len;
2308
2309 /* No need to lock, the hw_unavailable flag is already set in
2310 * alloc_orinocodev() */
2311 priv->nicbuf_size = IEEE80211_MAX_FRAME_LEN + ETH_HLEN;
2312
2313 /* Initialize the firmware */
2314 err = hermes_init(hw);
2315 if (err != 0) {
2316 printk(KERN_ERR "%s: failed to initialize firmware (err = %d)\n",
2317 dev->name, err);
2318 goto out;
2319 }
2320
2321 err = determine_firmware(dev);
2322 if (err != 0) {
2323 printk(KERN_ERR "%s: Incompatible firmware, aborting\n",
2324 dev->name);
2325 goto out;
2326 }
2327
2328 if (priv->do_fw_download) {
2329#ifdef CONFIG_HERMES_CACHE_FW_ON_INIT
2330 orinoco_cache_fw(priv, 0);
2331#endif
2332
2333 err = orinoco_download(priv);
2334 if (err)
2335 priv->do_fw_download = 0;
2336
2337 /* Check firmware version again */
2338 err = determine_firmware(dev);
2339 if (err != 0) {
2340 printk(KERN_ERR "%s: Incompatible firmware, aborting\n",
2341 dev->name);
2342 goto out;
2343 }
2344 }
2345
2346 if (priv->has_port3)
2347 printk(KERN_DEBUG "%s: Ad-hoc demo mode supported\n",
2348 dev->name);
2349 if (priv->has_ibss)
2350 printk(KERN_DEBUG "%s: IEEE standard IBSS ad-hoc mode supported\n",
2351 dev->name);
2352 if (priv->has_wep) {
2353 printk(KERN_DEBUG "%s: WEP supported, %s-bit key\n", dev->name,
2354 priv->has_big_wep ? "104" : "40");
2355 }
2356 if (priv->has_wpa) {
2357 printk(KERN_DEBUG "%s: WPA-PSK supported\n", dev->name);
2358 if (orinoco_mic_init(priv)) {
2359 printk(KERN_ERR "%s: Failed to setup MIC crypto "
2360 "algorithm. Disabling WPA support\n", dev->name);
2361 priv->has_wpa = 0;
2362 }
2363 }
2364
2365 /* Now we have the firmware capabilities, allocate appropiate
2366 * sized scan buffers */
2367 if (orinoco_bss_data_allocate(priv))
2368 goto out;
2369 orinoco_bss_data_init(priv);
2370
2371 /* Get the MAC address */
2372 err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CNFOWNMACADDR,
2373 ETH_ALEN, NULL, dev->dev_addr);
2374 if (err) {
2375 printk(KERN_WARNING "%s: failed to read MAC address!\n",
2376 dev->name);
2377 goto out;
2378 }
2379
2380 printk(KERN_DEBUG "%s: MAC address %pM\n",
2381 dev->name, dev->dev_addr);
2382
2383 /* Get the station name */
2384 err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CNFOWNNAME,
2385 sizeof(nickbuf), &reclen, &nickbuf);
2386 if (err) {
2387 printk(KERN_ERR "%s: failed to read station name\n",
2388 dev->name);
2389 goto out;
2390 }
2391 if (nickbuf.len)
2392 len = min(IW_ESSID_MAX_SIZE, (int)le16_to_cpu(nickbuf.len));
2393 else
2394 len = min(IW_ESSID_MAX_SIZE, 2 * reclen);
2395 memcpy(priv->nick, &nickbuf.val, len);
2396 priv->nick[len] = '\0';
2397
2398 printk(KERN_DEBUG "%s: Station name \"%s\"\n", dev->name, priv->nick);
2399
2400 err = orinoco_allocate_fid(dev);
2401 if (err) {
2402 printk(KERN_ERR "%s: failed to allocate NIC buffer!\n",
2403 dev->name);
2404 goto out;
2405 }
2406
2407 /* Get allowed channels */
2408 err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CHANNELLIST,
2409 &priv->channel_mask);
2410 if (err) {
2411 printk(KERN_ERR "%s: failed to read channel list!\n",
2412 dev->name);
2413 goto out;
2414 }
2415
2416 /* Get initial AP density */
2417 err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFSYSTEMSCALE,
2418 &priv->ap_density);
2419 if (err || priv->ap_density < 1 || priv->ap_density > 3)
2420 priv->has_sensitivity = 0;
2421
2422 /* Get initial RTS threshold */
2423 err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFRTSTHRESHOLD,
2424 &priv->rts_thresh);
2425 if (err) {
2426 printk(KERN_ERR "%s: failed to read RTS threshold!\n",
2427 dev->name);
2428 goto out;
2429 }
2430
2431 /* Get initial fragmentation settings */
2432 if (priv->has_mwo)
2433 err = hermes_read_wordrec(hw, USER_BAP,
2434 HERMES_RID_CNFMWOROBUST_AGERE,
2435 &priv->mwo_robust);
2436 else
2437 err = hermes_read_wordrec(hw, USER_BAP,
2438 HERMES_RID_CNFFRAGMENTATIONTHRESHOLD,
2439 &priv->frag_thresh);
2440 if (err) {
2441 printk(KERN_ERR "%s: failed to read fragmentation settings!\n",
2442 dev->name);
2443 goto out;
2444 }
2445
2446 /* Power management setup */
2447 if (priv->has_pm) {
2448 priv->pm_on = 0;
2449 priv->pm_mcast = 1;
2450 err = hermes_read_wordrec(hw, USER_BAP,
2451 HERMES_RID_CNFMAXSLEEPDURATION,
2452 &priv->pm_period);
2453 if (err) {
2454 printk(KERN_ERR "%s: failed to read power management period!\n",
2455 dev->name);
2456 goto out;
2457 }
2458 err = hermes_read_wordrec(hw, USER_BAP,
2459 HERMES_RID_CNFPMHOLDOVERDURATION,
2460 &priv->pm_timeout);
2461 if (err) {
2462 printk(KERN_ERR "%s: failed to read power management timeout!\n",
2463 dev->name);
2464 goto out;
2465 }
2466 }
2467
2468 /* Preamble setup */
2469 if (priv->has_preamble) {
2470 err = hermes_read_wordrec(hw, USER_BAP,
2471 HERMES_RID_CNFPREAMBLE_SYMBOL,
2472 &priv->preamble);
2473 if (err)
2474 goto out;
2475 }
2476
2477 /* Set up the default configuration */
2478 priv->iw_mode = IW_MODE_INFRA;
2479 /* By default use IEEE/IBSS ad-hoc mode if we have it */
2480 priv->prefer_port3 = priv->has_port3 && (!priv->has_ibss);
2481 set_port_type(priv);
2482 priv->channel = 0; /* use firmware default */
2483
2484 priv->promiscuous = 0;
2485 priv->encode_alg = IW_ENCODE_ALG_NONE;
2486 priv->tx_key = 0;
2487 priv->wpa_enabled = 0;
2488 priv->tkip_cm_active = 0;
2489 priv->key_mgmt = 0;
2490 priv->wpa_ie_len = 0;
2491 priv->wpa_ie = NULL;
2492
2493 /* Make the hardware available, as long as it hasn't been
2494 * removed elsewhere (e.g. by PCMCIA hot unplug) */
2495 spin_lock_irq(&priv->lock);
2496 priv->hw_unavailable--;
2497 spin_unlock_irq(&priv->lock);
2498
2499 printk(KERN_DEBUG "%s: ready\n", dev->name);
2500
2501 out:
2502 return err;
2503}
2504
2505static const struct net_device_ops orinoco_netdev_ops = {
2506 .ndo_init = orinoco_init,
2507 .ndo_open = orinoco_open,
2508 .ndo_stop = orinoco_stop,
2509 .ndo_start_xmit = orinoco_xmit,
2510 .ndo_set_multicast_list = orinoco_set_multicast_list,
2511 .ndo_change_mtu = orinoco_change_mtu,
2512 .ndo_tx_timeout = orinoco_tx_timeout,
2513 .ndo_get_stats = orinoco_get_stats,
2514};
2515
2516struct net_device
2517*alloc_orinocodev(int sizeof_card,
2518 struct device *device,
2519 int (*hard_reset)(struct orinoco_private *),
2520 int (*stop_fw)(struct orinoco_private *, int))
2521{
2522 struct net_device *dev;
2523 struct orinoco_private *priv;
2524
2525 dev = alloc_etherdev(sizeof(struct orinoco_private) + sizeof_card);
2526 if (!dev)
2527 return NULL;
2528 priv = netdev_priv(dev);
2529 priv->ndev = dev;
2530 if (sizeof_card)
2531 priv->card = (void *)((unsigned long)priv
2532 + sizeof(struct orinoco_private));
2533 else
2534 priv->card = NULL;
2535 priv->dev = device;
2536
2537 /* Setup / override net_device fields */
2538 dev->netdev_ops = &orinoco_netdev_ops;
2539 dev->watchdog_timeo = HZ; /* 1 second timeout */
2540 dev->ethtool_ops = &orinoco_ethtool_ops;
2541 dev->wireless_handlers = &orinoco_handler_def;
2542#ifdef WIRELESS_SPY
2543 priv->wireless_data.spy_data = &priv->spy_data;
2544 dev->wireless_data = &priv->wireless_data;
2545#endif
2546 /* we use the default eth_mac_addr for setting the MAC addr */
2547
2548 /* Reserve space in skb for the SNAP header */
2549 dev->hard_header_len += ENCAPS_OVERHEAD;
2550
2551 /* Set up default callbacks */
2552 priv->hard_reset = hard_reset;
2553 priv->stop_fw = stop_fw;
2554
2555 spin_lock_init(&priv->lock);
2556 priv->open = 0;
2557 priv->hw_unavailable = 1; /* orinoco_init() must clear this
2558 * before anything else touches the
2559 * hardware */
2560 INIT_WORK(&priv->reset_work, orinoco_reset);
2561 INIT_WORK(&priv->join_work, orinoco_join_ap);
2562 INIT_WORK(&priv->wevent_work, orinoco_send_wevents);
2563
2564 INIT_LIST_HEAD(&priv->rx_list);
2565 tasklet_init(&priv->rx_tasklet, orinoco_rx_isr_tasklet,
2566 (unsigned long) dev);
2567
2568 netif_carrier_off(dev);
2569 priv->last_linkstatus = 0xffff;
2570
2571 priv->cached_pri_fw = NULL;
2572 priv->cached_fw = NULL;
2573
2574 /* Register PM notifiers */
2575 priv->pm_notifier.notifier_call = orinoco_pm_notifier;
2576 register_pm_notifier(&priv->pm_notifier);
2577
2578 return dev;
2579}
2580EXPORT_SYMBOL(alloc_orinocodev);
2581
2582void free_orinocodev(struct net_device *dev)
2583{
2584 struct orinoco_private *priv = netdev_priv(dev);
2585 struct orinoco_rx_data *rx_data, *temp;
2586
2587 /* If the tasklet is scheduled when we call tasklet_kill it
2588 * will run one final time. However the tasklet will only
2589 * drain priv->rx_list if the hw is still available. */
2590 tasklet_kill(&priv->rx_tasklet);
2591
2592 /* Explicitly drain priv->rx_list */
2593 list_for_each_entry_safe(rx_data, temp, &priv->rx_list, list) {
2594 list_del(&rx_data->list);
2595
2596 dev_kfree_skb(rx_data->skb);
2597 kfree(rx_data->desc);
2598 kfree(rx_data);
2599 }
2600
2601 unregister_pm_notifier(&priv->pm_notifier);
2602 orinoco_uncache_fw(priv);
2603
2604 priv->wpa_ie_len = 0;
2605 kfree(priv->wpa_ie);
2606 orinoco_mic_free(priv);
2607 orinoco_bss_data_free(priv);
2608 free_netdev(dev);
2609}
2610EXPORT_SYMBOL(free_orinocodev);
2611
2612static void orinoco_get_drvinfo(struct net_device *dev,
2613 struct ethtool_drvinfo *info)
2614{
2615 struct orinoco_private *priv = netdev_priv(dev);
2616
2617 strncpy(info->driver, DRIVER_NAME, sizeof(info->driver) - 1);
2618 strncpy(info->version, DRIVER_VERSION, sizeof(info->version) - 1);
2619 strncpy(info->fw_version, priv->fw_name, sizeof(info->fw_version) - 1);
2620 if (dev->dev.parent)
2621 strncpy(info->bus_info, dev_name(dev->dev.parent),
2622 sizeof(info->bus_info) - 1);
2623 else
2624 snprintf(info->bus_info, sizeof(info->bus_info) - 1,
2625 "PCMCIA %p", priv->hw.iobase);
2626}
2627
2628static const struct ethtool_ops orinoco_ethtool_ops = {
2629 .get_drvinfo = orinoco_get_drvinfo,
2630 .get_link = ethtool_op_get_link,
2631};
2632
2633/********************************************************************/
2634/* Module initialization */
2635/********************************************************************/
2636
2637/* Can't be declared "const" or the whole __initdata section will
2638 * become const */
2639static char version[] __initdata = DRIVER_NAME " " DRIVER_VERSION
2640 " (David Gibson <hermes@gibson.dropbear.id.au>, "
2641 "Pavel Roskin <proski@gnu.org>, et al)";
2642
2643static int __init init_orinoco(void)
2644{
2645 printk(KERN_DEBUG "%s\n", version);
2646 return 0;
2647}
2648
2649static void __exit exit_orinoco(void)
2650{
2651}
2652
2653module_init(init_orinoco);
2654module_exit(exit_orinoco);
diff --git a/drivers/net/wireless/orinoco/main.h b/drivers/net/wireless/orinoco/main.h
new file mode 100644
index 000000000000..af2bae4fe395
--- /dev/null
+++ b/drivers/net/wireless/orinoco/main.h
@@ -0,0 +1,63 @@
1/* Exports from main to helper modules
2 *
3 * See copyright notice in main.c
4 */
5#ifndef _ORINOCO_MAIN_H_
6#define _ORINOCO_MAIN_H_
7
8#include <linux/ieee80211.h>
9#include "orinoco.h"
10
11/********************************************************************/
12/* Compile time configuration and compatibility stuff */
13/********************************************************************/
14
15/* We do this this way to avoid ifdefs in the actual code */
16#ifdef WIRELESS_SPY
17#define SPY_NUMBER(priv) (priv->spy_data.spy_number)
18#else
19#define SPY_NUMBER(priv) 0
20#endif /* WIRELESS_SPY */
21
22/********************************************************************/
23
24/* Export module parameter */
25extern int force_monitor;
26
27/* Forward declarations */
28struct net_device;
29struct work_struct;
30
31void set_port_type(struct orinoco_private *priv);
32int __orinoco_program_rids(struct net_device *dev);
33void orinoco_reset(struct work_struct *work);
34
35
36/* Information element helpers - find a home for these... */
37static inline u8 *orinoco_get_ie(u8 *data, size_t len,
38 enum ieee80211_eid eid)
39{
40 u8 *p = data;
41 while ((p + 2) < (data + len)) {
42 if (p[0] == eid)
43 return p;
44 p += p[1] + 2;
45 }
46 return NULL;
47}
48
49#define WPA_OUI_TYPE "\x00\x50\xF2\x01"
50#define WPA_SELECTOR_LEN 4
51static inline u8 *orinoco_get_wpa_ie(u8 *data, size_t len)
52{
53 u8 *p = data;
54 while ((p + 2 + WPA_SELECTOR_LEN) < (data + len)) {
55 if ((p[0] == WLAN_EID_GENERIC) &&
56 (memcmp(&p[2], WPA_OUI_TYPE, WPA_SELECTOR_LEN) == 0))
57 return p;
58 p += p[1] + 2;
59 }
60 return NULL;
61}
62
63#endif /* _ORINOCO_MAIN_H_ */
diff --git a/drivers/net/wireless/orinoco/mic.c b/drivers/net/wireless/orinoco/mic.c
new file mode 100644
index 000000000000..c03e7f54d1b8
--- /dev/null
+++ b/drivers/net/wireless/orinoco/mic.c
@@ -0,0 +1,79 @@
1/* Orinoco MIC helpers
2 *
3 * See copyright notice in main.c
4 */
5#include <linux/kernel.h>
6#include <linux/string.h>
7#include <linux/if_ether.h>
8#include <linux/scatterlist.h>
9#include <linux/crypto.h>
10
11#include "orinoco.h"
12#include "mic.h"
13
14/********************************************************************/
15/* Michael MIC crypto setup */
16/********************************************************************/
17int orinoco_mic_init(struct orinoco_private *priv)
18{
19 priv->tx_tfm_mic = crypto_alloc_hash("michael_mic", 0, 0);
20 if (IS_ERR(priv->tx_tfm_mic)) {
21 printk(KERN_DEBUG "orinoco_mic_init: could not allocate "
22 "crypto API michael_mic\n");
23 priv->tx_tfm_mic = NULL;
24 return -ENOMEM;
25 }
26
27 priv->rx_tfm_mic = crypto_alloc_hash("michael_mic", 0, 0);
28 if (IS_ERR(priv->rx_tfm_mic)) {
29 printk(KERN_DEBUG "orinoco_mic_init: could not allocate "
30 "crypto API michael_mic\n");
31 priv->rx_tfm_mic = NULL;
32 return -ENOMEM;
33 }
34
35 return 0;
36}
37
38void orinoco_mic_free(struct orinoco_private *priv)
39{
40 if (priv->tx_tfm_mic)
41 crypto_free_hash(priv->tx_tfm_mic);
42 if (priv->rx_tfm_mic)
43 crypto_free_hash(priv->rx_tfm_mic);
44}
45
46int orinoco_mic(struct crypto_hash *tfm_michael, u8 *key,
47 u8 *da, u8 *sa, u8 priority,
48 u8 *data, size_t data_len, u8 *mic)
49{
50 struct hash_desc desc;
51 struct scatterlist sg[2];
52 u8 hdr[ETH_HLEN + 2]; /* size of header + padding */
53
54 if (tfm_michael == NULL) {
55 printk(KERN_WARNING "orinoco_mic: tfm_michael == NULL\n");
56 return -1;
57 }
58
59 /* Copy header into buffer. We need the padding on the end zeroed */
60 memcpy(&hdr[0], da, ETH_ALEN);
61 memcpy(&hdr[ETH_ALEN], sa, ETH_ALEN);
62 hdr[ETH_ALEN*2] = priority;
63 hdr[ETH_ALEN*2+1] = 0;
64 hdr[ETH_ALEN*2+2] = 0;
65 hdr[ETH_ALEN*2+3] = 0;
66
67 /* Use scatter gather to MIC header and data in one go */
68 sg_init_table(sg, 2);
69 sg_set_buf(&sg[0], hdr, sizeof(hdr));
70 sg_set_buf(&sg[1], data, data_len);
71
72 if (crypto_hash_setkey(tfm_michael, key, MIC_KEYLEN))
73 return -1;
74
75 desc.tfm = tfm_michael;
76 desc.flags = 0;
77 return crypto_hash_digest(&desc, sg, data_len + sizeof(hdr),
78 mic);
79}
diff --git a/drivers/net/wireless/orinoco/mic.h b/drivers/net/wireless/orinoco/mic.h
new file mode 100644
index 000000000000..04d05bc566d6
--- /dev/null
+++ b/drivers/net/wireless/orinoco/mic.h
@@ -0,0 +1,22 @@
1/* Orinoco MIC helpers
2 *
3 * See copyright notice in main.c
4 */
5#ifndef _ORINOCO_MIC_H_
6#define _ORINOCO_MIC_H_
7
8#include <linux/types.h>
9
10#define MICHAEL_MIC_LEN 8
11
12/* Forward declarations */
13struct orinoco_private;
14struct crypto_hash;
15
16int orinoco_mic_init(struct orinoco_private *priv);
17void orinoco_mic_free(struct orinoco_private *priv);
18int orinoco_mic(struct crypto_hash *tfm_michael, u8 *key,
19 u8 *da, u8 *sa, u8 priority,
20 u8 *data, size_t data_len, u8 *mic);
21
22#endif /* ORINOCO_MIC_H */
diff --git a/drivers/net/wireless/orinoco/orinoco.c b/drivers/net/wireless/orinoco/orinoco.c
deleted file mode 100644
index e082ef085116..000000000000
--- a/drivers/net/wireless/orinoco/orinoco.c
+++ /dev/null
@@ -1,6153 +0,0 @@
1/* orinoco.c - (formerly known as dldwd_cs.c and orinoco_cs.c)
2 *
3 * A driver for Hermes or Prism 2 chipset based PCMCIA wireless
4 * adaptors, with Lucent/Agere, Intersil or Symbol firmware.
5 *
6 * Current maintainers (as of 29 September 2003) are:
7 * Pavel Roskin <proski AT gnu.org>
8 * and David Gibson <hermes AT gibson.dropbear.id.au>
9 *
10 * (C) Copyright David Gibson, IBM Corporation 2001-2003.
11 * Copyright (C) 2000 David Gibson, Linuxcare Australia.
12 * With some help from :
13 * Copyright (C) 2001 Jean Tourrilhes, HP Labs
14 * Copyright (C) 2001 Benjamin Herrenschmidt
15 *
16 * Based on dummy_cs.c 1.27 2000/06/12 21:27:25
17 *
18 * Portions based on wvlan_cs.c 1.0.6, Copyright Andreas Neuhaus <andy
19 * AT fasta.fh-dortmund.de>
20 * http://www.stud.fh-dortmund.de/~andy/wvlan/
21 *
22 * The contents of this file are subject to the Mozilla Public License
23 * Version 1.1 (the "License"); you may not use this file except in
24 * compliance with the License. You may obtain a copy of the License
25 * at http://www.mozilla.org/MPL/
26 *
27 * Software distributed under the License is distributed on an "AS IS"
28 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
29 * the License for the specific language governing rights and
30 * limitations under the License.
31 *
32 * The initial developer of the original code is David A. Hinds
33 * <dahinds AT users.sourceforge.net>. Portions created by David
34 * A. Hinds are Copyright (C) 1999 David A. Hinds. All Rights
35 * Reserved.
36 *
37 * Alternatively, the contents of this file may be used under the
38 * terms of the GNU General Public License version 2 (the "GPL"), in
39 * which case the provisions of the GPL are applicable instead of the
40 * above. If you wish to allow the use of your version of this file
41 * only under the terms of the GPL and not to allow others to use your
42 * version of this file under the MPL, indicate your decision by
43 * deleting the provisions above and replace them with the notice and
44 * other provisions required by the GPL. If you do not delete the
45 * provisions above, a recipient may use your version of this file
46 * under either the MPL or the GPL. */
47
48/*
49 * TODO
50 * o Handle de-encapsulation within network layer, provide 802.11
51 * headers (patch from Thomas 'Dent' Mirlacher)
52 * o Fix possible races in SPY handling.
53 * o Disconnect wireless extensions from fundamental configuration.
54 * o (maybe) Software WEP support (patch from Stano Meduna).
55 * o (maybe) Use multiple Tx buffers - driver handling queue
56 * rather than firmware.
57 */
58
59/* Locking and synchronization:
60 *
61 * The basic principle is that everything is serialized through a
62 * single spinlock, priv->lock. The lock is used in user, bh and irq
63 * context, so when taken outside hardirq context it should always be
64 * taken with interrupts disabled. The lock protects both the
65 * hardware and the struct orinoco_private.
66 *
67 * Another flag, priv->hw_unavailable indicates that the hardware is
68 * unavailable for an extended period of time (e.g. suspended, or in
69 * the middle of a hard reset). This flag is protected by the
70 * spinlock. All code which touches the hardware should check the
71 * flag after taking the lock, and if it is set, give up on whatever
72 * they are doing and drop the lock again. The orinoco_lock()
73 * function handles this (it unlocks and returns -EBUSY if
74 * hw_unavailable is non-zero).
75 */
76
77#define DRIVER_NAME "orinoco"
78
79#include <linux/module.h>
80#include <linux/kernel.h>
81#include <linux/init.h>
82#include <linux/delay.h>
83#include <linux/netdevice.h>
84#include <linux/etherdevice.h>
85#include <linux/ethtool.h>
86#include <linux/firmware.h>
87#include <linux/suspend.h>
88#include <linux/if_arp.h>
89#include <linux/wireless.h>
90#include <linux/ieee80211.h>
91#include <net/iw_handler.h>
92
93#include <linux/scatterlist.h>
94#include <linux/crypto.h>
95
96#include "hermes_rid.h"
97#include "hermes_dld.h"
98#include "orinoco.h"
99
100/********************************************************************/
101/* Module information */
102/********************************************************************/
103
104MODULE_AUTHOR("Pavel Roskin <proski@gnu.org> & David Gibson <hermes@gibson.dropbear.id.au>");
105MODULE_DESCRIPTION("Driver for Lucent Orinoco, Prism II based and similar wireless cards");
106MODULE_LICENSE("Dual MPL/GPL");
107
108/* Level of debugging. Used in the macros in orinoco.h */
109#ifdef ORINOCO_DEBUG
110int orinoco_debug = ORINOCO_DEBUG;
111module_param(orinoco_debug, int, 0644);
112MODULE_PARM_DESC(orinoco_debug, "Debug level");
113EXPORT_SYMBOL(orinoco_debug);
114#endif
115
116static int suppress_linkstatus; /* = 0 */
117module_param(suppress_linkstatus, bool, 0644);
118MODULE_PARM_DESC(suppress_linkstatus, "Don't log link status changes");
119static int ignore_disconnect; /* = 0 */
120module_param(ignore_disconnect, int, 0644);
121MODULE_PARM_DESC(ignore_disconnect, "Don't report lost link to the network layer");
122
123static int force_monitor; /* = 0 */
124module_param(force_monitor, int, 0644);
125MODULE_PARM_DESC(force_monitor, "Allow monitor mode for all firmware versions");
126
127/********************************************************************/
128/* Compile time configuration and compatibility stuff */
129/********************************************************************/
130
131/* We do this this way to avoid ifdefs in the actual code */
132#ifdef WIRELESS_SPY
133#define SPY_NUMBER(priv) (priv->spy_data.spy_number)
134#else
135#define SPY_NUMBER(priv) 0
136#endif /* WIRELESS_SPY */
137
138/********************************************************************/
139/* Internal constants */
140/********************************************************************/
141
142/* 802.2 LLC/SNAP header used for Ethernet encapsulation over 802.11 */
143static const u8 encaps_hdr[] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00};
144#define ENCAPS_OVERHEAD (sizeof(encaps_hdr) + 2)
145
146#define ORINOCO_MIN_MTU 256
147#define ORINOCO_MAX_MTU (IEEE80211_MAX_DATA_LEN - ENCAPS_OVERHEAD)
148
149#define SYMBOL_MAX_VER_LEN (14)
150#define USER_BAP 0
151#define IRQ_BAP 1
152#define MAX_IRQLOOPS_PER_IRQ 10
153#define MAX_IRQLOOPS_PER_JIFFY (20000/HZ) /* Based on a guestimate of
154 * how many events the
155 * device could
156 * legitimately generate */
157#define SMALL_KEY_SIZE 5
158#define LARGE_KEY_SIZE 13
159#define TX_NICBUF_SIZE_BUG 1585 /* Bug in Symbol firmware */
160
161#define DUMMY_FID 0xFFFF
162
163/*#define MAX_MULTICAST(priv) (priv->firmware_type == FIRMWARE_TYPE_AGERE ? \
164 HERMES_MAX_MULTICAST : 0)*/
165#define MAX_MULTICAST(priv) (HERMES_MAX_MULTICAST)
166
167#define ORINOCO_INTEN (HERMES_EV_RX | HERMES_EV_ALLOC \
168 | HERMES_EV_TX | HERMES_EV_TXEXC \
169 | HERMES_EV_WTERR | HERMES_EV_INFO \
170 | HERMES_EV_INFDROP )
171
172#define MAX_RID_LEN 1024
173
174static const struct iw_handler_def orinoco_handler_def;
175static const struct ethtool_ops orinoco_ethtool_ops;
176
177/********************************************************************/
178/* Data tables */
179/********************************************************************/
180
181#define NUM_CHANNELS 14
182
183/* This tables gives the actual meanings of the bitrate IDs returned
184 * by the firmware. */
185static struct {
186 int bitrate; /* in 100s of kilobits */
187 int automatic;
188 u16 agere_txratectrl;
189 u16 intersil_txratectrl;
190} bitrate_table[] = {
191 {110, 1, 3, 15}, /* Entry 0 is the default */
192 {10, 0, 1, 1},
193 {10, 1, 1, 1},
194 {20, 0, 2, 2},
195 {20, 1, 6, 3},
196 {55, 0, 4, 4},
197 {55, 1, 7, 7},
198 {110, 0, 5, 8},
199};
200#define BITRATE_TABLE_SIZE ARRAY_SIZE(bitrate_table)
201
202/********************************************************************/
203/* Data types */
204/********************************************************************/
205
206/* Beginning of the Tx descriptor, used in TxExc handling */
207struct hermes_txexc_data {
208 struct hermes_tx_descriptor desc;
209 __le16 frame_ctl;
210 __le16 duration_id;
211 u8 addr1[ETH_ALEN];
212} __attribute__ ((packed));
213
214/* Rx frame header except compatibility 802.3 header */
215struct hermes_rx_descriptor {
216 /* Control */
217 __le16 status;
218 __le32 time;
219 u8 silence;
220 u8 signal;
221 u8 rate;
222 u8 rxflow;
223 __le32 reserved;
224
225 /* 802.11 header */
226 __le16 frame_ctl;
227 __le16 duration_id;
228 u8 addr1[ETH_ALEN];
229 u8 addr2[ETH_ALEN];
230 u8 addr3[ETH_ALEN];
231 __le16 seq_ctl;
232 u8 addr4[ETH_ALEN];
233
234 /* Data length */
235 __le16 data_len;
236} __attribute__ ((packed));
237
238struct orinoco_rx_data {
239 struct hermes_rx_descriptor *desc;
240 struct sk_buff *skb;
241 struct list_head list;
242};
243
244/********************************************************************/
245/* Function prototypes */
246/********************************************************************/
247
248static int __orinoco_program_rids(struct net_device *dev);
249static void __orinoco_set_multicast_list(struct net_device *dev);
250
251/********************************************************************/
252/* Michael MIC crypto setup */
253/********************************************************************/
254#define MICHAEL_MIC_LEN 8
255static int orinoco_mic_init(struct orinoco_private *priv)
256{
257 priv->tx_tfm_mic = crypto_alloc_hash("michael_mic", 0, 0);
258 if (IS_ERR(priv->tx_tfm_mic)) {
259 printk(KERN_DEBUG "orinoco_mic_init: could not allocate "
260 "crypto API michael_mic\n");
261 priv->tx_tfm_mic = NULL;
262 return -ENOMEM;
263 }
264
265 priv->rx_tfm_mic = crypto_alloc_hash("michael_mic", 0, 0);
266 if (IS_ERR(priv->rx_tfm_mic)) {
267 printk(KERN_DEBUG "orinoco_mic_init: could not allocate "
268 "crypto API michael_mic\n");
269 priv->rx_tfm_mic = NULL;
270 return -ENOMEM;
271 }
272
273 return 0;
274}
275
276static void orinoco_mic_free(struct orinoco_private *priv)
277{
278 if (priv->tx_tfm_mic)
279 crypto_free_hash(priv->tx_tfm_mic);
280 if (priv->rx_tfm_mic)
281 crypto_free_hash(priv->rx_tfm_mic);
282}
283
284static int michael_mic(struct crypto_hash *tfm_michael, u8 *key,
285 u8 *da, u8 *sa, u8 priority,
286 u8 *data, size_t data_len, u8 *mic)
287{
288 struct hash_desc desc;
289 struct scatterlist sg[2];
290 u8 hdr[ETH_HLEN + 2]; /* size of header + padding */
291
292 if (tfm_michael == NULL) {
293 printk(KERN_WARNING "michael_mic: tfm_michael == NULL\n");
294 return -1;
295 }
296
297 /* Copy header into buffer. We need the padding on the end zeroed */
298 memcpy(&hdr[0], da, ETH_ALEN);
299 memcpy(&hdr[ETH_ALEN], sa, ETH_ALEN);
300 hdr[ETH_ALEN*2] = priority;
301 hdr[ETH_ALEN*2+1] = 0;
302 hdr[ETH_ALEN*2+2] = 0;
303 hdr[ETH_ALEN*2+3] = 0;
304
305 /* Use scatter gather to MIC header and data in one go */
306 sg_init_table(sg, 2);
307 sg_set_buf(&sg[0], hdr, sizeof(hdr));
308 sg_set_buf(&sg[1], data, data_len);
309
310 if (crypto_hash_setkey(tfm_michael, key, MIC_KEYLEN))
311 return -1;
312
313 desc.tfm = tfm_michael;
314 desc.flags = 0;
315 return crypto_hash_digest(&desc, sg, data_len + sizeof(hdr),
316 mic);
317}
318
319/********************************************************************/
320/* Internal helper functions */
321/********************************************************************/
322
323static inline void set_port_type(struct orinoco_private *priv)
324{
325 switch (priv->iw_mode) {
326 case IW_MODE_INFRA:
327 priv->port_type = 1;
328 priv->createibss = 0;
329 break;
330 case IW_MODE_ADHOC:
331 if (priv->prefer_port3) {
332 priv->port_type = 3;
333 priv->createibss = 0;
334 } else {
335 priv->port_type = priv->ibss_port;
336 priv->createibss = 1;
337 }
338 break;
339 case IW_MODE_MONITOR:
340 priv->port_type = 3;
341 priv->createibss = 0;
342 break;
343 default:
344 printk(KERN_ERR "%s: Invalid priv->iw_mode in set_port_type()\n",
345 priv->ndev->name);
346 }
347}
348
349#define ORINOCO_MAX_BSS_COUNT 64
350static int orinoco_bss_data_allocate(struct orinoco_private *priv)
351{
352 if (priv->bss_xbss_data)
353 return 0;
354
355 if (priv->has_ext_scan)
356 priv->bss_xbss_data = kzalloc(ORINOCO_MAX_BSS_COUNT *
357 sizeof(struct xbss_element),
358 GFP_KERNEL);
359 else
360 priv->bss_xbss_data = kzalloc(ORINOCO_MAX_BSS_COUNT *
361 sizeof(struct bss_element),
362 GFP_KERNEL);
363
364 if (!priv->bss_xbss_data) {
365 printk(KERN_WARNING "Out of memory allocating beacons");
366 return -ENOMEM;
367 }
368 return 0;
369}
370
371static void orinoco_bss_data_free(struct orinoco_private *priv)
372{
373 kfree(priv->bss_xbss_data);
374 priv->bss_xbss_data = NULL;
375}
376
377#define PRIV_BSS ((struct bss_element *)priv->bss_xbss_data)
378#define PRIV_XBSS ((struct xbss_element *)priv->bss_xbss_data)
379static void orinoco_bss_data_init(struct orinoco_private *priv)
380{
381 int i;
382
383 INIT_LIST_HEAD(&priv->bss_free_list);
384 INIT_LIST_HEAD(&priv->bss_list);
385 if (priv->has_ext_scan)
386 for (i = 0; i < ORINOCO_MAX_BSS_COUNT; i++)
387 list_add_tail(&(PRIV_XBSS[i].list),
388 &priv->bss_free_list);
389 else
390 for (i = 0; i < ORINOCO_MAX_BSS_COUNT; i++)
391 list_add_tail(&(PRIV_BSS[i].list),
392 &priv->bss_free_list);
393
394}
395
396static inline u8 *orinoco_get_ie(u8 *data, size_t len,
397 enum ieee80211_eid eid)
398{
399 u8 *p = data;
400 while ((p + 2) < (data + len)) {
401 if (p[0] == eid)
402 return p;
403 p += p[1] + 2;
404 }
405 return NULL;
406}
407
408#define WPA_OUI_TYPE "\x00\x50\xF2\x01"
409#define WPA_SELECTOR_LEN 4
410static inline u8 *orinoco_get_wpa_ie(u8 *data, size_t len)
411{
412 u8 *p = data;
413 while ((p + 2 + WPA_SELECTOR_LEN) < (data + len)) {
414 if ((p[0] == WLAN_EID_GENERIC) &&
415 (memcmp(&p[2], WPA_OUI_TYPE, WPA_SELECTOR_LEN) == 0))
416 return p;
417 p += p[1] + 2;
418 }
419 return NULL;
420}
421
422
423/********************************************************************/
424/* Download functionality */
425/********************************************************************/
426
427struct fw_info {
428 char *pri_fw;
429 char *sta_fw;
430 char *ap_fw;
431 u32 pda_addr;
432 u16 pda_size;
433};
434
435const static struct fw_info orinoco_fw[] = {
436 { NULL, "agere_sta_fw.bin", "agere_ap_fw.bin", 0x00390000, 1000 },
437 { NULL, "prism_sta_fw.bin", "prism_ap_fw.bin", 0, 1024 },
438 { "symbol_sp24t_prim_fw", "symbol_sp24t_sec_fw", NULL, 0x00003100, 512 }
439};
440
441/* Structure used to access fields in FW
442 * Make sure LE decoding macros are used
443 */
444struct orinoco_fw_header {
445 char hdr_vers[6]; /* ASCII string for header version */
446 __le16 headersize; /* Total length of header */
447 __le32 entry_point; /* NIC entry point */
448 __le32 blocks; /* Number of blocks to program */
449 __le32 block_offset; /* Offset of block data from eof header */
450 __le32 pdr_offset; /* Offset to PDR data from eof header */
451 __le32 pri_offset; /* Offset to primary plug data */
452 __le32 compat_offset; /* Offset to compatibility data*/
453 char signature[0]; /* FW signature length headersize-20 */
454} __attribute__ ((packed));
455
456/* Download either STA or AP firmware into the card. */
457static int
458orinoco_dl_firmware(struct orinoco_private *priv,
459 const struct fw_info *fw,
460 int ap)
461{
462 /* Plug Data Area (PDA) */
463 __le16 *pda;
464
465 hermes_t *hw = &priv->hw;
466 const struct firmware *fw_entry;
467 const struct orinoco_fw_header *hdr;
468 const unsigned char *first_block;
469 const unsigned char *end;
470 const char *firmware;
471 struct net_device *dev = priv->ndev;
472 int err = 0;
473
474 pda = kzalloc(fw->pda_size, GFP_KERNEL);
475 if (!pda)
476 return -ENOMEM;
477
478 if (ap)
479 firmware = fw->ap_fw;
480 else
481 firmware = fw->sta_fw;
482
483 printk(KERN_DEBUG "%s: Attempting to download firmware %s\n",
484 dev->name, firmware);
485
486 /* Read current plug data */
487 err = hermes_read_pda(hw, pda, fw->pda_addr, fw->pda_size, 0);
488 printk(KERN_DEBUG "%s: Read PDA returned %d\n", dev->name, err);
489 if (err)
490 goto free;
491
492 if (!priv->cached_fw) {
493 err = request_firmware(&fw_entry, firmware, priv->dev);
494
495 if (err) {
496 printk(KERN_ERR "%s: Cannot find firmware %s\n",
497 dev->name, firmware);
498 err = -ENOENT;
499 goto free;
500 }
501 } else
502 fw_entry = priv->cached_fw;
503
504 hdr = (const struct orinoco_fw_header *) fw_entry->data;
505
506 /* Enable aux port to allow programming */
507 err = hermesi_program_init(hw, le32_to_cpu(hdr->entry_point));
508 printk(KERN_DEBUG "%s: Program init returned %d\n", dev->name, err);
509 if (err != 0)
510 goto abort;
511
512 /* Program data */
513 first_block = (fw_entry->data +
514 le16_to_cpu(hdr->headersize) +
515 le32_to_cpu(hdr->block_offset));
516 end = fw_entry->data + fw_entry->size;
517
518 err = hermes_program(hw, first_block, end);
519 printk(KERN_DEBUG "%s: Program returned %d\n", dev->name, err);
520 if (err != 0)
521 goto abort;
522
523 /* Update production data */
524 first_block = (fw_entry->data +
525 le16_to_cpu(hdr->headersize) +
526 le32_to_cpu(hdr->pdr_offset));
527
528 err = hermes_apply_pda_with_defaults(hw, first_block, pda);
529 printk(KERN_DEBUG "%s: Apply PDA returned %d\n", dev->name, err);
530 if (err)
531 goto abort;
532
533 /* Tell card we've finished */
534 err = hermesi_program_end(hw);
535 printk(KERN_DEBUG "%s: Program end returned %d\n", dev->name, err);
536 if (err != 0)
537 goto abort;
538
539 /* Check if we're running */
540 printk(KERN_DEBUG "%s: hermes_present returned %d\n",
541 dev->name, hermes_present(hw));
542
543abort:
544 /* If we requested the firmware, release it. */
545 if (!priv->cached_fw)
546 release_firmware(fw_entry);
547
548free:
549 kfree(pda);
550 return err;
551}
552
553/* End markers */
554#define TEXT_END 0x1A /* End of text header */
555
556/*
557 * Process a firmware image - stop the card, load the firmware, reset
558 * the card and make sure it responds. For the secondary firmware take
559 * care of the PDA - read it and then write it on top of the firmware.
560 */
561static int
562symbol_dl_image(struct orinoco_private *priv, const struct fw_info *fw,
563 const unsigned char *image, const unsigned char *end,
564 int secondary)
565{
566 hermes_t *hw = &priv->hw;
567 int ret = 0;
568 const unsigned char *ptr;
569 const unsigned char *first_block;
570
571 /* Plug Data Area (PDA) */
572 __le16 *pda = NULL;
573
574 /* Binary block begins after the 0x1A marker */
575 ptr = image;
576 while (*ptr++ != TEXT_END);
577 first_block = ptr;
578
579 /* Read the PDA from EEPROM */
580 if (secondary) {
581 pda = kzalloc(fw->pda_size, GFP_KERNEL);
582 if (!pda)
583 return -ENOMEM;
584
585 ret = hermes_read_pda(hw, pda, fw->pda_addr, fw->pda_size, 1);
586 if (ret)
587 goto free;
588 }
589
590 /* Stop the firmware, so that it can be safely rewritten */
591 if (priv->stop_fw) {
592 ret = priv->stop_fw(priv, 1);
593 if (ret)
594 goto free;
595 }
596
597 /* Program the adapter with new firmware */
598 ret = hermes_program(hw, first_block, end);
599 if (ret)
600 goto free;
601
602 /* Write the PDA to the adapter */
603 if (secondary) {
604 size_t len = hermes_blocks_length(first_block);
605 ptr = first_block + len;
606 ret = hermes_apply_pda(hw, ptr, pda);
607 kfree(pda);
608 if (ret)
609 return ret;
610 }
611
612 /* Run the firmware */
613 if (priv->stop_fw) {
614 ret = priv->stop_fw(priv, 0);
615 if (ret)
616 return ret;
617 }
618
619 /* Reset hermes chip and make sure it responds */
620 ret = hermes_init(hw);
621
622 /* hermes_reset() should return 0 with the secondary firmware */
623 if (secondary && ret != 0)
624 return -ENODEV;
625
626 /* And this should work with any firmware */
627 if (!hermes_present(hw))
628 return -ENODEV;
629
630 return 0;
631
632free:
633 kfree(pda);
634 return ret;
635}
636
637
638/*
639 * Download the firmware into the card, this also does a PCMCIA soft
640 * reset on the card, to make sure it's in a sane state.
641 */
642static int
643symbol_dl_firmware(struct orinoco_private *priv,
644 const struct fw_info *fw)
645{
646 struct net_device *dev = priv->ndev;
647 int ret;
648 const struct firmware *fw_entry;
649
650 if (!priv->cached_pri_fw) {
651 if (request_firmware(&fw_entry, fw->pri_fw, priv->dev) != 0) {
652 printk(KERN_ERR "%s: Cannot find firmware: %s\n",
653 dev->name, fw->pri_fw);
654 return -ENOENT;
655 }
656 } else
657 fw_entry = priv->cached_pri_fw;
658
659 /* Load primary firmware */
660 ret = symbol_dl_image(priv, fw, fw_entry->data,
661 fw_entry->data + fw_entry->size, 0);
662
663 if (!priv->cached_pri_fw)
664 release_firmware(fw_entry);
665 if (ret) {
666 printk(KERN_ERR "%s: Primary firmware download failed\n",
667 dev->name);
668 return ret;
669 }
670
671 if (!priv->cached_fw) {
672 if (request_firmware(&fw_entry, fw->sta_fw, priv->dev) != 0) {
673 printk(KERN_ERR "%s: Cannot find firmware: %s\n",
674 dev->name, fw->sta_fw);
675 return -ENOENT;
676 }
677 } else
678 fw_entry = priv->cached_fw;
679
680 /* Load secondary firmware */
681 ret = symbol_dl_image(priv, fw, fw_entry->data,
682 fw_entry->data + fw_entry->size, 1);
683 if (!priv->cached_fw)
684 release_firmware(fw_entry);
685 if (ret) {
686 printk(KERN_ERR "%s: Secondary firmware download failed\n",
687 dev->name);
688 }
689
690 return ret;
691}
692
693static int orinoco_download(struct orinoco_private *priv)
694{
695 int err = 0;
696 /* Reload firmware */
697 switch (priv->firmware_type) {
698 case FIRMWARE_TYPE_AGERE:
699 /* case FIRMWARE_TYPE_INTERSIL: */
700 err = orinoco_dl_firmware(priv,
701 &orinoco_fw[priv->firmware_type], 0);
702 break;
703
704 case FIRMWARE_TYPE_SYMBOL:
705 err = symbol_dl_firmware(priv,
706 &orinoco_fw[priv->firmware_type]);
707 break;
708 case FIRMWARE_TYPE_INTERSIL:
709 break;
710 }
711 /* TODO: if we fail we probably need to reinitialise
712 * the driver */
713
714 return err;
715}
716
717#if defined(CONFIG_HERMES_CACHE_FW_ON_INIT) || defined(CONFIG_PM_SLEEP)
718static void orinoco_cache_fw(struct orinoco_private *priv, int ap)
719{
720 const struct firmware *fw_entry = NULL;
721 const char *pri_fw;
722 const char *fw;
723
724 pri_fw = orinoco_fw[priv->firmware_type].pri_fw;
725 if (ap)
726 fw = orinoco_fw[priv->firmware_type].ap_fw;
727 else
728 fw = orinoco_fw[priv->firmware_type].sta_fw;
729
730 if (pri_fw) {
731 if (request_firmware(&fw_entry, pri_fw, priv->dev) == 0)
732 priv->cached_pri_fw = fw_entry;
733 }
734
735 if (fw) {
736 if (request_firmware(&fw_entry, fw, priv->dev) == 0)
737 priv->cached_fw = fw_entry;
738 }
739}
740
741static void orinoco_uncache_fw(struct orinoco_private *priv)
742{
743 if (priv->cached_pri_fw)
744 release_firmware(priv->cached_pri_fw);
745 if (priv->cached_fw)
746 release_firmware(priv->cached_fw);
747
748 priv->cached_pri_fw = NULL;
749 priv->cached_fw = NULL;
750}
751#else
752#define orinoco_cache_fw(priv, ap)
753#define orinoco_uncache_fw(priv)
754#endif
755
756/********************************************************************/
757/* Device methods */
758/********************************************************************/
759
760static int orinoco_open(struct net_device *dev)
761{
762 struct orinoco_private *priv = netdev_priv(dev);
763 unsigned long flags;
764 int err;
765
766 if (orinoco_lock(priv, &flags) != 0)
767 return -EBUSY;
768
769 err = __orinoco_up(dev);
770
771 if (! err)
772 priv->open = 1;
773
774 orinoco_unlock(priv, &flags);
775
776 return err;
777}
778
779static int orinoco_stop(struct net_device *dev)
780{
781 struct orinoco_private *priv = netdev_priv(dev);
782 int err = 0;
783
784 /* We mustn't use orinoco_lock() here, because we need to be
785 able to close the interface even if hw_unavailable is set
786 (e.g. as we're released after a PC Card removal) */
787 spin_lock_irq(&priv->lock);
788
789 priv->open = 0;
790
791 err = __orinoco_down(dev);
792
793 spin_unlock_irq(&priv->lock);
794
795 return err;
796}
797
798static struct net_device_stats *orinoco_get_stats(struct net_device *dev)
799{
800 struct orinoco_private *priv = netdev_priv(dev);
801
802 return &priv->stats;
803}
804
805static struct iw_statistics *orinoco_get_wireless_stats(struct net_device *dev)
806{
807 struct orinoco_private *priv = netdev_priv(dev);
808 hermes_t *hw = &priv->hw;
809 struct iw_statistics *wstats = &priv->wstats;
810 int err;
811 unsigned long flags;
812
813 if (! netif_device_present(dev)) {
814 printk(KERN_WARNING "%s: get_wireless_stats() called while device not present\n",
815 dev->name);
816 return NULL; /* FIXME: Can we do better than this? */
817 }
818
819 /* If busy, return the old stats. Returning NULL may cause
820 * the interface to disappear from /proc/net/wireless */
821 if (orinoco_lock(priv, &flags) != 0)
822 return wstats;
823
824 /* We can't really wait for the tallies inquiry command to
825 * complete, so we just use the previous results and trigger
826 * a new tallies inquiry command for next time - Jean II */
827 /* FIXME: Really we should wait for the inquiry to come back -
828 * as it is the stats we give don't make a whole lot of sense.
829 * Unfortunately, it's not clear how to do that within the
830 * wireless extensions framework: I think we're in user
831 * context, but a lock seems to be held by the time we get in
832 * here so we're not safe to sleep here. */
833 hermes_inquire(hw, HERMES_INQ_TALLIES);
834
835 if (priv->iw_mode == IW_MODE_ADHOC) {
836 memset(&wstats->qual, 0, sizeof(wstats->qual));
837 /* If a spy address is defined, we report stats of the
838 * first spy address - Jean II */
839 if (SPY_NUMBER(priv)) {
840 wstats->qual.qual = priv->spy_data.spy_stat[0].qual;
841 wstats->qual.level = priv->spy_data.spy_stat[0].level;
842 wstats->qual.noise = priv->spy_data.spy_stat[0].noise;
843 wstats->qual.updated = priv->spy_data.spy_stat[0].updated;
844 }
845 } else {
846 struct {
847 __le16 qual, signal, noise, unused;
848 } __attribute__ ((packed)) cq;
849
850 err = HERMES_READ_RECORD(hw, USER_BAP,
851 HERMES_RID_COMMSQUALITY, &cq);
852
853 if (!err) {
854 wstats->qual.qual = (int)le16_to_cpu(cq.qual);
855 wstats->qual.level = (int)le16_to_cpu(cq.signal) - 0x95;
856 wstats->qual.noise = (int)le16_to_cpu(cq.noise) - 0x95;
857 wstats->qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
858 }
859 }
860
861 orinoco_unlock(priv, &flags);
862 return wstats;
863}
864
865static void orinoco_set_multicast_list(struct net_device *dev)
866{
867 struct orinoco_private *priv = netdev_priv(dev);
868 unsigned long flags;
869
870 if (orinoco_lock(priv, &flags) != 0) {
871 printk(KERN_DEBUG "%s: orinoco_set_multicast_list() "
872 "called when hw_unavailable\n", dev->name);
873 return;
874 }
875
876 __orinoco_set_multicast_list(dev);
877 orinoco_unlock(priv, &flags);
878}
879
880static int orinoco_change_mtu(struct net_device *dev, int new_mtu)
881{
882 struct orinoco_private *priv = netdev_priv(dev);
883
884 if ( (new_mtu < ORINOCO_MIN_MTU) || (new_mtu > ORINOCO_MAX_MTU) )
885 return -EINVAL;
886
887 /* MTU + encapsulation + header length */
888 if ( (new_mtu + ENCAPS_OVERHEAD + sizeof(struct ieee80211_hdr)) >
889 (priv->nicbuf_size - ETH_HLEN) )
890 return -EINVAL;
891
892 dev->mtu = new_mtu;
893
894 return 0;
895}
896
897/********************************************************************/
898/* Tx path */
899/********************************************************************/
900
901static int orinoco_xmit(struct sk_buff *skb, struct net_device *dev)
902{
903 struct orinoco_private *priv = netdev_priv(dev);
904 struct net_device_stats *stats = &priv->stats;
905 hermes_t *hw = &priv->hw;
906 int err = 0;
907 u16 txfid = priv->txfid;
908 struct ethhdr *eh;
909 int tx_control;
910 unsigned long flags;
911
912 if (! netif_running(dev)) {
913 printk(KERN_ERR "%s: Tx on stopped device!\n",
914 dev->name);
915 return NETDEV_TX_BUSY;
916 }
917
918 if (netif_queue_stopped(dev)) {
919 printk(KERN_DEBUG "%s: Tx while transmitter busy!\n",
920 dev->name);
921 return NETDEV_TX_BUSY;
922 }
923
924 if (orinoco_lock(priv, &flags) != 0) {
925 printk(KERN_ERR "%s: orinoco_xmit() called while hw_unavailable\n",
926 dev->name);
927 return NETDEV_TX_BUSY;
928 }
929
930 if (! netif_carrier_ok(dev) || (priv->iw_mode == IW_MODE_MONITOR)) {
931 /* Oops, the firmware hasn't established a connection,
932 silently drop the packet (this seems to be the
933 safest approach). */
934 goto drop;
935 }
936
937 /* Check packet length */
938 if (skb->len < ETH_HLEN)
939 goto drop;
940
941 tx_control = HERMES_TXCTRL_TX_OK | HERMES_TXCTRL_TX_EX;
942
943 if (priv->encode_alg == IW_ENCODE_ALG_TKIP)
944 tx_control |= (priv->tx_key << HERMES_MIC_KEY_ID_SHIFT) |
945 HERMES_TXCTRL_MIC;
946
947 if (priv->has_alt_txcntl) {
948 /* WPA enabled firmwares have tx_cntl at the end of
949 * the 802.11 header. So write zeroed descriptor and
950 * 802.11 header at the same time
951 */
952 char desc[HERMES_802_3_OFFSET];
953 __le16 *txcntl = (__le16 *) &desc[HERMES_TXCNTL2_OFFSET];
954
955 memset(&desc, 0, sizeof(desc));
956
957 *txcntl = cpu_to_le16(tx_control);
958 err = hermes_bap_pwrite(hw, USER_BAP, &desc, sizeof(desc),
959 txfid, 0);
960 if (err) {
961 if (net_ratelimit())
962 printk(KERN_ERR "%s: Error %d writing Tx "
963 "descriptor to BAP\n", dev->name, err);
964 goto busy;
965 }
966 } else {
967 struct hermes_tx_descriptor desc;
968
969 memset(&desc, 0, sizeof(desc));
970
971 desc.tx_control = cpu_to_le16(tx_control);
972 err = hermes_bap_pwrite(hw, USER_BAP, &desc, sizeof(desc),
973 txfid, 0);
974 if (err) {
975 if (net_ratelimit())
976 printk(KERN_ERR "%s: Error %d writing Tx "
977 "descriptor to BAP\n", dev->name, err);
978 goto busy;
979 }
980
981 /* Clear the 802.11 header and data length fields - some
982 * firmwares (e.g. Lucent/Agere 8.xx) appear to get confused
983 * if this isn't done. */
984 hermes_clear_words(hw, HERMES_DATA0,
985 HERMES_802_3_OFFSET - HERMES_802_11_OFFSET);
986 }
987
988 eh = (struct ethhdr *)skb->data;
989
990 /* Encapsulate Ethernet-II frames */
991 if (ntohs(eh->h_proto) > ETH_DATA_LEN) { /* Ethernet-II frame */
992 struct header_struct {
993 struct ethhdr eth; /* 802.3 header */
994 u8 encap[6]; /* 802.2 header */
995 } __attribute__ ((packed)) hdr;
996
997 /* Strip destination and source from the data */
998 skb_pull(skb, 2 * ETH_ALEN);
999
1000 /* And move them to a separate header */
1001 memcpy(&hdr.eth, eh, 2 * ETH_ALEN);
1002 hdr.eth.h_proto = htons(sizeof(encaps_hdr) + skb->len);
1003 memcpy(hdr.encap, encaps_hdr, sizeof(encaps_hdr));
1004
1005 /* Insert the SNAP header */
1006 if (skb_headroom(skb) < sizeof(hdr)) {
1007 printk(KERN_ERR
1008 "%s: Not enough headroom for 802.2 headers %d\n",
1009 dev->name, skb_headroom(skb));
1010 goto drop;
1011 }
1012 eh = (struct ethhdr *) skb_push(skb, sizeof(hdr));
1013 memcpy(eh, &hdr, sizeof(hdr));
1014 }
1015
1016 err = hermes_bap_pwrite(hw, USER_BAP, skb->data, skb->len,
1017 txfid, HERMES_802_3_OFFSET);
1018 if (err) {
1019 printk(KERN_ERR "%s: Error %d writing packet to BAP\n",
1020 dev->name, err);
1021 goto busy;
1022 }
1023
1024 /* Calculate Michael MIC */
1025 if (priv->encode_alg == IW_ENCODE_ALG_TKIP) {
1026 u8 mic_buf[MICHAEL_MIC_LEN + 1];
1027 u8 *mic;
1028 size_t offset;
1029 size_t len;
1030
1031 if (skb->len % 2) {
1032 /* MIC start is on an odd boundary */
1033 mic_buf[0] = skb->data[skb->len - 1];
1034 mic = &mic_buf[1];
1035 offset = skb->len - 1;
1036 len = MICHAEL_MIC_LEN + 1;
1037 } else {
1038 mic = &mic_buf[0];
1039 offset = skb->len;
1040 len = MICHAEL_MIC_LEN;
1041 }
1042
1043 michael_mic(priv->tx_tfm_mic,
1044 priv->tkip_key[priv->tx_key].tx_mic,
1045 eh->h_dest, eh->h_source, 0 /* priority */,
1046 skb->data + ETH_HLEN, skb->len - ETH_HLEN, mic);
1047
1048 /* Write the MIC */
1049 err = hermes_bap_pwrite(hw, USER_BAP, &mic_buf[0], len,
1050 txfid, HERMES_802_3_OFFSET + offset);
1051 if (err) {
1052 printk(KERN_ERR "%s: Error %d writing MIC to BAP\n",
1053 dev->name, err);
1054 goto busy;
1055 }
1056 }
1057
1058 /* Finally, we actually initiate the send */
1059 netif_stop_queue(dev);
1060
1061 err = hermes_docmd_wait(hw, HERMES_CMD_TX | HERMES_CMD_RECL,
1062 txfid, NULL);
1063 if (err) {
1064 netif_start_queue(dev);
1065 if (net_ratelimit())
1066 printk(KERN_ERR "%s: Error %d transmitting packet\n",
1067 dev->name, err);
1068 goto busy;
1069 }
1070
1071 dev->trans_start = jiffies;
1072 stats->tx_bytes += HERMES_802_3_OFFSET + skb->len;
1073 goto ok;
1074
1075 drop:
1076 stats->tx_errors++;
1077 stats->tx_dropped++;
1078
1079 ok:
1080 orinoco_unlock(priv, &flags);
1081 dev_kfree_skb(skb);
1082 return NETDEV_TX_OK;
1083
1084 busy:
1085 if (err == -EIO)
1086 schedule_work(&priv->reset_work);
1087 orinoco_unlock(priv, &flags);
1088 return NETDEV_TX_BUSY;
1089}
1090
1091static void __orinoco_ev_alloc(struct net_device *dev, hermes_t *hw)
1092{
1093 struct orinoco_private *priv = netdev_priv(dev);
1094 u16 fid = hermes_read_regn(hw, ALLOCFID);
1095
1096 if (fid != priv->txfid) {
1097 if (fid != DUMMY_FID)
1098 printk(KERN_WARNING "%s: Allocate event on unexpected fid (%04X)\n",
1099 dev->name, fid);
1100 return;
1101 }
1102
1103 hermes_write_regn(hw, ALLOCFID, DUMMY_FID);
1104}
1105
1106static void __orinoco_ev_tx(struct net_device *dev, hermes_t *hw)
1107{
1108 struct orinoco_private *priv = netdev_priv(dev);
1109 struct net_device_stats *stats = &priv->stats;
1110
1111 stats->tx_packets++;
1112
1113 netif_wake_queue(dev);
1114
1115 hermes_write_regn(hw, TXCOMPLFID, DUMMY_FID);
1116}
1117
1118static void __orinoco_ev_txexc(struct net_device *dev, hermes_t *hw)
1119{
1120 struct orinoco_private *priv = netdev_priv(dev);
1121 struct net_device_stats *stats = &priv->stats;
1122 u16 fid = hermes_read_regn(hw, TXCOMPLFID);
1123 u16 status;
1124 struct hermes_txexc_data hdr;
1125 int err = 0;
1126
1127 if (fid == DUMMY_FID)
1128 return; /* Nothing's really happened */
1129
1130 /* Read part of the frame header - we need status and addr1 */
1131 err = hermes_bap_pread(hw, IRQ_BAP, &hdr,
1132 sizeof(struct hermes_txexc_data),
1133 fid, 0);
1134
1135 hermes_write_regn(hw, TXCOMPLFID, DUMMY_FID);
1136 stats->tx_errors++;
1137
1138 if (err) {
1139 printk(KERN_WARNING "%s: Unable to read descriptor on Tx error "
1140 "(FID=%04X error %d)\n",
1141 dev->name, fid, err);
1142 return;
1143 }
1144
1145 DEBUG(1, "%s: Tx error, err %d (FID=%04X)\n", dev->name,
1146 err, fid);
1147
1148 /* We produce a TXDROP event only for retry or lifetime
1149 * exceeded, because that's the only status that really mean
1150 * that this particular node went away.
1151 * Other errors means that *we* screwed up. - Jean II */
1152 status = le16_to_cpu(hdr.desc.status);
1153 if (status & (HERMES_TXSTAT_RETRYERR | HERMES_TXSTAT_AGEDERR)) {
1154 union iwreq_data wrqu;
1155
1156 /* Copy 802.11 dest address.
1157 * We use the 802.11 header because the frame may
1158 * not be 802.3 or may be mangled...
1159 * In Ad-Hoc mode, it will be the node address.
1160 * In managed mode, it will be most likely the AP addr
1161 * User space will figure out how to convert it to
1162 * whatever it needs (IP address or else).
1163 * - Jean II */
1164 memcpy(wrqu.addr.sa_data, hdr.addr1, ETH_ALEN);
1165 wrqu.addr.sa_family = ARPHRD_ETHER;
1166
1167 /* Send event to user space */
1168 wireless_send_event(dev, IWEVTXDROP, &wrqu, NULL);
1169 }
1170
1171 netif_wake_queue(dev);
1172}
1173
1174static void orinoco_tx_timeout(struct net_device *dev)
1175{
1176 struct orinoco_private *priv = netdev_priv(dev);
1177 struct net_device_stats *stats = &priv->stats;
1178 struct hermes *hw = &priv->hw;
1179
1180 printk(KERN_WARNING "%s: Tx timeout! "
1181 "ALLOCFID=%04x, TXCOMPLFID=%04x, EVSTAT=%04x\n",
1182 dev->name, hermes_read_regn(hw, ALLOCFID),
1183 hermes_read_regn(hw, TXCOMPLFID), hermes_read_regn(hw, EVSTAT));
1184
1185 stats->tx_errors++;
1186
1187 schedule_work(&priv->reset_work);
1188}
1189
1190/********************************************************************/
1191/* Rx path (data frames) */
1192/********************************************************************/
1193
1194/* Does the frame have a SNAP header indicating it should be
1195 * de-encapsulated to Ethernet-II? */
1196static inline int is_ethersnap(void *_hdr)
1197{
1198 u8 *hdr = _hdr;
1199
1200 /* We de-encapsulate all packets which, a) have SNAP headers
1201 * (i.e. SSAP=DSAP=0xaa and CTRL=0x3 in the 802.2 LLC header
1202 * and where b) the OUI of the SNAP header is 00:00:00 or
1203 * 00:00:f8 - we need both because different APs appear to use
1204 * different OUIs for some reason */
1205 return (memcmp(hdr, &encaps_hdr, 5) == 0)
1206 && ( (hdr[5] == 0x00) || (hdr[5] == 0xf8) );
1207}
1208
1209static inline void orinoco_spy_gather(struct net_device *dev, u_char *mac,
1210 int level, int noise)
1211{
1212 struct iw_quality wstats;
1213 wstats.level = level - 0x95;
1214 wstats.noise = noise - 0x95;
1215 wstats.qual = (level > noise) ? (level - noise) : 0;
1216 wstats.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
1217 /* Update spy records */
1218 wireless_spy_update(dev, mac, &wstats);
1219}
1220
1221static void orinoco_stat_gather(struct net_device *dev,
1222 struct sk_buff *skb,
1223 struct hermes_rx_descriptor *desc)
1224{
1225 struct orinoco_private *priv = netdev_priv(dev);
1226
1227 /* Using spy support with lots of Rx packets, like in an
1228 * infrastructure (AP), will really slow down everything, because
1229 * the MAC address must be compared to each entry of the spy list.
1230 * If the user really asks for it (set some address in the
1231 * spy list), we do it, but he will pay the price.
1232 * Note that to get here, you need both WIRELESS_SPY
1233 * compiled in AND some addresses in the list !!!
1234 */
1235 /* Note : gcc will optimise the whole section away if
1236 * WIRELESS_SPY is not defined... - Jean II */
1237 if (SPY_NUMBER(priv)) {
1238 orinoco_spy_gather(dev, skb_mac_header(skb) + ETH_ALEN,
1239 desc->signal, desc->silence);
1240 }
1241}
1242
1243/*
1244 * orinoco_rx_monitor - handle received monitor frames.
1245 *
1246 * Arguments:
1247 * dev network device
1248 * rxfid received FID
1249 * desc rx descriptor of the frame
1250 *
1251 * Call context: interrupt
1252 */
1253static void orinoco_rx_monitor(struct net_device *dev, u16 rxfid,
1254 struct hermes_rx_descriptor *desc)
1255{
1256 u32 hdrlen = 30; /* return full header by default */
1257 u32 datalen = 0;
1258 u16 fc;
1259 int err;
1260 int len;
1261 struct sk_buff *skb;
1262 struct orinoco_private *priv = netdev_priv(dev);
1263 struct net_device_stats *stats = &priv->stats;
1264 hermes_t *hw = &priv->hw;
1265
1266 len = le16_to_cpu(desc->data_len);
1267
1268 /* Determine the size of the header and the data */
1269 fc = le16_to_cpu(desc->frame_ctl);
1270 switch (fc & IEEE80211_FCTL_FTYPE) {
1271 case IEEE80211_FTYPE_DATA:
1272 if ((fc & IEEE80211_FCTL_TODS)
1273 && (fc & IEEE80211_FCTL_FROMDS))
1274 hdrlen = 30;
1275 else
1276 hdrlen = 24;
1277 datalen = len;
1278 break;
1279 case IEEE80211_FTYPE_MGMT:
1280 hdrlen = 24;
1281 datalen = len;
1282 break;
1283 case IEEE80211_FTYPE_CTL:
1284 switch (fc & IEEE80211_FCTL_STYPE) {
1285 case IEEE80211_STYPE_PSPOLL:
1286 case IEEE80211_STYPE_RTS:
1287 case IEEE80211_STYPE_CFEND:
1288 case IEEE80211_STYPE_CFENDACK:
1289 hdrlen = 16;
1290 break;
1291 case IEEE80211_STYPE_CTS:
1292 case IEEE80211_STYPE_ACK:
1293 hdrlen = 10;
1294 break;
1295 }
1296 break;
1297 default:
1298 /* Unknown frame type */
1299 break;
1300 }
1301
1302 /* sanity check the length */
1303 if (datalen > IEEE80211_MAX_DATA_LEN + 12) {
1304 printk(KERN_DEBUG "%s: oversized monitor frame, "
1305 "data length = %d\n", dev->name, datalen);
1306 stats->rx_length_errors++;
1307 goto update_stats;
1308 }
1309
1310 skb = dev_alloc_skb(hdrlen + datalen);
1311 if (!skb) {
1312 printk(KERN_WARNING "%s: Cannot allocate skb for monitor frame\n",
1313 dev->name);
1314 goto update_stats;
1315 }
1316
1317 /* Copy the 802.11 header to the skb */
1318 memcpy(skb_put(skb, hdrlen), &(desc->frame_ctl), hdrlen);
1319 skb_reset_mac_header(skb);
1320
1321 /* If any, copy the data from the card to the skb */
1322 if (datalen > 0) {
1323 err = hermes_bap_pread(hw, IRQ_BAP, skb_put(skb, datalen),
1324 ALIGN(datalen, 2), rxfid,
1325 HERMES_802_2_OFFSET);
1326 if (err) {
1327 printk(KERN_ERR "%s: error %d reading monitor frame\n",
1328 dev->name, err);
1329 goto drop;
1330 }
1331 }
1332
1333 skb->dev = dev;
1334 skb->ip_summed = CHECKSUM_NONE;
1335 skb->pkt_type = PACKET_OTHERHOST;
1336 skb->protocol = cpu_to_be16(ETH_P_802_2);
1337
1338 stats->rx_packets++;
1339 stats->rx_bytes += skb->len;
1340
1341 netif_rx(skb);
1342 return;
1343
1344 drop:
1345 dev_kfree_skb_irq(skb);
1346 update_stats:
1347 stats->rx_errors++;
1348 stats->rx_dropped++;
1349}
1350
1351/* Get tsc from the firmware */
1352static int orinoco_hw_get_tkip_iv(struct orinoco_private *priv, int key,
1353 u8 *tsc)
1354{
1355 hermes_t *hw = &priv->hw;
1356 int err = 0;
1357 u8 tsc_arr[4][IW_ENCODE_SEQ_MAX_SIZE];
1358
1359 if ((key < 0) || (key > 4))
1360 return -EINVAL;
1361
1362 err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CURRENT_TKIP_IV,
1363 sizeof(tsc_arr), NULL, &tsc_arr);
1364 if (!err)
1365 memcpy(tsc, &tsc_arr[key][0], sizeof(tsc_arr[0]));
1366
1367 return err;
1368}
1369
1370static void __orinoco_ev_rx(struct net_device *dev, hermes_t *hw)
1371{
1372 struct orinoco_private *priv = netdev_priv(dev);
1373 struct net_device_stats *stats = &priv->stats;
1374 struct iw_statistics *wstats = &priv->wstats;
1375 struct sk_buff *skb = NULL;
1376 u16 rxfid, status;
1377 int length;
1378 struct hermes_rx_descriptor *desc;
1379 struct orinoco_rx_data *rx_data;
1380 int err;
1381
1382 desc = kmalloc(sizeof(*desc), GFP_ATOMIC);
1383 if (!desc) {
1384 printk(KERN_WARNING
1385 "%s: Can't allocate space for RX descriptor\n",
1386 dev->name);
1387 goto update_stats;
1388 }
1389
1390 rxfid = hermes_read_regn(hw, RXFID);
1391
1392 err = hermes_bap_pread(hw, IRQ_BAP, desc, sizeof(*desc),
1393 rxfid, 0);
1394 if (err) {
1395 printk(KERN_ERR "%s: error %d reading Rx descriptor. "
1396 "Frame dropped.\n", dev->name, err);
1397 goto update_stats;
1398 }
1399
1400 status = le16_to_cpu(desc->status);
1401
1402 if (status & HERMES_RXSTAT_BADCRC) {
1403 DEBUG(1, "%s: Bad CRC on Rx. Frame dropped.\n",
1404 dev->name);
1405 stats->rx_crc_errors++;
1406 goto update_stats;
1407 }
1408
1409 /* Handle frames in monitor mode */
1410 if (priv->iw_mode == IW_MODE_MONITOR) {
1411 orinoco_rx_monitor(dev, rxfid, desc);
1412 goto out;
1413 }
1414
1415 if (status & HERMES_RXSTAT_UNDECRYPTABLE) {
1416 DEBUG(1, "%s: Undecryptable frame on Rx. Frame dropped.\n",
1417 dev->name);
1418 wstats->discard.code++;
1419 goto update_stats;
1420 }
1421
1422 length = le16_to_cpu(desc->data_len);
1423
1424 /* Sanity checks */
1425 if (length < 3) { /* No for even an 802.2 LLC header */
1426 /* At least on Symbol firmware with PCF we get quite a
1427 lot of these legitimately - Poll frames with no
1428 data. */
1429 goto out;
1430 }
1431 if (length > IEEE80211_MAX_DATA_LEN) {
1432 printk(KERN_WARNING "%s: Oversized frame received (%d bytes)\n",
1433 dev->name, length);
1434 stats->rx_length_errors++;
1435 goto update_stats;
1436 }
1437
1438 /* Payload size does not include Michael MIC. Increase payload
1439 * size to read it together with the data. */
1440 if (status & HERMES_RXSTAT_MIC)
1441 length += MICHAEL_MIC_LEN;
1442
1443 /* We need space for the packet data itself, plus an ethernet
1444 header, plus 2 bytes so we can align the IP header on a
1445 32bit boundary, plus 1 byte so we can read in odd length
1446 packets from the card, which has an IO granularity of 16
1447 bits */
1448 skb = dev_alloc_skb(length+ETH_HLEN+2+1);
1449 if (!skb) {
1450 printk(KERN_WARNING "%s: Can't allocate skb for Rx\n",
1451 dev->name);
1452 goto update_stats;
1453 }
1454
1455 /* We'll prepend the header, so reserve space for it. The worst
1456 case is no decapsulation, when 802.3 header is prepended and
1457 nothing is removed. 2 is for aligning the IP header. */
1458 skb_reserve(skb, ETH_HLEN + 2);
1459
1460 err = hermes_bap_pread(hw, IRQ_BAP, skb_put(skb, length),
1461 ALIGN(length, 2), rxfid,
1462 HERMES_802_2_OFFSET);
1463 if (err) {
1464 printk(KERN_ERR "%s: error %d reading frame. "
1465 "Frame dropped.\n", dev->name, err);
1466 goto drop;
1467 }
1468
1469 /* Add desc and skb to rx queue */
1470 rx_data = kzalloc(sizeof(*rx_data), GFP_ATOMIC);
1471 if (!rx_data) {
1472 printk(KERN_WARNING "%s: Can't allocate RX packet\n",
1473 dev->name);
1474 goto drop;
1475 }
1476 rx_data->desc = desc;
1477 rx_data->skb = skb;
1478 list_add_tail(&rx_data->list, &priv->rx_list);
1479 tasklet_schedule(&priv->rx_tasklet);
1480
1481 return;
1482
1483drop:
1484 dev_kfree_skb_irq(skb);
1485update_stats:
1486 stats->rx_errors++;
1487 stats->rx_dropped++;
1488out:
1489 kfree(desc);
1490}
1491
1492static void orinoco_rx(struct net_device *dev,
1493 struct hermes_rx_descriptor *desc,
1494 struct sk_buff *skb)
1495{
1496 struct orinoco_private *priv = netdev_priv(dev);
1497 struct net_device_stats *stats = &priv->stats;
1498 u16 status, fc;
1499 int length;
1500 struct ethhdr *hdr;
1501
1502 status = le16_to_cpu(desc->status);
1503 length = le16_to_cpu(desc->data_len);
1504 fc = le16_to_cpu(desc->frame_ctl);
1505
1506 /* Calculate and check MIC */
1507 if (status & HERMES_RXSTAT_MIC) {
1508 int key_id = ((status & HERMES_RXSTAT_MIC_KEY_ID) >>
1509 HERMES_MIC_KEY_ID_SHIFT);
1510 u8 mic[MICHAEL_MIC_LEN];
1511 u8 *rxmic;
1512 u8 *src = (fc & IEEE80211_FCTL_FROMDS) ?
1513 desc->addr3 : desc->addr2;
1514
1515 /* Extract Michael MIC from payload */
1516 rxmic = skb->data + skb->len - MICHAEL_MIC_LEN;
1517
1518 skb_trim(skb, skb->len - MICHAEL_MIC_LEN);
1519 length -= MICHAEL_MIC_LEN;
1520
1521 michael_mic(priv->rx_tfm_mic,
1522 priv->tkip_key[key_id].rx_mic,
1523 desc->addr1,
1524 src,
1525 0, /* priority or QoS? */
1526 skb->data,
1527 skb->len,
1528 &mic[0]);
1529
1530 if (memcmp(mic, rxmic,
1531 MICHAEL_MIC_LEN)) {
1532 union iwreq_data wrqu;
1533 struct iw_michaelmicfailure wxmic;
1534
1535 printk(KERN_WARNING "%s: "
1536 "Invalid Michael MIC in data frame from %pM, "
1537 "using key %i\n",
1538 dev->name, src, key_id);
1539
1540 /* TODO: update stats */
1541
1542 /* Notify userspace */
1543 memset(&wxmic, 0, sizeof(wxmic));
1544 wxmic.flags = key_id & IW_MICFAILURE_KEY_ID;
1545 wxmic.flags |= (desc->addr1[0] & 1) ?
1546 IW_MICFAILURE_GROUP : IW_MICFAILURE_PAIRWISE;
1547 wxmic.src_addr.sa_family = ARPHRD_ETHER;
1548 memcpy(wxmic.src_addr.sa_data, src, ETH_ALEN);
1549
1550 (void) orinoco_hw_get_tkip_iv(priv, key_id,
1551 &wxmic.tsc[0]);
1552
1553 memset(&wrqu, 0, sizeof(wrqu));
1554 wrqu.data.length = sizeof(wxmic);
1555 wireless_send_event(dev, IWEVMICHAELMICFAILURE, &wrqu,
1556 (char *) &wxmic);
1557
1558 goto drop;
1559 }
1560 }
1561
1562 /* Handle decapsulation
1563 * In most cases, the firmware tell us about SNAP frames.
1564 * For some reason, the SNAP frames sent by LinkSys APs
1565 * are not properly recognised by most firmwares.
1566 * So, check ourselves */
1567 if (length >= ENCAPS_OVERHEAD &&
1568 (((status & HERMES_RXSTAT_MSGTYPE) == HERMES_RXSTAT_1042) ||
1569 ((status & HERMES_RXSTAT_MSGTYPE) == HERMES_RXSTAT_TUNNEL) ||
1570 is_ethersnap(skb->data))) {
1571 /* These indicate a SNAP within 802.2 LLC within
1572 802.11 frame which we'll need to de-encapsulate to
1573 the original EthernetII frame. */
1574 hdr = (struct ethhdr *)skb_push(skb, ETH_HLEN - ENCAPS_OVERHEAD);
1575 } else {
1576 /* 802.3 frame - prepend 802.3 header as is */
1577 hdr = (struct ethhdr *)skb_push(skb, ETH_HLEN);
1578 hdr->h_proto = htons(length);
1579 }
1580 memcpy(hdr->h_dest, desc->addr1, ETH_ALEN);
1581 if (fc & IEEE80211_FCTL_FROMDS)
1582 memcpy(hdr->h_source, desc->addr3, ETH_ALEN);
1583 else
1584 memcpy(hdr->h_source, desc->addr2, ETH_ALEN);
1585
1586 skb->protocol = eth_type_trans(skb, dev);
1587 skb->ip_summed = CHECKSUM_NONE;
1588 if (fc & IEEE80211_FCTL_TODS)
1589 skb->pkt_type = PACKET_OTHERHOST;
1590
1591 /* Process the wireless stats if needed */
1592 orinoco_stat_gather(dev, skb, desc);
1593
1594 /* Pass the packet to the networking stack */
1595 netif_rx(skb);
1596 stats->rx_packets++;
1597 stats->rx_bytes += length;
1598
1599 return;
1600
1601 drop:
1602 dev_kfree_skb(skb);
1603 stats->rx_errors++;
1604 stats->rx_dropped++;
1605}
1606
1607static void orinoco_rx_isr_tasklet(unsigned long data)
1608{
1609 struct net_device *dev = (struct net_device *) data;
1610 struct orinoco_private *priv = netdev_priv(dev);
1611 struct orinoco_rx_data *rx_data, *temp;
1612 struct hermes_rx_descriptor *desc;
1613 struct sk_buff *skb;
1614 unsigned long flags;
1615
1616 /* orinoco_rx requires the driver lock, and we also need to
1617 * protect priv->rx_list, so just hold the lock over the
1618 * lot.
1619 *
1620 * If orinoco_lock fails, we've unplugged the card. In this
1621 * case just abort. */
1622 if (orinoco_lock(priv, &flags) != 0)
1623 return;
1624
1625 /* extract desc and skb from queue */
1626 list_for_each_entry_safe(rx_data, temp, &priv->rx_list, list) {
1627 desc = rx_data->desc;
1628 skb = rx_data->skb;
1629 list_del(&rx_data->list);
1630 kfree(rx_data);
1631
1632 orinoco_rx(dev, desc, skb);
1633
1634 kfree(desc);
1635 }
1636
1637 orinoco_unlock(priv, &flags);
1638}
1639
1640/********************************************************************/
1641/* Rx path (info frames) */
1642/********************************************************************/
1643
1644static void print_linkstatus(struct net_device *dev, u16 status)
1645{
1646 char * s;
1647
1648 if (suppress_linkstatus)
1649 return;
1650
1651 switch (status) {
1652 case HERMES_LINKSTATUS_NOT_CONNECTED:
1653 s = "Not Connected";
1654 break;
1655 case HERMES_LINKSTATUS_CONNECTED:
1656 s = "Connected";
1657 break;
1658 case HERMES_LINKSTATUS_DISCONNECTED:
1659 s = "Disconnected";
1660 break;
1661 case HERMES_LINKSTATUS_AP_CHANGE:
1662 s = "AP Changed";
1663 break;
1664 case HERMES_LINKSTATUS_AP_OUT_OF_RANGE:
1665 s = "AP Out of Range";
1666 break;
1667 case HERMES_LINKSTATUS_AP_IN_RANGE:
1668 s = "AP In Range";
1669 break;
1670 case HERMES_LINKSTATUS_ASSOC_FAILED:
1671 s = "Association Failed";
1672 break;
1673 default:
1674 s = "UNKNOWN";
1675 }
1676
1677 printk(KERN_DEBUG "%s: New link status: %s (%04x)\n",
1678 dev->name, s, status);
1679}
1680
1681/* Search scan results for requested BSSID, join it if found */
1682static void orinoco_join_ap(struct work_struct *work)
1683{
1684 struct orinoco_private *priv =
1685 container_of(work, struct orinoco_private, join_work);
1686 struct net_device *dev = priv->ndev;
1687 struct hermes *hw = &priv->hw;
1688 int err;
1689 unsigned long flags;
1690 struct join_req {
1691 u8 bssid[ETH_ALEN];
1692 __le16 channel;
1693 } __attribute__ ((packed)) req;
1694 const int atom_len = offsetof(struct prism2_scan_apinfo, atim);
1695 struct prism2_scan_apinfo *atom = NULL;
1696 int offset = 4;
1697 int found = 0;
1698 u8 *buf;
1699 u16 len;
1700
1701 /* Allocate buffer for scan results */
1702 buf = kmalloc(MAX_SCAN_LEN, GFP_KERNEL);
1703 if (! buf)
1704 return;
1705
1706 if (orinoco_lock(priv, &flags) != 0)
1707 goto fail_lock;
1708
1709 /* Sanity checks in case user changed something in the meantime */
1710 if (! priv->bssid_fixed)
1711 goto out;
1712
1713 if (strlen(priv->desired_essid) == 0)
1714 goto out;
1715
1716 /* Read scan results from the firmware */
1717 err = hermes_read_ltv(hw, USER_BAP,
1718 HERMES_RID_SCANRESULTSTABLE,
1719 MAX_SCAN_LEN, &len, buf);
1720 if (err) {
1721 printk(KERN_ERR "%s: Cannot read scan results\n",
1722 dev->name);
1723 goto out;
1724 }
1725
1726 len = HERMES_RECLEN_TO_BYTES(len);
1727
1728 /* Go through the scan results looking for the channel of the AP
1729 * we were requested to join */
1730 for (; offset + atom_len <= len; offset += atom_len) {
1731 atom = (struct prism2_scan_apinfo *) (buf + offset);
1732 if (memcmp(&atom->bssid, priv->desired_bssid, ETH_ALEN) == 0) {
1733 found = 1;
1734 break;
1735 }
1736 }
1737
1738 if (! found) {
1739 DEBUG(1, "%s: Requested AP not found in scan results\n",
1740 dev->name);
1741 goto out;
1742 }
1743
1744 memcpy(req.bssid, priv->desired_bssid, ETH_ALEN);
1745 req.channel = atom->channel; /* both are little-endian */
1746 err = HERMES_WRITE_RECORD(hw, USER_BAP, HERMES_RID_CNFJOINREQUEST,
1747 &req);
1748 if (err)
1749 printk(KERN_ERR "%s: Error issuing join request\n", dev->name);
1750
1751 out:
1752 orinoco_unlock(priv, &flags);
1753
1754 fail_lock:
1755 kfree(buf);
1756}
1757
1758/* Send new BSSID to userspace */
1759static void orinoco_send_bssid_wevent(struct orinoco_private *priv)
1760{
1761 struct net_device *dev = priv->ndev;
1762 struct hermes *hw = &priv->hw;
1763 union iwreq_data wrqu;
1764 int err;
1765
1766 err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CURRENTBSSID,
1767 ETH_ALEN, NULL, wrqu.ap_addr.sa_data);
1768 if (err != 0)
1769 return;
1770
1771 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
1772
1773 /* Send event to user space */
1774 wireless_send_event(dev, SIOCGIWAP, &wrqu, NULL);
1775}
1776
1777static void orinoco_send_assocreqie_wevent(struct orinoco_private *priv)
1778{
1779 struct net_device *dev = priv->ndev;
1780 struct hermes *hw = &priv->hw;
1781 union iwreq_data wrqu;
1782 int err;
1783 u8 buf[88];
1784 u8 *ie;
1785
1786 if (!priv->has_wpa)
1787 return;
1788
1789 err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CURRENT_ASSOC_REQ_INFO,
1790 sizeof(buf), NULL, &buf);
1791 if (err != 0)
1792 return;
1793
1794 ie = orinoco_get_wpa_ie(buf, sizeof(buf));
1795 if (ie) {
1796 int rem = sizeof(buf) - (ie - &buf[0]);
1797 wrqu.data.length = ie[1] + 2;
1798 if (wrqu.data.length > rem)
1799 wrqu.data.length = rem;
1800
1801 if (wrqu.data.length)
1802 /* Send event to user space */
1803 wireless_send_event(dev, IWEVASSOCREQIE, &wrqu, ie);
1804 }
1805}
1806
1807static void orinoco_send_assocrespie_wevent(struct orinoco_private *priv)
1808{
1809 struct net_device *dev = priv->ndev;
1810 struct hermes *hw = &priv->hw;
1811 union iwreq_data wrqu;
1812 int err;
1813 u8 buf[88]; /* TODO: verify max size or IW_GENERIC_IE_MAX */
1814 u8 *ie;
1815
1816 if (!priv->has_wpa)
1817 return;
1818
1819 err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CURRENT_ASSOC_RESP_INFO,
1820 sizeof(buf), NULL, &buf);
1821 if (err != 0)
1822 return;
1823
1824 ie = orinoco_get_wpa_ie(buf, sizeof(buf));
1825 if (ie) {
1826 int rem = sizeof(buf) - (ie - &buf[0]);
1827 wrqu.data.length = ie[1] + 2;
1828 if (wrqu.data.length > rem)
1829 wrqu.data.length = rem;
1830
1831 if (wrqu.data.length)
1832 /* Send event to user space */
1833 wireless_send_event(dev, IWEVASSOCRESPIE, &wrqu, ie);
1834 }
1835}
1836
1837static void orinoco_send_wevents(struct work_struct *work)
1838{
1839 struct orinoco_private *priv =
1840 container_of(work, struct orinoco_private, wevent_work);
1841 unsigned long flags;
1842
1843 if (orinoco_lock(priv, &flags) != 0)
1844 return;
1845
1846 orinoco_send_assocreqie_wevent(priv);
1847 orinoco_send_assocrespie_wevent(priv);
1848 orinoco_send_bssid_wevent(priv);
1849
1850 orinoco_unlock(priv, &flags);
1851}
1852
1853static inline void orinoco_clear_scan_results(struct orinoco_private *priv,
1854 unsigned long scan_age)
1855{
1856 if (priv->has_ext_scan) {
1857 struct xbss_element *bss;
1858 struct xbss_element *tmp_bss;
1859
1860 /* Blow away current list of scan results */
1861 list_for_each_entry_safe(bss, tmp_bss, &priv->bss_list, list) {
1862 if (!scan_age ||
1863 time_after(jiffies, bss->last_scanned + scan_age)) {
1864 list_move_tail(&bss->list,
1865 &priv->bss_free_list);
1866 /* Don't blow away ->list, just BSS data */
1867 memset(&bss->bss, 0, sizeof(bss->bss));
1868 bss->last_scanned = 0;
1869 }
1870 }
1871 } else {
1872 struct bss_element *bss;
1873 struct bss_element *tmp_bss;
1874
1875 /* Blow away current list of scan results */
1876 list_for_each_entry_safe(bss, tmp_bss, &priv->bss_list, list) {
1877 if (!scan_age ||
1878 time_after(jiffies, bss->last_scanned + scan_age)) {
1879 list_move_tail(&bss->list,
1880 &priv->bss_free_list);
1881 /* Don't blow away ->list, just BSS data */
1882 memset(&bss->bss, 0, sizeof(bss->bss));
1883 bss->last_scanned = 0;
1884 }
1885 }
1886 }
1887}
1888
1889static void orinoco_add_ext_scan_result(struct orinoco_private *priv,
1890 struct agere_ext_scan_info *atom)
1891{
1892 struct xbss_element *bss = NULL;
1893 int found = 0;
1894
1895 /* Try to update an existing bss first */
1896 list_for_each_entry(bss, &priv->bss_list, list) {
1897 if (compare_ether_addr(bss->bss.bssid, atom->bssid))
1898 continue;
1899 /* ESSID lengths */
1900 if (bss->bss.data[1] != atom->data[1])
1901 continue;
1902 if (memcmp(&bss->bss.data[2], &atom->data[2],
1903 atom->data[1]))
1904 continue;
1905 found = 1;
1906 break;
1907 }
1908
1909 /* Grab a bss off the free list */
1910 if (!found && !list_empty(&priv->bss_free_list)) {
1911 bss = list_entry(priv->bss_free_list.next,
1912 struct xbss_element, list);
1913 list_del(priv->bss_free_list.next);
1914
1915 list_add_tail(&bss->list, &priv->bss_list);
1916 }
1917
1918 if (bss) {
1919 /* Always update the BSS to get latest beacon info */
1920 memcpy(&bss->bss, atom, sizeof(bss->bss));
1921 bss->last_scanned = jiffies;
1922 }
1923}
1924
1925static int orinoco_process_scan_results(struct net_device *dev,
1926 unsigned char *buf,
1927 int len)
1928{
1929 struct orinoco_private *priv = netdev_priv(dev);
1930 int offset; /* In the scan data */
1931 union hermes_scan_info *atom;
1932 int atom_len;
1933
1934 switch (priv->firmware_type) {
1935 case FIRMWARE_TYPE_AGERE:
1936 atom_len = sizeof(struct agere_scan_apinfo);
1937 offset = 0;
1938 break;
1939 case FIRMWARE_TYPE_SYMBOL:
1940 /* Lack of documentation necessitates this hack.
1941 * Different firmwares have 68 or 76 byte long atoms.
1942 * We try modulo first. If the length divides by both,
1943 * we check what would be the channel in the second
1944 * frame for a 68-byte atom. 76-byte atoms have 0 there.
1945 * Valid channel cannot be 0. */
1946 if (len % 76)
1947 atom_len = 68;
1948 else if (len % 68)
1949 atom_len = 76;
1950 else if (len >= 1292 && buf[68] == 0)
1951 atom_len = 76;
1952 else
1953 atom_len = 68;
1954 offset = 0;
1955 break;
1956 case FIRMWARE_TYPE_INTERSIL:
1957 offset = 4;
1958 if (priv->has_hostscan) {
1959 atom_len = le16_to_cpup((__le16 *)buf);
1960 /* Sanity check for atom_len */
1961 if (atom_len < sizeof(struct prism2_scan_apinfo)) {
1962 printk(KERN_ERR "%s: Invalid atom_len in scan "
1963 "data: %d\n", dev->name, atom_len);
1964 return -EIO;
1965 }
1966 } else
1967 atom_len = offsetof(struct prism2_scan_apinfo, atim);
1968 break;
1969 default:
1970 return -EOPNOTSUPP;
1971 }
1972
1973 /* Check that we got an whole number of atoms */
1974 if ((len - offset) % atom_len) {
1975 printk(KERN_ERR "%s: Unexpected scan data length %d, "
1976 "atom_len %d, offset %d\n", dev->name, len,
1977 atom_len, offset);
1978 return -EIO;
1979 }
1980
1981 orinoco_clear_scan_results(priv, msecs_to_jiffies(15000));
1982
1983 /* Read the entries one by one */
1984 for (; offset + atom_len <= len; offset += atom_len) {
1985 int found = 0;
1986 struct bss_element *bss = NULL;
1987
1988 /* Get next atom */
1989 atom = (union hermes_scan_info *) (buf + offset);
1990
1991 /* Try to update an existing bss first */
1992 list_for_each_entry(bss, &priv->bss_list, list) {
1993 if (compare_ether_addr(bss->bss.a.bssid, atom->a.bssid))
1994 continue;
1995 if (le16_to_cpu(bss->bss.a.essid_len) !=
1996 le16_to_cpu(atom->a.essid_len))
1997 continue;
1998 if (memcmp(bss->bss.a.essid, atom->a.essid,
1999 le16_to_cpu(atom->a.essid_len)))
2000 continue;
2001 found = 1;
2002 break;
2003 }
2004
2005 /* Grab a bss off the free list */
2006 if (!found && !list_empty(&priv->bss_free_list)) {
2007 bss = list_entry(priv->bss_free_list.next,
2008 struct bss_element, list);
2009 list_del(priv->bss_free_list.next);
2010
2011 list_add_tail(&bss->list, &priv->bss_list);
2012 }
2013
2014 if (bss) {
2015 /* Always update the BSS to get latest beacon info */
2016 memcpy(&bss->bss, atom, sizeof(bss->bss));
2017 bss->last_scanned = jiffies;
2018 }
2019 }
2020
2021 return 0;
2022}
2023
2024static void __orinoco_ev_info(struct net_device *dev, hermes_t *hw)
2025{
2026 struct orinoco_private *priv = netdev_priv(dev);
2027 u16 infofid;
2028 struct {
2029 __le16 len;
2030 __le16 type;
2031 } __attribute__ ((packed)) info;
2032 int len, type;
2033 int err;
2034
2035 /* This is an answer to an INQUIRE command that we did earlier,
2036 * or an information "event" generated by the card
2037 * The controller return to us a pseudo frame containing
2038 * the information in question - Jean II */
2039 infofid = hermes_read_regn(hw, INFOFID);
2040
2041 /* Read the info frame header - don't try too hard */
2042 err = hermes_bap_pread(hw, IRQ_BAP, &info, sizeof(info),
2043 infofid, 0);
2044 if (err) {
2045 printk(KERN_ERR "%s: error %d reading info frame. "
2046 "Frame dropped.\n", dev->name, err);
2047 return;
2048 }
2049
2050 len = HERMES_RECLEN_TO_BYTES(le16_to_cpu(info.len));
2051 type = le16_to_cpu(info.type);
2052
2053 switch (type) {
2054 case HERMES_INQ_TALLIES: {
2055 struct hermes_tallies_frame tallies;
2056 struct iw_statistics *wstats = &priv->wstats;
2057
2058 if (len > sizeof(tallies)) {
2059 printk(KERN_WARNING "%s: Tallies frame too long (%d bytes)\n",
2060 dev->name, len);
2061 len = sizeof(tallies);
2062 }
2063
2064 err = hermes_bap_pread(hw, IRQ_BAP, &tallies, len,
2065 infofid, sizeof(info));
2066 if (err)
2067 break;
2068
2069 /* Increment our various counters */
2070 /* wstats->discard.nwid - no wrong BSSID stuff */
2071 wstats->discard.code +=
2072 le16_to_cpu(tallies.RxWEPUndecryptable);
2073 if (len == sizeof(tallies))
2074 wstats->discard.code +=
2075 le16_to_cpu(tallies.RxDiscards_WEPICVError) +
2076 le16_to_cpu(tallies.RxDiscards_WEPExcluded);
2077 wstats->discard.misc +=
2078 le16_to_cpu(tallies.TxDiscardsWrongSA);
2079 wstats->discard.fragment +=
2080 le16_to_cpu(tallies.RxMsgInBadMsgFragments);
2081 wstats->discard.retries +=
2082 le16_to_cpu(tallies.TxRetryLimitExceeded);
2083 /* wstats->miss.beacon - no match */
2084 }
2085 break;
2086 case HERMES_INQ_LINKSTATUS: {
2087 struct hermes_linkstatus linkstatus;
2088 u16 newstatus;
2089 int connected;
2090
2091 if (priv->iw_mode == IW_MODE_MONITOR)
2092 break;
2093
2094 if (len != sizeof(linkstatus)) {
2095 printk(KERN_WARNING "%s: Unexpected size for linkstatus frame (%d bytes)\n",
2096 dev->name, len);
2097 break;
2098 }
2099
2100 err = hermes_bap_pread(hw, IRQ_BAP, &linkstatus, len,
2101 infofid, sizeof(info));
2102 if (err)
2103 break;
2104 newstatus = le16_to_cpu(linkstatus.linkstatus);
2105
2106 /* Symbol firmware uses "out of range" to signal that
2107 * the hostscan frame can be requested. */
2108 if (newstatus == HERMES_LINKSTATUS_AP_OUT_OF_RANGE &&
2109 priv->firmware_type == FIRMWARE_TYPE_SYMBOL &&
2110 priv->has_hostscan && priv->scan_inprogress) {
2111 hermes_inquire(hw, HERMES_INQ_HOSTSCAN_SYMBOL);
2112 break;
2113 }
2114
2115 connected = (newstatus == HERMES_LINKSTATUS_CONNECTED)
2116 || (newstatus == HERMES_LINKSTATUS_AP_CHANGE)
2117 || (newstatus == HERMES_LINKSTATUS_AP_IN_RANGE);
2118
2119 if (connected)
2120 netif_carrier_on(dev);
2121 else if (!ignore_disconnect)
2122 netif_carrier_off(dev);
2123
2124 if (newstatus != priv->last_linkstatus) {
2125 priv->last_linkstatus = newstatus;
2126 print_linkstatus(dev, newstatus);
2127 /* The info frame contains only one word which is the
2128 * status (see hermes.h). The status is pretty boring
2129 * in itself, that's why we export the new BSSID...
2130 * Jean II */
2131 schedule_work(&priv->wevent_work);
2132 }
2133 }
2134 break;
2135 case HERMES_INQ_SCAN:
2136 if (!priv->scan_inprogress && priv->bssid_fixed &&
2137 priv->firmware_type == FIRMWARE_TYPE_INTERSIL) {
2138 schedule_work(&priv->join_work);
2139 break;
2140 }
2141 /* fall through */
2142 case HERMES_INQ_HOSTSCAN:
2143 case HERMES_INQ_HOSTSCAN_SYMBOL: {
2144 /* Result of a scanning. Contains information about
2145 * cells in the vicinity - Jean II */
2146 union iwreq_data wrqu;
2147 unsigned char *buf;
2148
2149 /* Scan is no longer in progress */
2150 priv->scan_inprogress = 0;
2151
2152 /* Sanity check */
2153 if (len > 4096) {
2154 printk(KERN_WARNING "%s: Scan results too large (%d bytes)\n",
2155 dev->name, len);
2156 break;
2157 }
2158
2159 /* Allocate buffer for results */
2160 buf = kmalloc(len, GFP_ATOMIC);
2161 if (buf == NULL)
2162 /* No memory, so can't printk()... */
2163 break;
2164
2165 /* Read scan data */
2166 err = hermes_bap_pread(hw, IRQ_BAP, (void *) buf, len,
2167 infofid, sizeof(info));
2168 if (err) {
2169 kfree(buf);
2170 break;
2171 }
2172
2173#ifdef ORINOCO_DEBUG
2174 {
2175 int i;
2176 printk(KERN_DEBUG "Scan result [%02X", buf[0]);
2177 for(i = 1; i < (len * 2); i++)
2178 printk(":%02X", buf[i]);
2179 printk("]\n");
2180 }
2181#endif /* ORINOCO_DEBUG */
2182
2183 if (orinoco_process_scan_results(dev, buf, len) == 0) {
2184 /* Send an empty event to user space.
2185 * We don't send the received data on the event because
2186 * it would require us to do complex transcoding, and
2187 * we want to minimise the work done in the irq handler
2188 * Use a request to extract the data - Jean II */
2189 wrqu.data.length = 0;
2190 wrqu.data.flags = 0;
2191 wireless_send_event(dev, SIOCGIWSCAN, &wrqu, NULL);
2192 }
2193 kfree(buf);
2194 }
2195 break;
2196 case HERMES_INQ_CHANNELINFO:
2197 {
2198 struct agere_ext_scan_info *bss;
2199
2200 if (!priv->scan_inprogress) {
2201 printk(KERN_DEBUG "%s: Got chaninfo without scan, "
2202 "len=%d\n", dev->name, len);
2203 break;
2204 }
2205
2206 /* An empty result indicates that the scan is complete */
2207 if (len == 0) {
2208 union iwreq_data wrqu;
2209
2210 /* Scan is no longer in progress */
2211 priv->scan_inprogress = 0;
2212
2213 wrqu.data.length = 0;
2214 wrqu.data.flags = 0;
2215 wireless_send_event(dev, SIOCGIWSCAN, &wrqu, NULL);
2216 break;
2217 }
2218
2219 /* Sanity check */
2220 else if (len > sizeof(*bss)) {
2221 printk(KERN_WARNING
2222 "%s: Ext scan results too large (%d bytes). "
2223 "Truncating results to %zd bytes.\n",
2224 dev->name, len, sizeof(*bss));
2225 len = sizeof(*bss);
2226 } else if (len < (offsetof(struct agere_ext_scan_info,
2227 data) + 2)) {
2228 /* Drop this result now so we don't have to
2229 * keep checking later */
2230 printk(KERN_WARNING
2231 "%s: Ext scan results too short (%d bytes)\n",
2232 dev->name, len);
2233 break;
2234 }
2235
2236 bss = kmalloc(sizeof(*bss), GFP_ATOMIC);
2237 if (bss == NULL)
2238 break;
2239
2240 /* Read scan data */
2241 err = hermes_bap_pread(hw, IRQ_BAP, (void *) bss, len,
2242 infofid, sizeof(info));
2243 if (err) {
2244 kfree(bss);
2245 break;
2246 }
2247
2248 orinoco_add_ext_scan_result(priv, bss);
2249
2250 kfree(bss);
2251 break;
2252 }
2253 case HERMES_INQ_SEC_STAT_AGERE:
2254 /* Security status (Agere specific) */
2255 /* Ignore this frame for now */
2256 if (priv->firmware_type == FIRMWARE_TYPE_AGERE)
2257 break;
2258 /* fall through */
2259 default:
2260 printk(KERN_DEBUG "%s: Unknown information frame received: "
2261 "type 0x%04x, length %d\n", dev->name, type, len);
2262 /* We don't actually do anything about it */
2263 break;
2264 }
2265}
2266
2267static void __orinoco_ev_infdrop(struct net_device *dev, hermes_t *hw)
2268{
2269 if (net_ratelimit())
2270 printk(KERN_DEBUG "%s: Information frame lost.\n", dev->name);
2271}
2272
2273/********************************************************************/
2274/* Internal hardware control routines */
2275/********************************************************************/
2276
2277int __orinoco_up(struct net_device *dev)
2278{
2279 struct orinoco_private *priv = netdev_priv(dev);
2280 struct hermes *hw = &priv->hw;
2281 int err;
2282
2283 netif_carrier_off(dev); /* just to make sure */
2284
2285 err = __orinoco_program_rids(dev);
2286 if (err) {
2287 printk(KERN_ERR "%s: Error %d configuring card\n",
2288 dev->name, err);
2289 return err;
2290 }
2291
2292 /* Fire things up again */
2293 hermes_set_irqmask(hw, ORINOCO_INTEN);
2294 err = hermes_enable_port(hw, 0);
2295 if (err) {
2296 printk(KERN_ERR "%s: Error %d enabling MAC port\n",
2297 dev->name, err);
2298 return err;
2299 }
2300
2301 netif_start_queue(dev);
2302
2303 return 0;
2304}
2305
2306int __orinoco_down(struct net_device *dev)
2307{
2308 struct orinoco_private *priv = netdev_priv(dev);
2309 struct hermes *hw = &priv->hw;
2310 int err;
2311
2312 netif_stop_queue(dev);
2313
2314 if (! priv->hw_unavailable) {
2315 if (! priv->broken_disableport) {
2316 err = hermes_disable_port(hw, 0);
2317 if (err) {
2318 /* Some firmwares (e.g. Intersil 1.3.x) seem
2319 * to have problems disabling the port, oh
2320 * well, too bad. */
2321 printk(KERN_WARNING "%s: Error %d disabling MAC port\n",
2322 dev->name, err);
2323 priv->broken_disableport = 1;
2324 }
2325 }
2326 hermes_set_irqmask(hw, 0);
2327 hermes_write_regn(hw, EVACK, 0xffff);
2328 }
2329
2330 /* firmware will have to reassociate */
2331 netif_carrier_off(dev);
2332 priv->last_linkstatus = 0xffff;
2333
2334 return 0;
2335}
2336
2337static int orinoco_allocate_fid(struct net_device *dev)
2338{
2339 struct orinoco_private *priv = netdev_priv(dev);
2340 struct hermes *hw = &priv->hw;
2341 int err;
2342
2343 err = hermes_allocate(hw, priv->nicbuf_size, &priv->txfid);
2344 if (err == -EIO && priv->nicbuf_size > TX_NICBUF_SIZE_BUG) {
2345 /* Try workaround for old Symbol firmware bug */
2346 printk(KERN_WARNING "%s: firmware ALLOC bug detected "
2347 "(old Symbol firmware?). Trying to work around... ",
2348 dev->name);
2349
2350 priv->nicbuf_size = TX_NICBUF_SIZE_BUG;
2351 err = hermes_allocate(hw, priv->nicbuf_size, &priv->txfid);
2352 if (err)
2353 printk("failed!\n");
2354 else
2355 printk("ok.\n");
2356 }
2357
2358 return err;
2359}
2360
2361int orinoco_reinit_firmware(struct net_device *dev)
2362{
2363 struct orinoco_private *priv = netdev_priv(dev);
2364 struct hermes *hw = &priv->hw;
2365 int err;
2366
2367 err = hermes_init(hw);
2368 if (priv->do_fw_download && !err) {
2369 err = orinoco_download(priv);
2370 if (err)
2371 priv->do_fw_download = 0;
2372 }
2373 if (!err)
2374 err = orinoco_allocate_fid(dev);
2375
2376 return err;
2377}
2378
2379static int __orinoco_hw_set_bitrate(struct orinoco_private *priv)
2380{
2381 hermes_t *hw = &priv->hw;
2382 int err = 0;
2383
2384 if (priv->bitratemode >= BITRATE_TABLE_SIZE) {
2385 printk(KERN_ERR "%s: BUG: Invalid bitrate mode %d\n",
2386 priv->ndev->name, priv->bitratemode);
2387 return -EINVAL;
2388 }
2389
2390 switch (priv->firmware_type) {
2391 case FIRMWARE_TYPE_AGERE:
2392 err = hermes_write_wordrec(hw, USER_BAP,
2393 HERMES_RID_CNFTXRATECONTROL,
2394 bitrate_table[priv->bitratemode].agere_txratectrl);
2395 break;
2396 case FIRMWARE_TYPE_INTERSIL:
2397 case FIRMWARE_TYPE_SYMBOL:
2398 err = hermes_write_wordrec(hw, USER_BAP,
2399 HERMES_RID_CNFTXRATECONTROL,
2400 bitrate_table[priv->bitratemode].intersil_txratectrl);
2401 break;
2402 default:
2403 BUG();
2404 }
2405
2406 return err;
2407}
2408
2409/* Set fixed AP address */
2410static int __orinoco_hw_set_wap(struct orinoco_private *priv)
2411{
2412 int roaming_flag;
2413 int err = 0;
2414 hermes_t *hw = &priv->hw;
2415
2416 switch (priv->firmware_type) {
2417 case FIRMWARE_TYPE_AGERE:
2418 /* not supported */
2419 break;
2420 case FIRMWARE_TYPE_INTERSIL:
2421 if (priv->bssid_fixed)
2422 roaming_flag = 2;
2423 else
2424 roaming_flag = 1;
2425
2426 err = hermes_write_wordrec(hw, USER_BAP,
2427 HERMES_RID_CNFROAMINGMODE,
2428 roaming_flag);
2429 break;
2430 case FIRMWARE_TYPE_SYMBOL:
2431 err = HERMES_WRITE_RECORD(hw, USER_BAP,
2432 HERMES_RID_CNFMANDATORYBSSID_SYMBOL,
2433 &priv->desired_bssid);
2434 break;
2435 }
2436 return err;
2437}
2438
2439/* Change the WEP keys and/or the current keys. Can be called
2440 * either from __orinoco_hw_setup_enc() or directly from
2441 * orinoco_ioctl_setiwencode(). In the later case the association
2442 * with the AP is not broken (if the firmware can handle it),
2443 * which is needed for 802.1x implementations. */
2444static int __orinoco_hw_setup_wepkeys(struct orinoco_private *priv)
2445{
2446 hermes_t *hw = &priv->hw;
2447 int err = 0;
2448
2449 switch (priv->firmware_type) {
2450 case FIRMWARE_TYPE_AGERE:
2451 err = HERMES_WRITE_RECORD(hw, USER_BAP,
2452 HERMES_RID_CNFWEPKEYS_AGERE,
2453 &priv->keys);
2454 if (err)
2455 return err;
2456 err = hermes_write_wordrec(hw, USER_BAP,
2457 HERMES_RID_CNFTXKEY_AGERE,
2458 priv->tx_key);
2459 if (err)
2460 return err;
2461 break;
2462 case FIRMWARE_TYPE_INTERSIL:
2463 case FIRMWARE_TYPE_SYMBOL:
2464 {
2465 int keylen;
2466 int i;
2467
2468 /* Force uniform key length to work around firmware bugs */
2469 keylen = le16_to_cpu(priv->keys[priv->tx_key].len);
2470
2471 if (keylen > LARGE_KEY_SIZE) {
2472 printk(KERN_ERR "%s: BUG: Key %d has oversize length %d.\n",
2473 priv->ndev->name, priv->tx_key, keylen);
2474 return -E2BIG;
2475 }
2476
2477 /* Write all 4 keys */
2478 for(i = 0; i < ORINOCO_MAX_KEYS; i++) {
2479 err = hermes_write_ltv(hw, USER_BAP,
2480 HERMES_RID_CNFDEFAULTKEY0 + i,
2481 HERMES_BYTES_TO_RECLEN(keylen),
2482 priv->keys[i].data);
2483 if (err)
2484 return err;
2485 }
2486
2487 /* Write the index of the key used in transmission */
2488 err = hermes_write_wordrec(hw, USER_BAP,
2489 HERMES_RID_CNFWEPDEFAULTKEYID,
2490 priv->tx_key);
2491 if (err)
2492 return err;
2493 }
2494 break;
2495 }
2496
2497 return 0;
2498}
2499
2500static int __orinoco_hw_setup_enc(struct orinoco_private *priv)
2501{
2502 hermes_t *hw = &priv->hw;
2503 int err = 0;
2504 int master_wep_flag;
2505 int auth_flag;
2506 int enc_flag;
2507
2508 /* Setup WEP keys for WEP and WPA */
2509 if (priv->encode_alg)
2510 __orinoco_hw_setup_wepkeys(priv);
2511
2512 if (priv->wep_restrict)
2513 auth_flag = HERMES_AUTH_SHARED_KEY;
2514 else
2515 auth_flag = HERMES_AUTH_OPEN;
2516
2517 if (priv->wpa_enabled)
2518 enc_flag = 2;
2519 else if (priv->encode_alg == IW_ENCODE_ALG_WEP)
2520 enc_flag = 1;
2521 else
2522 enc_flag = 0;
2523
2524 switch (priv->firmware_type) {
2525 case FIRMWARE_TYPE_AGERE: /* Agere style WEP */
2526 if (priv->encode_alg == IW_ENCODE_ALG_WEP) {
2527 /* Enable the shared-key authentication. */
2528 err = hermes_write_wordrec(hw, USER_BAP,
2529 HERMES_RID_CNFAUTHENTICATION_AGERE,
2530 auth_flag);
2531 }
2532 err = hermes_write_wordrec(hw, USER_BAP,
2533 HERMES_RID_CNFWEPENABLED_AGERE,
2534 enc_flag);
2535 if (err)
2536 return err;
2537
2538 if (priv->has_wpa) {
2539 /* Set WPA key management */
2540 err = hermes_write_wordrec(hw, USER_BAP,
2541 HERMES_RID_CNFSETWPAAUTHMGMTSUITE_AGERE,
2542 priv->key_mgmt);
2543 if (err)
2544 return err;
2545 }
2546
2547 break;
2548
2549 case FIRMWARE_TYPE_INTERSIL: /* Intersil style WEP */
2550 case FIRMWARE_TYPE_SYMBOL: /* Symbol style WEP */
2551 if (priv->encode_alg == IW_ENCODE_ALG_WEP) {
2552 if (priv->wep_restrict ||
2553 (priv->firmware_type == FIRMWARE_TYPE_SYMBOL))
2554 master_wep_flag = HERMES_WEP_PRIVACY_INVOKED |
2555 HERMES_WEP_EXCL_UNENCRYPTED;
2556 else
2557 master_wep_flag = HERMES_WEP_PRIVACY_INVOKED;
2558
2559 err = hermes_write_wordrec(hw, USER_BAP,
2560 HERMES_RID_CNFAUTHENTICATION,
2561 auth_flag);
2562 if (err)
2563 return err;
2564 } else
2565 master_wep_flag = 0;
2566
2567 if (priv->iw_mode == IW_MODE_MONITOR)
2568 master_wep_flag |= HERMES_WEP_HOST_DECRYPT;
2569
2570 /* Master WEP setting : on/off */
2571 err = hermes_write_wordrec(hw, USER_BAP,
2572 HERMES_RID_CNFWEPFLAGS_INTERSIL,
2573 master_wep_flag);
2574 if (err)
2575 return err;
2576
2577 break;
2578 }
2579
2580 return 0;
2581}
2582
2583/* key must be 32 bytes, including the tx and rx MIC keys.
2584 * rsc must be 8 bytes
2585 * tsc must be 8 bytes or NULL
2586 */
2587static int __orinoco_hw_set_tkip_key(hermes_t *hw, int key_idx, int set_tx,
2588 u8 *key, u8 *rsc, u8 *tsc)
2589{
2590 struct {
2591 __le16 idx;
2592 u8 rsc[IW_ENCODE_SEQ_MAX_SIZE];
2593 u8 key[TKIP_KEYLEN];
2594 u8 tx_mic[MIC_KEYLEN];
2595 u8 rx_mic[MIC_KEYLEN];
2596 u8 tsc[IW_ENCODE_SEQ_MAX_SIZE];
2597 } __attribute__ ((packed)) buf;
2598 int ret;
2599 int err;
2600 int k;
2601 u16 xmitting;
2602
2603 key_idx &= 0x3;
2604
2605 if (set_tx)
2606 key_idx |= 0x8000;
2607
2608 buf.idx = cpu_to_le16(key_idx);
2609 memcpy(buf.key, key,
2610 sizeof(buf.key) + sizeof(buf.tx_mic) + sizeof(buf.rx_mic));
2611
2612 if (rsc == NULL)
2613 memset(buf.rsc, 0, sizeof(buf.rsc));
2614 else
2615 memcpy(buf.rsc, rsc, sizeof(buf.rsc));
2616
2617 if (tsc == NULL) {
2618 memset(buf.tsc, 0, sizeof(buf.tsc));
2619 buf.tsc[4] = 0x10;
2620 } else {
2621 memcpy(buf.tsc, tsc, sizeof(buf.tsc));
2622 }
2623
2624 /* Wait upto 100ms for tx queue to empty */
2625 k = 100;
2626 do {
2627 k--;
2628 udelay(1000);
2629 ret = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_TXQUEUEEMPTY,
2630 &xmitting);
2631 if (ret)
2632 break;
2633 } while ((k > 0) && xmitting);
2634
2635 if (k == 0)
2636 ret = -ETIMEDOUT;
2637
2638 err = HERMES_WRITE_RECORD(hw, USER_BAP,
2639 HERMES_RID_CNFADDDEFAULTTKIPKEY_AGERE,
2640 &buf);
2641
2642 return ret ? ret : err;
2643}
2644
2645static int orinoco_clear_tkip_key(struct orinoco_private *priv,
2646 int key_idx)
2647{
2648 hermes_t *hw = &priv->hw;
2649 int err;
2650
2651 memset(&priv->tkip_key[key_idx], 0, sizeof(priv->tkip_key[key_idx]));
2652 err = hermes_write_wordrec(hw, USER_BAP,
2653 HERMES_RID_CNFREMDEFAULTTKIPKEY_AGERE,
2654 key_idx);
2655 if (err)
2656 printk(KERN_WARNING "%s: Error %d clearing TKIP key %d\n",
2657 priv->ndev->name, err, key_idx);
2658 return err;
2659}
2660
2661static int __orinoco_program_rids(struct net_device *dev)
2662{
2663 struct orinoco_private *priv = netdev_priv(dev);
2664 hermes_t *hw = &priv->hw;
2665 int err;
2666 struct hermes_idstring idbuf;
2667
2668 /* Set the MAC address */
2669 err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFOWNMACADDR,
2670 HERMES_BYTES_TO_RECLEN(ETH_ALEN), dev->dev_addr);
2671 if (err) {
2672 printk(KERN_ERR "%s: Error %d setting MAC address\n",
2673 dev->name, err);
2674 return err;
2675 }
2676
2677 /* Set up the link mode */
2678 err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNFPORTTYPE,
2679 priv->port_type);
2680 if (err) {
2681 printk(KERN_ERR "%s: Error %d setting port type\n",
2682 dev->name, err);
2683 return err;
2684 }
2685 /* Set the channel/frequency */
2686 if (priv->channel != 0 && priv->iw_mode != IW_MODE_INFRA) {
2687 err = hermes_write_wordrec(hw, USER_BAP,
2688 HERMES_RID_CNFOWNCHANNEL,
2689 priv->channel);
2690 if (err) {
2691 printk(KERN_ERR "%s: Error %d setting channel %d\n",
2692 dev->name, err, priv->channel);
2693 return err;
2694 }
2695 }
2696
2697 if (priv->has_ibss) {
2698 u16 createibss;
2699
2700 if ((strlen(priv->desired_essid) == 0) && (priv->createibss)) {
2701 printk(KERN_WARNING "%s: This firmware requires an "
2702 "ESSID in IBSS-Ad-Hoc mode.\n", dev->name);
2703 /* With wvlan_cs, in this case, we would crash.
2704 * hopefully, this driver will behave better...
2705 * Jean II */
2706 createibss = 0;
2707 } else {
2708 createibss = priv->createibss;
2709 }
2710
2711 err = hermes_write_wordrec(hw, USER_BAP,
2712 HERMES_RID_CNFCREATEIBSS,
2713 createibss);
2714 if (err) {
2715 printk(KERN_ERR "%s: Error %d setting CREATEIBSS\n",
2716 dev->name, err);
2717 return err;
2718 }
2719 }
2720
2721 /* Set the desired BSSID */
2722 err = __orinoco_hw_set_wap(priv);
2723 if (err) {
2724 printk(KERN_ERR "%s: Error %d setting AP address\n",
2725 dev->name, err);
2726 return err;
2727 }
2728 /* Set the desired ESSID */
2729 idbuf.len = cpu_to_le16(strlen(priv->desired_essid));
2730 memcpy(&idbuf.val, priv->desired_essid, sizeof(idbuf.val));
2731 /* WinXP wants partner to configure OWNSSID even in IBSS mode. (jimc) */
2732 err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFOWNSSID,
2733 HERMES_BYTES_TO_RECLEN(strlen(priv->desired_essid)+2),
2734 &idbuf);
2735 if (err) {
2736 printk(KERN_ERR "%s: Error %d setting OWNSSID\n",
2737 dev->name, err);
2738 return err;
2739 }
2740 err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFDESIREDSSID,
2741 HERMES_BYTES_TO_RECLEN(strlen(priv->desired_essid)+2),
2742 &idbuf);
2743 if (err) {
2744 printk(KERN_ERR "%s: Error %d setting DESIREDSSID\n",
2745 dev->name, err);
2746 return err;
2747 }
2748
2749 /* Set the station name */
2750 idbuf.len = cpu_to_le16(strlen(priv->nick));
2751 memcpy(&idbuf.val, priv->nick, sizeof(idbuf.val));
2752 err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFOWNNAME,
2753 HERMES_BYTES_TO_RECLEN(strlen(priv->nick)+2),
2754 &idbuf);
2755 if (err) {
2756 printk(KERN_ERR "%s: Error %d setting nickname\n",
2757 dev->name, err);
2758 return err;
2759 }
2760
2761 /* Set AP density */
2762 if (priv->has_sensitivity) {
2763 err = hermes_write_wordrec(hw, USER_BAP,
2764 HERMES_RID_CNFSYSTEMSCALE,
2765 priv->ap_density);
2766 if (err) {
2767 printk(KERN_WARNING "%s: Error %d setting SYSTEMSCALE. "
2768 "Disabling sensitivity control\n",
2769 dev->name, err);
2770
2771 priv->has_sensitivity = 0;
2772 }
2773 }
2774
2775 /* Set RTS threshold */
2776 err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNFRTSTHRESHOLD,
2777 priv->rts_thresh);
2778 if (err) {
2779 printk(KERN_ERR "%s: Error %d setting RTS threshold\n",
2780 dev->name, err);
2781 return err;
2782 }
2783
2784 /* Set fragmentation threshold or MWO robustness */
2785 if (priv->has_mwo)
2786 err = hermes_write_wordrec(hw, USER_BAP,
2787 HERMES_RID_CNFMWOROBUST_AGERE,
2788 priv->mwo_robust);
2789 else
2790 err = hermes_write_wordrec(hw, USER_BAP,
2791 HERMES_RID_CNFFRAGMENTATIONTHRESHOLD,
2792 priv->frag_thresh);
2793 if (err) {
2794 printk(KERN_ERR "%s: Error %d setting fragmentation\n",
2795 dev->name, err);
2796 return err;
2797 }
2798
2799 /* Set bitrate */
2800 err = __orinoco_hw_set_bitrate(priv);
2801 if (err) {
2802 printk(KERN_ERR "%s: Error %d setting bitrate\n",
2803 dev->name, err);
2804 return err;
2805 }
2806
2807 /* Set power management */
2808 if (priv->has_pm) {
2809 err = hermes_write_wordrec(hw, USER_BAP,
2810 HERMES_RID_CNFPMENABLED,
2811 priv->pm_on);
2812 if (err) {
2813 printk(KERN_ERR "%s: Error %d setting up PM\n",
2814 dev->name, err);
2815 return err;
2816 }
2817
2818 err = hermes_write_wordrec(hw, USER_BAP,
2819 HERMES_RID_CNFMULTICASTRECEIVE,
2820 priv->pm_mcast);
2821 if (err) {
2822 printk(KERN_ERR "%s: Error %d setting up PM\n",
2823 dev->name, err);
2824 return err;
2825 }
2826 err = hermes_write_wordrec(hw, USER_BAP,
2827 HERMES_RID_CNFMAXSLEEPDURATION,
2828 priv->pm_period);
2829 if (err) {
2830 printk(KERN_ERR "%s: Error %d setting up PM\n",
2831 dev->name, err);
2832 return err;
2833 }
2834 err = hermes_write_wordrec(hw, USER_BAP,
2835 HERMES_RID_CNFPMHOLDOVERDURATION,
2836 priv->pm_timeout);
2837 if (err) {
2838 printk(KERN_ERR "%s: Error %d setting up PM\n",
2839 dev->name, err);
2840 return err;
2841 }
2842 }
2843
2844 /* Set preamble - only for Symbol so far... */
2845 if (priv->has_preamble) {
2846 err = hermes_write_wordrec(hw, USER_BAP,
2847 HERMES_RID_CNFPREAMBLE_SYMBOL,
2848 priv->preamble);
2849 if (err) {
2850 printk(KERN_ERR "%s: Error %d setting preamble\n",
2851 dev->name, err);
2852 return err;
2853 }
2854 }
2855
2856 /* Set up encryption */
2857 if (priv->has_wep || priv->has_wpa) {
2858 err = __orinoco_hw_setup_enc(priv);
2859 if (err) {
2860 printk(KERN_ERR "%s: Error %d activating encryption\n",
2861 dev->name, err);
2862 return err;
2863 }
2864 }
2865
2866 if (priv->iw_mode == IW_MODE_MONITOR) {
2867 /* Enable monitor mode */
2868 dev->type = ARPHRD_IEEE80211;
2869 err = hermes_docmd_wait(hw, HERMES_CMD_TEST |
2870 HERMES_TEST_MONITOR, 0, NULL);
2871 } else {
2872 /* Disable monitor mode */
2873 dev->type = ARPHRD_ETHER;
2874 err = hermes_docmd_wait(hw, HERMES_CMD_TEST |
2875 HERMES_TEST_STOP, 0, NULL);
2876 }
2877 if (err)
2878 return err;
2879
2880 /* Set promiscuity / multicast*/
2881 priv->promiscuous = 0;
2882 priv->mc_count = 0;
2883
2884 /* FIXME: what about netif_tx_lock */
2885 __orinoco_set_multicast_list(dev);
2886
2887 return 0;
2888}
2889
2890/* FIXME: return int? */
2891static void
2892__orinoco_set_multicast_list(struct net_device *dev)
2893{
2894 struct orinoco_private *priv = netdev_priv(dev);
2895 hermes_t *hw = &priv->hw;
2896 int err = 0;
2897 int promisc, mc_count;
2898
2899 /* The Hermes doesn't seem to have an allmulti mode, so we go
2900 * into promiscuous mode and let the upper levels deal. */
2901 if ( (dev->flags & IFF_PROMISC) || (dev->flags & IFF_ALLMULTI) ||
2902 (dev->mc_count > MAX_MULTICAST(priv)) ) {
2903 promisc = 1;
2904 mc_count = 0;
2905 } else {
2906 promisc = 0;
2907 mc_count = dev->mc_count;
2908 }
2909
2910 if (promisc != priv->promiscuous) {
2911 err = hermes_write_wordrec(hw, USER_BAP,
2912 HERMES_RID_CNFPROMISCUOUSMODE,
2913 promisc);
2914 if (err) {
2915 printk(KERN_ERR "%s: Error %d setting PROMISCUOUSMODE to 1.\n",
2916 dev->name, err);
2917 } else
2918 priv->promiscuous = promisc;
2919 }
2920
2921 /* If we're not in promiscuous mode, then we need to set the
2922 * group address if either we want to multicast, or if we were
2923 * multicasting and want to stop */
2924 if (! promisc && (mc_count || priv->mc_count) ) {
2925 struct dev_mc_list *p = dev->mc_list;
2926 struct hermes_multicast mclist;
2927 int i;
2928
2929 for (i = 0; i < mc_count; i++) {
2930 /* paranoia: is list shorter than mc_count? */
2931 BUG_ON(! p);
2932 /* paranoia: bad address size in list? */
2933 BUG_ON(p->dmi_addrlen != ETH_ALEN);
2934
2935 memcpy(mclist.addr[i], p->dmi_addr, ETH_ALEN);
2936 p = p->next;
2937 }
2938
2939 if (p)
2940 printk(KERN_WARNING "%s: Multicast list is "
2941 "longer than mc_count\n", dev->name);
2942
2943 err = hermes_write_ltv(hw, USER_BAP,
2944 HERMES_RID_CNFGROUPADDRESSES,
2945 HERMES_BYTES_TO_RECLEN(mc_count * ETH_ALEN),
2946 &mclist);
2947 if (err)
2948 printk(KERN_ERR "%s: Error %d setting multicast list.\n",
2949 dev->name, err);
2950 else
2951 priv->mc_count = mc_count;
2952 }
2953}
2954
2955/* This must be called from user context, without locks held - use
2956 * schedule_work() */
2957static void orinoco_reset(struct work_struct *work)
2958{
2959 struct orinoco_private *priv =
2960 container_of(work, struct orinoco_private, reset_work);
2961 struct net_device *dev = priv->ndev;
2962 struct hermes *hw = &priv->hw;
2963 int err;
2964 unsigned long flags;
2965
2966 if (orinoco_lock(priv, &flags) != 0)
2967 /* When the hardware becomes available again, whatever
2968 * detects that is responsible for re-initializing
2969 * it. So no need for anything further */
2970 return;
2971
2972 netif_stop_queue(dev);
2973
2974 /* Shut off interrupts. Depending on what state the hardware
2975 * is in, this might not work, but we'll try anyway */
2976 hermes_set_irqmask(hw, 0);
2977 hermes_write_regn(hw, EVACK, 0xffff);
2978
2979 priv->hw_unavailable++;
2980 priv->last_linkstatus = 0xffff; /* firmware will have to reassociate */
2981 netif_carrier_off(dev);
2982
2983 orinoco_unlock(priv, &flags);
2984
2985 /* Scanning support: Cleanup of driver struct */
2986 orinoco_clear_scan_results(priv, 0);
2987 priv->scan_inprogress = 0;
2988
2989 if (priv->hard_reset) {
2990 err = (*priv->hard_reset)(priv);
2991 if (err) {
2992 printk(KERN_ERR "%s: orinoco_reset: Error %d "
2993 "performing hard reset\n", dev->name, err);
2994 goto disable;
2995 }
2996 }
2997
2998 err = orinoco_reinit_firmware(dev);
2999 if (err) {
3000 printk(KERN_ERR "%s: orinoco_reset: Error %d re-initializing firmware\n",
3001 dev->name, err);
3002 goto disable;
3003 }
3004
3005 spin_lock_irq(&priv->lock); /* This has to be called from user context */
3006
3007 priv->hw_unavailable--;
3008
3009 /* priv->open or priv->hw_unavailable might have changed while
3010 * we dropped the lock */
3011 if (priv->open && (! priv->hw_unavailable)) {
3012 err = __orinoco_up(dev);
3013 if (err) {
3014 printk(KERN_ERR "%s: orinoco_reset: Error %d reenabling card\n",
3015 dev->name, err);
3016 } else
3017 dev->trans_start = jiffies;
3018 }
3019
3020 spin_unlock_irq(&priv->lock);
3021
3022 return;
3023 disable:
3024 hermes_set_irqmask(hw, 0);
3025 netif_device_detach(dev);
3026 printk(KERN_ERR "%s: Device has been disabled!\n", dev->name);
3027}
3028
3029/********************************************************************/
3030/* Interrupt handler */
3031/********************************************************************/
3032
3033static void __orinoco_ev_tick(struct net_device *dev, hermes_t *hw)
3034{
3035 printk(KERN_DEBUG "%s: TICK\n", dev->name);
3036}
3037
3038static void __orinoco_ev_wterr(struct net_device *dev, hermes_t *hw)
3039{
3040 /* This seems to happen a fair bit under load, but ignoring it
3041 seems to work fine...*/
3042 printk(KERN_DEBUG "%s: MAC controller error (WTERR). Ignoring.\n",
3043 dev->name);
3044}
3045
3046irqreturn_t orinoco_interrupt(int irq, void *dev_id)
3047{
3048 struct net_device *dev = dev_id;
3049 struct orinoco_private *priv = netdev_priv(dev);
3050 hermes_t *hw = &priv->hw;
3051 int count = MAX_IRQLOOPS_PER_IRQ;
3052 u16 evstat, events;
3053 /* These are used to detect a runaway interrupt situation */
3054 /* If we get more than MAX_IRQLOOPS_PER_JIFFY iterations in a jiffy,
3055 * we panic and shut down the hardware */
3056 static int last_irq_jiffy = 0; /* jiffies value the last time
3057 * we were called */
3058 static int loops_this_jiffy = 0;
3059 unsigned long flags;
3060
3061 if (orinoco_lock(priv, &flags) != 0) {
3062 /* If hw is unavailable - we don't know if the irq was
3063 * for us or not */
3064 return IRQ_HANDLED;
3065 }
3066
3067 evstat = hermes_read_regn(hw, EVSTAT);
3068 events = evstat & hw->inten;
3069 if (! events) {
3070 orinoco_unlock(priv, &flags);
3071 return IRQ_NONE;
3072 }
3073
3074 if (jiffies != last_irq_jiffy)
3075 loops_this_jiffy = 0;
3076 last_irq_jiffy = jiffies;
3077
3078 while (events && count--) {
3079 if (++loops_this_jiffy > MAX_IRQLOOPS_PER_JIFFY) {
3080 printk(KERN_WARNING "%s: IRQ handler is looping too "
3081 "much! Resetting.\n", dev->name);
3082 /* Disable interrupts for now */
3083 hermes_set_irqmask(hw, 0);
3084 schedule_work(&priv->reset_work);
3085 break;
3086 }
3087
3088 /* Check the card hasn't been removed */
3089 if (! hermes_present(hw)) {
3090 DEBUG(0, "orinoco_interrupt(): card removed\n");
3091 break;
3092 }
3093
3094 if (events & HERMES_EV_TICK)
3095 __orinoco_ev_tick(dev, hw);
3096 if (events & HERMES_EV_WTERR)
3097 __orinoco_ev_wterr(dev, hw);
3098 if (events & HERMES_EV_INFDROP)
3099 __orinoco_ev_infdrop(dev, hw);
3100 if (events & HERMES_EV_INFO)
3101 __orinoco_ev_info(dev, hw);
3102 if (events & HERMES_EV_RX)
3103 __orinoco_ev_rx(dev, hw);
3104 if (events & HERMES_EV_TXEXC)
3105 __orinoco_ev_txexc(dev, hw);
3106 if (events & HERMES_EV_TX)
3107 __orinoco_ev_tx(dev, hw);
3108 if (events & HERMES_EV_ALLOC)
3109 __orinoco_ev_alloc(dev, hw);
3110
3111 hermes_write_regn(hw, EVACK, evstat);
3112
3113 evstat = hermes_read_regn(hw, EVSTAT);
3114 events = evstat & hw->inten;
3115 };
3116
3117 orinoco_unlock(priv, &flags);
3118 return IRQ_HANDLED;
3119}
3120
3121/********************************************************************/
3122/* Power management */
3123/********************************************************************/
3124#if defined(CONFIG_PM_SLEEP) && !defined(CONFIG_HERMES_CACHE_FW_ON_INIT)
3125static int orinoco_pm_notifier(struct notifier_block *notifier,
3126 unsigned long pm_event,
3127 void *unused)
3128{
3129 struct orinoco_private *priv = container_of(notifier,
3130 struct orinoco_private,
3131 pm_notifier);
3132
3133 /* All we need to do is cache the firmware before suspend, and
3134 * release it when we come out.
3135 *
3136 * Only need to do this if we're downloading firmware. */
3137 if (!priv->do_fw_download)
3138 return NOTIFY_DONE;
3139
3140 switch (pm_event) {
3141 case PM_HIBERNATION_PREPARE:
3142 case PM_SUSPEND_PREPARE:
3143 orinoco_cache_fw(priv, 0);
3144 break;
3145
3146 case PM_POST_RESTORE:
3147 /* Restore from hibernation failed. We need to clean
3148 * up in exactly the same way, so fall through. */
3149 case PM_POST_HIBERNATION:
3150 case PM_POST_SUSPEND:
3151 orinoco_uncache_fw(priv);
3152 break;
3153
3154 case PM_RESTORE_PREPARE:
3155 default:
3156 break;
3157 }
3158
3159 return NOTIFY_DONE;
3160}
3161#else /* !PM_SLEEP || HERMES_CACHE_FW_ON_INIT */
3162#define orinoco_pm_notifier NULL
3163#endif
3164
3165/********************************************************************/
3166/* Initialization */
3167/********************************************************************/
3168
3169struct comp_id {
3170 u16 id, variant, major, minor;
3171} __attribute__ ((packed));
3172
3173static inline fwtype_t determine_firmware_type(struct comp_id *nic_id)
3174{
3175 if (nic_id->id < 0x8000)
3176 return FIRMWARE_TYPE_AGERE;
3177 else if (nic_id->id == 0x8000 && nic_id->major == 0)
3178 return FIRMWARE_TYPE_SYMBOL;
3179 else
3180 return FIRMWARE_TYPE_INTERSIL;
3181}
3182
3183/* Set priv->firmware type, determine firmware properties */
3184static int determine_firmware(struct net_device *dev)
3185{
3186 struct orinoco_private *priv = netdev_priv(dev);
3187 hermes_t *hw = &priv->hw;
3188 int err;
3189 struct comp_id nic_id, sta_id;
3190 unsigned int firmver;
3191 char tmp[SYMBOL_MAX_VER_LEN+1] __attribute__((aligned(2)));
3192
3193 /* Get the hardware version */
3194 err = HERMES_READ_RECORD(hw, USER_BAP, HERMES_RID_NICID, &nic_id);
3195 if (err) {
3196 printk(KERN_ERR "%s: Cannot read hardware identity: error %d\n",
3197 dev->name, err);
3198 return err;
3199 }
3200
3201 le16_to_cpus(&nic_id.id);
3202 le16_to_cpus(&nic_id.variant);
3203 le16_to_cpus(&nic_id.major);
3204 le16_to_cpus(&nic_id.minor);
3205 printk(KERN_DEBUG "%s: Hardware identity %04x:%04x:%04x:%04x\n",
3206 dev->name, nic_id.id, nic_id.variant,
3207 nic_id.major, nic_id.minor);
3208
3209 priv->firmware_type = determine_firmware_type(&nic_id);
3210
3211 /* Get the firmware version */
3212 err = HERMES_READ_RECORD(hw, USER_BAP, HERMES_RID_STAID, &sta_id);
3213 if (err) {
3214 printk(KERN_ERR "%s: Cannot read station identity: error %d\n",
3215 dev->name, err);
3216 return err;
3217 }
3218
3219 le16_to_cpus(&sta_id.id);
3220 le16_to_cpus(&sta_id.variant);
3221 le16_to_cpus(&sta_id.major);
3222 le16_to_cpus(&sta_id.minor);
3223 printk(KERN_DEBUG "%s: Station identity %04x:%04x:%04x:%04x\n",
3224 dev->name, sta_id.id, sta_id.variant,
3225 sta_id.major, sta_id.minor);
3226
3227 switch (sta_id.id) {
3228 case 0x15:
3229 printk(KERN_ERR "%s: Primary firmware is active\n",
3230 dev->name);
3231 return -ENODEV;
3232 case 0x14b:
3233 printk(KERN_ERR "%s: Tertiary firmware is active\n",
3234 dev->name);
3235 return -ENODEV;
3236 case 0x1f: /* Intersil, Agere, Symbol Spectrum24 */
3237 case 0x21: /* Symbol Spectrum24 Trilogy */
3238 break;
3239 default:
3240 printk(KERN_NOTICE "%s: Unknown station ID, please report\n",
3241 dev->name);
3242 break;
3243 }
3244
3245 /* Default capabilities */
3246 priv->has_sensitivity = 1;
3247 priv->has_mwo = 0;
3248 priv->has_preamble = 0;
3249 priv->has_port3 = 1;
3250 priv->has_ibss = 1;
3251 priv->has_wep = 0;
3252 priv->has_big_wep = 0;
3253 priv->has_alt_txcntl = 0;
3254 priv->has_ext_scan = 0;
3255 priv->has_wpa = 0;
3256 priv->do_fw_download = 0;
3257
3258 /* Determine capabilities from the firmware version */
3259 switch (priv->firmware_type) {
3260 case FIRMWARE_TYPE_AGERE:
3261 /* Lucent Wavelan IEEE, Lucent Orinoco, Cabletron RoamAbout,
3262 ELSA, Melco, HP, IBM, Dell 1150, Compaq 110/210 */
3263 snprintf(priv->fw_name, sizeof(priv->fw_name) - 1,
3264 "Lucent/Agere %d.%02d", sta_id.major, sta_id.minor);
3265
3266 firmver = ((unsigned long)sta_id.major << 16) | sta_id.minor;
3267
3268 priv->has_ibss = (firmver >= 0x60006);
3269 priv->has_wep = (firmver >= 0x40020);
3270 priv->has_big_wep = 1; /* FIXME: this is wrong - how do we tell
3271 Gold cards from the others? */
3272 priv->has_mwo = (firmver >= 0x60000);
3273 priv->has_pm = (firmver >= 0x40020); /* Don't work in 7.52 ? */
3274 priv->ibss_port = 1;
3275 priv->has_hostscan = (firmver >= 0x8000a);
3276 priv->do_fw_download = 1;
3277 priv->broken_monitor = (firmver >= 0x80000);
3278 priv->has_alt_txcntl = (firmver >= 0x90000); /* All 9.x ? */
3279 priv->has_ext_scan = (firmver >= 0x90000); /* All 9.x ? */
3280 priv->has_wpa = (firmver >= 0x9002a);
3281 /* Tested with Agere firmware :
3282 * 1.16 ; 4.08 ; 4.52 ; 6.04 ; 6.16 ; 7.28 => Jean II
3283 * Tested CableTron firmware : 4.32 => Anton */
3284 break;
3285 case FIRMWARE_TYPE_SYMBOL:
3286 /* Symbol , 3Com AirConnect, Intel, Ericsson WLAN */
3287 /* Intel MAC : 00:02:B3:* */
3288 /* 3Com MAC : 00:50:DA:* */
3289 memset(tmp, 0, sizeof(tmp));
3290 /* Get the Symbol firmware version */
3291 err = hermes_read_ltv(hw, USER_BAP,
3292 HERMES_RID_SECONDARYVERSION_SYMBOL,
3293 SYMBOL_MAX_VER_LEN, NULL, &tmp);
3294 if (err) {
3295 printk(KERN_WARNING
3296 "%s: Error %d reading Symbol firmware info. Wildly guessing capabilities...\n",
3297 dev->name, err);
3298 firmver = 0;
3299 tmp[0] = '\0';
3300 } else {
3301 /* The firmware revision is a string, the format is
3302 * something like : "V2.20-01".
3303 * Quick and dirty parsing... - Jean II
3304 */
3305 firmver = ((tmp[1] - '0') << 16) | ((tmp[3] - '0') << 12)
3306 | ((tmp[4] - '0') << 8) | ((tmp[6] - '0') << 4)
3307 | (tmp[7] - '0');
3308
3309 tmp[SYMBOL_MAX_VER_LEN] = '\0';
3310 }
3311
3312 snprintf(priv->fw_name, sizeof(priv->fw_name) - 1,
3313 "Symbol %s", tmp);
3314
3315 priv->has_ibss = (firmver >= 0x20000);
3316 priv->has_wep = (firmver >= 0x15012);
3317 priv->has_big_wep = (firmver >= 0x20000);
3318 priv->has_pm = (firmver >= 0x20000 && firmver < 0x22000) ||
3319 (firmver >= 0x29000 && firmver < 0x30000) ||
3320 firmver >= 0x31000;
3321 priv->has_preamble = (firmver >= 0x20000);
3322 priv->ibss_port = 4;
3323
3324 /* Symbol firmware is found on various cards, but
3325 * there has been no attempt to check firmware
3326 * download on non-spectrum_cs based cards.
3327 *
3328 * Given that the Agere firmware download works
3329 * differently, we should avoid doing a firmware
3330 * download with the Symbol algorithm on non-spectrum
3331 * cards.
3332 *
3333 * For now we can identify a spectrum_cs based card
3334 * because it has a firmware reset function.
3335 */
3336 priv->do_fw_download = (priv->stop_fw != NULL);
3337
3338 priv->broken_disableport = (firmver == 0x25013) ||
3339 (firmver >= 0x30000 && firmver <= 0x31000);
3340 priv->has_hostscan = (firmver >= 0x31001) ||
3341 (firmver >= 0x29057 && firmver < 0x30000);
3342 /* Tested with Intel firmware : 0x20015 => Jean II */
3343 /* Tested with 3Com firmware : 0x15012 & 0x22001 => Jean II */
3344 break;
3345 case FIRMWARE_TYPE_INTERSIL:
3346 /* D-Link, Linksys, Adtron, ZoomAir, and many others...
3347 * Samsung, Compaq 100/200 and Proxim are slightly
3348 * different and less well tested */
3349 /* D-Link MAC : 00:40:05:* */
3350 /* Addtron MAC : 00:90:D1:* */
3351 snprintf(priv->fw_name, sizeof(priv->fw_name) - 1,
3352 "Intersil %d.%d.%d", sta_id.major, sta_id.minor,
3353 sta_id.variant);
3354
3355 firmver = ((unsigned long)sta_id.major << 16) |
3356 ((unsigned long)sta_id.minor << 8) | sta_id.variant;
3357
3358 priv->has_ibss = (firmver >= 0x000700); /* FIXME */
3359 priv->has_big_wep = priv->has_wep = (firmver >= 0x000800);
3360 priv->has_pm = (firmver >= 0x000700);
3361 priv->has_hostscan = (firmver >= 0x010301);
3362
3363 if (firmver >= 0x000800)
3364 priv->ibss_port = 0;
3365 else {
3366 printk(KERN_NOTICE "%s: Intersil firmware earlier "
3367 "than v0.8.x - several features not supported\n",
3368 dev->name);
3369 priv->ibss_port = 1;
3370 }
3371 break;
3372 }
3373 printk(KERN_DEBUG "%s: Firmware determined as %s\n", dev->name,
3374 priv->fw_name);
3375
3376 return 0;
3377}
3378
3379static int orinoco_init(struct net_device *dev)
3380{
3381 struct orinoco_private *priv = netdev_priv(dev);
3382 hermes_t *hw = &priv->hw;
3383 int err = 0;
3384 struct hermes_idstring nickbuf;
3385 u16 reclen;
3386 int len;
3387
3388 /* No need to lock, the hw_unavailable flag is already set in
3389 * alloc_orinocodev() */
3390 priv->nicbuf_size = IEEE80211_MAX_FRAME_LEN + ETH_HLEN;
3391
3392 /* Initialize the firmware */
3393 err = hermes_init(hw);
3394 if (err != 0) {
3395 printk(KERN_ERR "%s: failed to initialize firmware (err = %d)\n",
3396 dev->name, err);
3397 goto out;
3398 }
3399
3400 err = determine_firmware(dev);
3401 if (err != 0) {
3402 printk(KERN_ERR "%s: Incompatible firmware, aborting\n",
3403 dev->name);
3404 goto out;
3405 }
3406
3407 if (priv->do_fw_download) {
3408#ifdef CONFIG_HERMES_CACHE_FW_ON_INIT
3409 orinoco_cache_fw(priv, 0);
3410#endif
3411
3412 err = orinoco_download(priv);
3413 if (err)
3414 priv->do_fw_download = 0;
3415
3416 /* Check firmware version again */
3417 err = determine_firmware(dev);
3418 if (err != 0) {
3419 printk(KERN_ERR "%s: Incompatible firmware, aborting\n",
3420 dev->name);
3421 goto out;
3422 }
3423 }
3424
3425 if (priv->has_port3)
3426 printk(KERN_DEBUG "%s: Ad-hoc demo mode supported\n", dev->name);
3427 if (priv->has_ibss)
3428 printk(KERN_DEBUG "%s: IEEE standard IBSS ad-hoc mode supported\n",
3429 dev->name);
3430 if (priv->has_wep) {
3431 printk(KERN_DEBUG "%s: WEP supported, ", dev->name);
3432 if (priv->has_big_wep)
3433 printk("104-bit key\n");
3434 else
3435 printk("40-bit key\n");
3436 }
3437 if (priv->has_wpa) {
3438 printk(KERN_DEBUG "%s: WPA-PSK supported\n", dev->name);
3439 if (orinoco_mic_init(priv)) {
3440 printk(KERN_ERR "%s: Failed to setup MIC crypto "
3441 "algorithm. Disabling WPA support\n", dev->name);
3442 priv->has_wpa = 0;
3443 }
3444 }
3445
3446 /* Now we have the firmware capabilities, allocate appropiate
3447 * sized scan buffers */
3448 if (orinoco_bss_data_allocate(priv))
3449 goto out;
3450 orinoco_bss_data_init(priv);
3451
3452 /* Get the MAC address */
3453 err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CNFOWNMACADDR,
3454 ETH_ALEN, NULL, dev->dev_addr);
3455 if (err) {
3456 printk(KERN_WARNING "%s: failed to read MAC address!\n",
3457 dev->name);
3458 goto out;
3459 }
3460
3461 printk(KERN_DEBUG "%s: MAC address %pM\n",
3462 dev->name, dev->dev_addr);
3463
3464 /* Get the station name */
3465 err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CNFOWNNAME,
3466 sizeof(nickbuf), &reclen, &nickbuf);
3467 if (err) {
3468 printk(KERN_ERR "%s: failed to read station name\n",
3469 dev->name);
3470 goto out;
3471 }
3472 if (nickbuf.len)
3473 len = min(IW_ESSID_MAX_SIZE, (int)le16_to_cpu(nickbuf.len));
3474 else
3475 len = min(IW_ESSID_MAX_SIZE, 2 * reclen);
3476 memcpy(priv->nick, &nickbuf.val, len);
3477 priv->nick[len] = '\0';
3478
3479 printk(KERN_DEBUG "%s: Station name \"%s\"\n", dev->name, priv->nick);
3480
3481 err = orinoco_allocate_fid(dev);
3482 if (err) {
3483 printk(KERN_ERR "%s: failed to allocate NIC buffer!\n",
3484 dev->name);
3485 goto out;
3486 }
3487
3488 /* Get allowed channels */
3489 err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CHANNELLIST,
3490 &priv->channel_mask);
3491 if (err) {
3492 printk(KERN_ERR "%s: failed to read channel list!\n",
3493 dev->name);
3494 goto out;
3495 }
3496
3497 /* Get initial AP density */
3498 err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFSYSTEMSCALE,
3499 &priv->ap_density);
3500 if (err || priv->ap_density < 1 || priv->ap_density > 3) {
3501 priv->has_sensitivity = 0;
3502 }
3503
3504 /* Get initial RTS threshold */
3505 err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFRTSTHRESHOLD,
3506 &priv->rts_thresh);
3507 if (err) {
3508 printk(KERN_ERR "%s: failed to read RTS threshold!\n",
3509 dev->name);
3510 goto out;
3511 }
3512
3513 /* Get initial fragmentation settings */
3514 if (priv->has_mwo)
3515 err = hermes_read_wordrec(hw, USER_BAP,
3516 HERMES_RID_CNFMWOROBUST_AGERE,
3517 &priv->mwo_robust);
3518 else
3519 err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFFRAGMENTATIONTHRESHOLD,
3520 &priv->frag_thresh);
3521 if (err) {
3522 printk(KERN_ERR "%s: failed to read fragmentation settings!\n",
3523 dev->name);
3524 goto out;
3525 }
3526
3527 /* Power management setup */
3528 if (priv->has_pm) {
3529 priv->pm_on = 0;
3530 priv->pm_mcast = 1;
3531 err = hermes_read_wordrec(hw, USER_BAP,
3532 HERMES_RID_CNFMAXSLEEPDURATION,
3533 &priv->pm_period);
3534 if (err) {
3535 printk(KERN_ERR "%s: failed to read power management period!\n",
3536 dev->name);
3537 goto out;
3538 }
3539 err = hermes_read_wordrec(hw, USER_BAP,
3540 HERMES_RID_CNFPMHOLDOVERDURATION,
3541 &priv->pm_timeout);
3542 if (err) {
3543 printk(KERN_ERR "%s: failed to read power management timeout!\n",
3544 dev->name);
3545 goto out;
3546 }
3547 }
3548
3549 /* Preamble setup */
3550 if (priv->has_preamble) {
3551 err = hermes_read_wordrec(hw, USER_BAP,
3552 HERMES_RID_CNFPREAMBLE_SYMBOL,
3553 &priv->preamble);
3554 if (err)
3555 goto out;
3556 }
3557
3558 /* Set up the default configuration */
3559 priv->iw_mode = IW_MODE_INFRA;
3560 /* By default use IEEE/IBSS ad-hoc mode if we have it */
3561 priv->prefer_port3 = priv->has_port3 && (! priv->has_ibss);
3562 set_port_type(priv);
3563 priv->channel = 0; /* use firmware default */
3564
3565 priv->promiscuous = 0;
3566 priv->encode_alg = IW_ENCODE_ALG_NONE;
3567 priv->tx_key = 0;
3568 priv->wpa_enabled = 0;
3569 priv->tkip_cm_active = 0;
3570 priv->key_mgmt = 0;
3571 priv->wpa_ie_len = 0;
3572 priv->wpa_ie = NULL;
3573
3574 /* Make the hardware available, as long as it hasn't been
3575 * removed elsewhere (e.g. by PCMCIA hot unplug) */
3576 spin_lock_irq(&priv->lock);
3577 priv->hw_unavailable--;
3578 spin_unlock_irq(&priv->lock);
3579
3580 printk(KERN_DEBUG "%s: ready\n", dev->name);
3581
3582 out:
3583 return err;
3584}
3585
3586static const struct net_device_ops orinoco_netdev_ops = {
3587 .ndo_init = orinoco_init,
3588 .ndo_open = orinoco_open,
3589 .ndo_stop = orinoco_stop,
3590 .ndo_start_xmit = orinoco_xmit,
3591 .ndo_set_multicast_list = orinoco_set_multicast_list,
3592 .ndo_change_mtu = orinoco_change_mtu,
3593 .ndo_tx_timeout = orinoco_tx_timeout,
3594 .ndo_get_stats = orinoco_get_stats,
3595};
3596
3597struct net_device
3598*alloc_orinocodev(int sizeof_card,
3599 struct device *device,
3600 int (*hard_reset)(struct orinoco_private *),
3601 int (*stop_fw)(struct orinoco_private *, int))
3602{
3603 struct net_device *dev;
3604 struct orinoco_private *priv;
3605
3606 dev = alloc_etherdev(sizeof(struct orinoco_private) + sizeof_card);
3607 if (!dev)
3608 return NULL;
3609 priv = netdev_priv(dev);
3610 priv->ndev = dev;
3611 if (sizeof_card)
3612 priv->card = (void *)((unsigned long)priv
3613 + sizeof(struct orinoco_private));
3614 else
3615 priv->card = NULL;
3616 priv->dev = device;
3617
3618 /* Setup / override net_device fields */
3619 dev->netdev_ops = &orinoco_netdev_ops;
3620 dev->watchdog_timeo = HZ; /* 1 second timeout */
3621 dev->ethtool_ops = &orinoco_ethtool_ops;
3622 dev->wireless_handlers = &orinoco_handler_def;
3623#ifdef WIRELESS_SPY
3624 priv->wireless_data.spy_data = &priv->spy_data;
3625 dev->wireless_data = &priv->wireless_data;
3626#endif
3627 /* we use the default eth_mac_addr for setting the MAC addr */
3628
3629 /* Reserve space in skb for the SNAP header */
3630 dev->hard_header_len += ENCAPS_OVERHEAD;
3631
3632 /* Set up default callbacks */
3633 priv->hard_reset = hard_reset;
3634 priv->stop_fw = stop_fw;
3635
3636 spin_lock_init(&priv->lock);
3637 priv->open = 0;
3638 priv->hw_unavailable = 1; /* orinoco_init() must clear this
3639 * before anything else touches the
3640 * hardware */
3641 INIT_WORK(&priv->reset_work, orinoco_reset);
3642 INIT_WORK(&priv->join_work, orinoco_join_ap);
3643 INIT_WORK(&priv->wevent_work, orinoco_send_wevents);
3644
3645 INIT_LIST_HEAD(&priv->rx_list);
3646 tasklet_init(&priv->rx_tasklet, orinoco_rx_isr_tasklet,
3647 (unsigned long) dev);
3648
3649 netif_carrier_off(dev);
3650 priv->last_linkstatus = 0xffff;
3651
3652 priv->cached_pri_fw = NULL;
3653 priv->cached_fw = NULL;
3654
3655 /* Register PM notifiers */
3656 priv->pm_notifier.notifier_call = orinoco_pm_notifier;
3657 register_pm_notifier(&priv->pm_notifier);
3658
3659 return dev;
3660}
3661
3662void free_orinocodev(struct net_device *dev)
3663{
3664 struct orinoco_private *priv = netdev_priv(dev);
3665 struct orinoco_rx_data *rx_data, *temp;
3666
3667 /* If the tasklet is scheduled when we call tasklet_kill it
3668 * will run one final time. However the tasklet will only
3669 * drain priv->rx_list if the hw is still available. */
3670 tasklet_kill(&priv->rx_tasklet);
3671
3672 /* Explicitly drain priv->rx_list */
3673 list_for_each_entry_safe(rx_data, temp, &priv->rx_list, list) {
3674 list_del(&rx_data->list);
3675
3676 dev_kfree_skb(rx_data->skb);
3677 kfree(rx_data->desc);
3678 kfree(rx_data);
3679 }
3680
3681 unregister_pm_notifier(&priv->pm_notifier);
3682 orinoco_uncache_fw(priv);
3683
3684 priv->wpa_ie_len = 0;
3685 kfree(priv->wpa_ie);
3686 orinoco_mic_free(priv);
3687 orinoco_bss_data_free(priv);
3688 free_netdev(dev);
3689}
3690
3691/********************************************************************/
3692/* Wireless extensions */
3693/********************************************************************/
3694
3695/* Return : < 0 -> error code ; >= 0 -> length */
3696static int orinoco_hw_get_essid(struct orinoco_private *priv, int *active,
3697 char buf[IW_ESSID_MAX_SIZE+1])
3698{
3699 hermes_t *hw = &priv->hw;
3700 int err = 0;
3701 struct hermes_idstring essidbuf;
3702 char *p = (char *)(&essidbuf.val);
3703 int len;
3704 unsigned long flags;
3705
3706 if (orinoco_lock(priv, &flags) != 0)
3707 return -EBUSY;
3708
3709 if (strlen(priv->desired_essid) > 0) {
3710 /* We read the desired SSID from the hardware rather
3711 than from priv->desired_essid, just in case the
3712 firmware is allowed to change it on us. I'm not
3713 sure about this */
3714 /* My guess is that the OWNSSID should always be whatever
3715 * we set to the card, whereas CURRENT_SSID is the one that
3716 * may change... - Jean II */
3717 u16 rid;
3718
3719 *active = 1;
3720
3721 rid = (priv->port_type == 3) ? HERMES_RID_CNFOWNSSID :
3722 HERMES_RID_CNFDESIREDSSID;
3723
3724 err = hermes_read_ltv(hw, USER_BAP, rid, sizeof(essidbuf),
3725 NULL, &essidbuf);
3726 if (err)
3727 goto fail_unlock;
3728 } else {
3729 *active = 0;
3730
3731 err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CURRENTSSID,
3732 sizeof(essidbuf), NULL, &essidbuf);
3733 if (err)
3734 goto fail_unlock;
3735 }
3736
3737 len = le16_to_cpu(essidbuf.len);
3738 BUG_ON(len > IW_ESSID_MAX_SIZE);
3739
3740 memset(buf, 0, IW_ESSID_MAX_SIZE);
3741 memcpy(buf, p, len);
3742 err = len;
3743
3744 fail_unlock:
3745 orinoco_unlock(priv, &flags);
3746
3747 return err;
3748}
3749
3750static int orinoco_hw_get_freq(struct orinoco_private *priv)
3751{
3752
3753 hermes_t *hw = &priv->hw;
3754 int err = 0;
3755 u16 channel;
3756 int freq = 0;
3757 unsigned long flags;
3758
3759 if (orinoco_lock(priv, &flags) != 0)
3760 return -EBUSY;
3761
3762 err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CURRENTCHANNEL, &channel);
3763 if (err)
3764 goto out;
3765
3766 /* Intersil firmware 1.3.5 returns 0 when the interface is down */
3767 if (channel == 0) {
3768 err = -EBUSY;
3769 goto out;
3770 }
3771
3772 if ( (channel < 1) || (channel > NUM_CHANNELS) ) {
3773 printk(KERN_WARNING "%s: Channel out of range (%d)!\n",
3774 priv->ndev->name, channel);
3775 err = -EBUSY;
3776 goto out;
3777
3778 }
3779 freq = ieee80211_dsss_chan_to_freq(channel);
3780
3781 out:
3782 orinoco_unlock(priv, &flags);
3783
3784 if (err > 0)
3785 err = -EBUSY;
3786 return err ? err : freq;
3787}
3788
3789static int orinoco_hw_get_bitratelist(struct orinoco_private *priv,
3790 int *numrates, s32 *rates, int max)
3791{
3792 hermes_t *hw = &priv->hw;
3793 struct hermes_idstring list;
3794 unsigned char *p = (unsigned char *)&list.val;
3795 int err = 0;
3796 int num;
3797 int i;
3798 unsigned long flags;
3799
3800 if (orinoco_lock(priv, &flags) != 0)
3801 return -EBUSY;
3802
3803 err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_SUPPORTEDDATARATES,
3804 sizeof(list), NULL, &list);
3805 orinoco_unlock(priv, &flags);
3806
3807 if (err)
3808 return err;
3809
3810 num = le16_to_cpu(list.len);
3811 *numrates = num;
3812 num = min(num, max);
3813
3814 for (i = 0; i < num; i++) {
3815 rates[i] = (p[i] & 0x7f) * 500000; /* convert to bps */
3816 }
3817
3818 return 0;
3819}
3820
3821static int orinoco_ioctl_getname(struct net_device *dev,
3822 struct iw_request_info *info,
3823 char *name,
3824 char *extra)
3825{
3826 struct orinoco_private *priv = netdev_priv(dev);
3827 int numrates;
3828 int err;
3829
3830 err = orinoco_hw_get_bitratelist(priv, &numrates, NULL, 0);
3831
3832 if (!err && (numrates > 2))
3833 strcpy(name, "IEEE 802.11b");
3834 else
3835 strcpy(name, "IEEE 802.11-DS");
3836
3837 return 0;
3838}
3839
3840static int orinoco_ioctl_setwap(struct net_device *dev,
3841 struct iw_request_info *info,
3842 struct sockaddr *ap_addr,
3843 char *extra)
3844{
3845 struct orinoco_private *priv = netdev_priv(dev);
3846 int err = -EINPROGRESS; /* Call commit handler */
3847 unsigned long flags;
3848 static const u8 off_addr[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
3849 static const u8 any_addr[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
3850
3851 if (orinoco_lock(priv, &flags) != 0)
3852 return -EBUSY;
3853
3854 /* Enable automatic roaming - no sanity checks are needed */
3855 if (memcmp(&ap_addr->sa_data, off_addr, ETH_ALEN) == 0 ||
3856 memcmp(&ap_addr->sa_data, any_addr, ETH_ALEN) == 0) {
3857 priv->bssid_fixed = 0;
3858 memset(priv->desired_bssid, 0, ETH_ALEN);
3859
3860 /* "off" means keep existing connection */
3861 if (ap_addr->sa_data[0] == 0) {
3862 __orinoco_hw_set_wap(priv);
3863 err = 0;
3864 }
3865 goto out;
3866 }
3867
3868 if (priv->firmware_type == FIRMWARE_TYPE_AGERE) {
3869 printk(KERN_WARNING "%s: Lucent/Agere firmware doesn't "
3870 "support manual roaming\n",
3871 dev->name);
3872 err = -EOPNOTSUPP;
3873 goto out;
3874 }
3875
3876 if (priv->iw_mode != IW_MODE_INFRA) {
3877 printk(KERN_WARNING "%s: Manual roaming supported only in "
3878 "managed mode\n", dev->name);
3879 err = -EOPNOTSUPP;
3880 goto out;
3881 }
3882
3883 /* Intersil firmware hangs without Desired ESSID */
3884 if (priv->firmware_type == FIRMWARE_TYPE_INTERSIL &&
3885 strlen(priv->desired_essid) == 0) {
3886 printk(KERN_WARNING "%s: Desired ESSID must be set for "
3887 "manual roaming\n", dev->name);
3888 err = -EOPNOTSUPP;
3889 goto out;
3890 }
3891
3892 /* Finally, enable manual roaming */
3893 priv->bssid_fixed = 1;
3894 memcpy(priv->desired_bssid, &ap_addr->sa_data, ETH_ALEN);
3895
3896 out:
3897 orinoco_unlock(priv, &flags);
3898 return err;
3899}
3900
3901static int orinoco_ioctl_getwap(struct net_device *dev,
3902 struct iw_request_info *info,
3903 struct sockaddr *ap_addr,
3904 char *extra)
3905{
3906 struct orinoco_private *priv = netdev_priv(dev);
3907
3908 hermes_t *hw = &priv->hw;
3909 int err = 0;
3910 unsigned long flags;
3911
3912 if (orinoco_lock(priv, &flags) != 0)
3913 return -EBUSY;
3914
3915 ap_addr->sa_family = ARPHRD_ETHER;
3916 err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CURRENTBSSID,
3917 ETH_ALEN, NULL, ap_addr->sa_data);
3918
3919 orinoco_unlock(priv, &flags);
3920
3921 return err;
3922}
3923
3924static int orinoco_ioctl_setmode(struct net_device *dev,
3925 struct iw_request_info *info,
3926 u32 *mode,
3927 char *extra)
3928{
3929 struct orinoco_private *priv = netdev_priv(dev);
3930 int err = -EINPROGRESS; /* Call commit handler */
3931 unsigned long flags;
3932
3933 if (priv->iw_mode == *mode)
3934 return 0;
3935
3936 if (orinoco_lock(priv, &flags) != 0)
3937 return -EBUSY;
3938
3939 switch (*mode) {
3940 case IW_MODE_ADHOC:
3941 if (!priv->has_ibss && !priv->has_port3)
3942 err = -EOPNOTSUPP;
3943 break;
3944
3945 case IW_MODE_INFRA:
3946 break;
3947
3948 case IW_MODE_MONITOR:
3949 if (priv->broken_monitor && !force_monitor) {
3950 printk(KERN_WARNING "%s: Monitor mode support is "
3951 "buggy in this firmware, not enabling\n",
3952 dev->name);
3953 err = -EOPNOTSUPP;
3954 }
3955 break;
3956
3957 default:
3958 err = -EOPNOTSUPP;
3959 break;
3960 }
3961
3962 if (err == -EINPROGRESS) {
3963 priv->iw_mode = *mode;
3964 set_port_type(priv);
3965 }
3966
3967 orinoco_unlock(priv, &flags);
3968
3969 return err;
3970}
3971
3972static int orinoco_ioctl_getmode(struct net_device *dev,
3973 struct iw_request_info *info,
3974 u32 *mode,
3975 char *extra)
3976{
3977 struct orinoco_private *priv = netdev_priv(dev);
3978
3979 *mode = priv->iw_mode;
3980 return 0;
3981}
3982
3983static int orinoco_ioctl_getiwrange(struct net_device *dev,
3984 struct iw_request_info *info,
3985 struct iw_point *rrq,
3986 char *extra)
3987{
3988 struct orinoco_private *priv = netdev_priv(dev);
3989 int err = 0;
3990 struct iw_range *range = (struct iw_range *) extra;
3991 int numrates;
3992 int i, k;
3993
3994 rrq->length = sizeof(struct iw_range);
3995 memset(range, 0, sizeof(struct iw_range));
3996
3997 range->we_version_compiled = WIRELESS_EXT;
3998 range->we_version_source = 22;
3999
4000 /* Set available channels/frequencies */
4001 range->num_channels = NUM_CHANNELS;
4002 k = 0;
4003 for (i = 0; i < NUM_CHANNELS; i++) {
4004 if (priv->channel_mask & (1 << i)) {
4005 range->freq[k].i = i + 1;
4006 range->freq[k].m = (ieee80211_dsss_chan_to_freq(i + 1) *
4007 100000);
4008 range->freq[k].e = 1;
4009 k++;
4010 }
4011
4012 if (k >= IW_MAX_FREQUENCIES)
4013 break;
4014 }
4015 range->num_frequency = k;
4016 range->sensitivity = 3;
4017
4018 if (priv->has_wep) {
4019 range->max_encoding_tokens = ORINOCO_MAX_KEYS;
4020 range->encoding_size[0] = SMALL_KEY_SIZE;
4021 range->num_encoding_sizes = 1;
4022
4023 if (priv->has_big_wep) {
4024 range->encoding_size[1] = LARGE_KEY_SIZE;
4025 range->num_encoding_sizes = 2;
4026 }
4027 }
4028
4029 if (priv->has_wpa)
4030 range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_CIPHER_TKIP;
4031
4032 if ((priv->iw_mode == IW_MODE_ADHOC) && (!SPY_NUMBER(priv))){
4033 /* Quality stats meaningless in ad-hoc mode */
4034 } else {
4035 range->max_qual.qual = 0x8b - 0x2f;
4036 range->max_qual.level = 0x2f - 0x95 - 1;
4037 range->max_qual.noise = 0x2f - 0x95 - 1;
4038 /* Need to get better values */
4039 range->avg_qual.qual = 0x24;
4040 range->avg_qual.level = 0xC2;
4041 range->avg_qual.noise = 0x9E;
4042 }
4043
4044 err = orinoco_hw_get_bitratelist(priv, &numrates,
4045 range->bitrate, IW_MAX_BITRATES);
4046 if (err)
4047 return err;
4048 range->num_bitrates = numrates;
4049
4050 /* Set an indication of the max TCP throughput in bit/s that we can
4051 * expect using this interface. May be use for QoS stuff...
4052 * Jean II */
4053 if (numrates > 2)
4054 range->throughput = 5 * 1000 * 1000; /* ~5 Mb/s */
4055 else
4056 range->throughput = 1.5 * 1000 * 1000; /* ~1.5 Mb/s */
4057
4058 range->min_rts = 0;
4059 range->max_rts = 2347;
4060 range->min_frag = 256;
4061 range->max_frag = 2346;
4062
4063 range->min_pmp = 0;
4064 range->max_pmp = 65535000;
4065 range->min_pmt = 0;
4066 range->max_pmt = 65535 * 1000; /* ??? */
4067 range->pmp_flags = IW_POWER_PERIOD;
4068 range->pmt_flags = IW_POWER_TIMEOUT;
4069 range->pm_capa = IW_POWER_PERIOD | IW_POWER_TIMEOUT | IW_POWER_UNICAST_R;
4070
4071 range->retry_capa = IW_RETRY_LIMIT | IW_RETRY_LIFETIME;
4072 range->retry_flags = IW_RETRY_LIMIT;
4073 range->r_time_flags = IW_RETRY_LIFETIME;
4074 range->min_retry = 0;
4075 range->max_retry = 65535; /* ??? */
4076 range->min_r_time = 0;
4077 range->max_r_time = 65535 * 1000; /* ??? */
4078
4079 if (priv->firmware_type == FIRMWARE_TYPE_AGERE)
4080 range->scan_capa = IW_SCAN_CAPA_ESSID;
4081 else
4082 range->scan_capa = IW_SCAN_CAPA_NONE;
4083
4084 /* Event capability (kernel) */
4085 IW_EVENT_CAPA_SET_KERNEL(range->event_capa);
4086 /* Event capability (driver) */
4087 IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWTHRSPY);
4088 IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWAP);
4089 IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWSCAN);
4090 IW_EVENT_CAPA_SET(range->event_capa, IWEVTXDROP);
4091
4092 return 0;
4093}
4094
4095static int orinoco_ioctl_setiwencode(struct net_device *dev,
4096 struct iw_request_info *info,
4097 struct iw_point *erq,
4098 char *keybuf)
4099{
4100 struct orinoco_private *priv = netdev_priv(dev);
4101 int index = (erq->flags & IW_ENCODE_INDEX) - 1;
4102 int setindex = priv->tx_key;
4103 int encode_alg = priv->encode_alg;
4104 int restricted = priv->wep_restrict;
4105 u16 xlen = 0;
4106 int err = -EINPROGRESS; /* Call commit handler */
4107 unsigned long flags;
4108
4109 if (! priv->has_wep)
4110 return -EOPNOTSUPP;
4111
4112 if (erq->pointer) {
4113 /* We actually have a key to set - check its length */
4114 if (erq->length > LARGE_KEY_SIZE)
4115 return -E2BIG;
4116
4117 if ( (erq->length > SMALL_KEY_SIZE) && !priv->has_big_wep )
4118 return -E2BIG;
4119 }
4120
4121 if (orinoco_lock(priv, &flags) != 0)
4122 return -EBUSY;
4123
4124 /* Clear any TKIP key we have */
4125 if ((priv->has_wpa) && (priv->encode_alg == IW_ENCODE_ALG_TKIP))
4126 (void) orinoco_clear_tkip_key(priv, setindex);
4127
4128 if (erq->length > 0) {
4129 if ((index < 0) || (index >= ORINOCO_MAX_KEYS))
4130 index = priv->tx_key;
4131
4132 /* Adjust key length to a supported value */
4133 if (erq->length > SMALL_KEY_SIZE) {
4134 xlen = LARGE_KEY_SIZE;
4135 } else if (erq->length > 0) {
4136 xlen = SMALL_KEY_SIZE;
4137 } else
4138 xlen = 0;
4139
4140 /* Switch on WEP if off */
4141 if ((encode_alg != IW_ENCODE_ALG_WEP) && (xlen > 0)) {
4142 setindex = index;
4143 encode_alg = IW_ENCODE_ALG_WEP;
4144 }
4145 } else {
4146 /* Important note : if the user do "iwconfig eth0 enc off",
4147 * we will arrive there with an index of -1. This is valid
4148 * but need to be taken care off... Jean II */
4149 if ((index < 0) || (index >= ORINOCO_MAX_KEYS)) {
4150 if((index != -1) || (erq->flags == 0)) {
4151 err = -EINVAL;
4152 goto out;
4153 }
4154 } else {
4155 /* Set the index : Check that the key is valid */
4156 if(priv->keys[index].len == 0) {
4157 err = -EINVAL;
4158 goto out;
4159 }
4160 setindex = index;
4161 }
4162 }
4163
4164 if (erq->flags & IW_ENCODE_DISABLED)
4165 encode_alg = IW_ENCODE_ALG_NONE;
4166 if (erq->flags & IW_ENCODE_OPEN)
4167 restricted = 0;
4168 if (erq->flags & IW_ENCODE_RESTRICTED)
4169 restricted = 1;
4170
4171 if (erq->pointer && erq->length > 0) {
4172 priv->keys[index].len = cpu_to_le16(xlen);
4173 memset(priv->keys[index].data, 0,
4174 sizeof(priv->keys[index].data));
4175 memcpy(priv->keys[index].data, keybuf, erq->length);
4176 }
4177 priv->tx_key = setindex;
4178
4179 /* Try fast key change if connected and only keys are changed */
4180 if ((priv->encode_alg == encode_alg) &&
4181 (priv->wep_restrict == restricted) &&
4182 netif_carrier_ok(dev)) {
4183 err = __orinoco_hw_setup_wepkeys(priv);
4184 /* No need to commit if successful */
4185 goto out;
4186 }
4187
4188 priv->encode_alg = encode_alg;
4189 priv->wep_restrict = restricted;
4190
4191 out:
4192 orinoco_unlock(priv, &flags);
4193
4194 return err;
4195}
4196
4197static int orinoco_ioctl_getiwencode(struct net_device *dev,
4198 struct iw_request_info *info,
4199 struct iw_point *erq,
4200 char *keybuf)
4201{
4202 struct orinoco_private *priv = netdev_priv(dev);
4203 int index = (erq->flags & IW_ENCODE_INDEX) - 1;
4204 u16 xlen = 0;
4205 unsigned long flags;
4206
4207 if (! priv->has_wep)
4208 return -EOPNOTSUPP;
4209
4210 if (orinoco_lock(priv, &flags) != 0)
4211 return -EBUSY;
4212
4213 if ((index < 0) || (index >= ORINOCO_MAX_KEYS))
4214 index = priv->tx_key;
4215
4216 erq->flags = 0;
4217 if (!priv->encode_alg)
4218 erq->flags |= IW_ENCODE_DISABLED;
4219 erq->flags |= index + 1;
4220
4221 if (priv->wep_restrict)
4222 erq->flags |= IW_ENCODE_RESTRICTED;
4223 else
4224 erq->flags |= IW_ENCODE_OPEN;
4225
4226 xlen = le16_to_cpu(priv->keys[index].len);
4227
4228 erq->length = xlen;
4229
4230 memcpy(keybuf, priv->keys[index].data, ORINOCO_MAX_KEY_SIZE);
4231
4232 orinoco_unlock(priv, &flags);
4233 return 0;
4234}
4235
4236static int orinoco_ioctl_setessid(struct net_device *dev,
4237 struct iw_request_info *info,
4238 struct iw_point *erq,
4239 char *essidbuf)
4240{
4241 struct orinoco_private *priv = netdev_priv(dev);
4242 unsigned long flags;
4243
4244 /* Note : ESSID is ignored in Ad-Hoc demo mode, but we can set it
4245 * anyway... - Jean II */
4246
4247 /* Hum... Should not use Wireless Extension constant (may change),
4248 * should use our own... - Jean II */
4249 if (erq->length > IW_ESSID_MAX_SIZE)
4250 return -E2BIG;
4251
4252 if (orinoco_lock(priv, &flags) != 0)
4253 return -EBUSY;
4254
4255 /* NULL the string (for NULL termination & ESSID = ANY) - Jean II */
4256 memset(priv->desired_essid, 0, sizeof(priv->desired_essid));
4257
4258 /* If not ANY, get the new ESSID */
4259 if (erq->flags) {
4260 memcpy(priv->desired_essid, essidbuf, erq->length);
4261 }
4262
4263 orinoco_unlock(priv, &flags);
4264
4265 return -EINPROGRESS; /* Call commit handler */
4266}
4267
4268static int orinoco_ioctl_getessid(struct net_device *dev,
4269 struct iw_request_info *info,
4270 struct iw_point *erq,
4271 char *essidbuf)
4272{
4273 struct orinoco_private *priv = netdev_priv(dev);
4274 int active;
4275 int err = 0;
4276 unsigned long flags;
4277
4278 if (netif_running(dev)) {
4279 err = orinoco_hw_get_essid(priv, &active, essidbuf);
4280 if (err < 0)
4281 return err;
4282 erq->length = err;
4283 } else {
4284 if (orinoco_lock(priv, &flags) != 0)
4285 return -EBUSY;
4286 memcpy(essidbuf, priv->desired_essid, IW_ESSID_MAX_SIZE);
4287 erq->length = strlen(priv->desired_essid);
4288 orinoco_unlock(priv, &flags);
4289 }
4290
4291 erq->flags = 1;
4292
4293 return 0;
4294}
4295
4296static int orinoco_ioctl_setnick(struct net_device *dev,
4297 struct iw_request_info *info,
4298 struct iw_point *nrq,
4299 char *nickbuf)
4300{
4301 struct orinoco_private *priv = netdev_priv(dev);
4302 unsigned long flags;
4303
4304 if (nrq->length > IW_ESSID_MAX_SIZE)
4305 return -E2BIG;
4306
4307 if (orinoco_lock(priv, &flags) != 0)
4308 return -EBUSY;
4309
4310 memset(priv->nick, 0, sizeof(priv->nick));
4311 memcpy(priv->nick, nickbuf, nrq->length);
4312
4313 orinoco_unlock(priv, &flags);
4314
4315 return -EINPROGRESS; /* Call commit handler */
4316}
4317
4318static int orinoco_ioctl_getnick(struct net_device *dev,
4319 struct iw_request_info *info,
4320 struct iw_point *nrq,
4321 char *nickbuf)
4322{
4323 struct orinoco_private *priv = netdev_priv(dev);
4324 unsigned long flags;
4325
4326 if (orinoco_lock(priv, &flags) != 0)
4327 return -EBUSY;
4328
4329 memcpy(nickbuf, priv->nick, IW_ESSID_MAX_SIZE);
4330 orinoco_unlock(priv, &flags);
4331
4332 nrq->length = strlen(priv->nick);
4333
4334 return 0;
4335}
4336
4337static int orinoco_ioctl_setfreq(struct net_device *dev,
4338 struct iw_request_info *info,
4339 struct iw_freq *frq,
4340 char *extra)
4341{
4342 struct orinoco_private *priv = netdev_priv(dev);
4343 int chan = -1;
4344 unsigned long flags;
4345 int err = -EINPROGRESS; /* Call commit handler */
4346
4347 /* In infrastructure mode the AP sets the channel */
4348 if (priv->iw_mode == IW_MODE_INFRA)
4349 return -EBUSY;
4350
4351 if ( (frq->e == 0) && (frq->m <= 1000) ) {
4352 /* Setting by channel number */
4353 chan = frq->m;
4354 } else {
4355 /* Setting by frequency */
4356 int denom = 1;
4357 int i;
4358
4359 /* Calculate denominator to rescale to MHz */
4360 for (i = 0; i < (6 - frq->e); i++)
4361 denom *= 10;
4362
4363 chan = ieee80211_freq_to_dsss_chan(frq->m / denom);
4364 }
4365
4366 if ( (chan < 1) || (chan > NUM_CHANNELS) ||
4367 ! (priv->channel_mask & (1 << (chan-1)) ) )
4368 return -EINVAL;
4369
4370 if (orinoco_lock(priv, &flags) != 0)
4371 return -EBUSY;
4372
4373 priv->channel = chan;
4374 if (priv->iw_mode == IW_MODE_MONITOR) {
4375 /* Fast channel change - no commit if successful */
4376 hermes_t *hw = &priv->hw;
4377 err = hermes_docmd_wait(hw, HERMES_CMD_TEST |
4378 HERMES_TEST_SET_CHANNEL,
4379 chan, NULL);
4380 }
4381 orinoco_unlock(priv, &flags);
4382
4383 return err;
4384}
4385
4386static int orinoco_ioctl_getfreq(struct net_device *dev,
4387 struct iw_request_info *info,
4388 struct iw_freq *frq,
4389 char *extra)
4390{
4391 struct orinoco_private *priv = netdev_priv(dev);
4392 int tmp;
4393
4394 /* Locking done in there */
4395 tmp = orinoco_hw_get_freq(priv);
4396 if (tmp < 0) {
4397 return tmp;
4398 }
4399
4400 frq->m = tmp * 100000;
4401 frq->e = 1;
4402
4403 return 0;
4404}
4405
4406static int orinoco_ioctl_getsens(struct net_device *dev,
4407 struct iw_request_info *info,
4408 struct iw_param *srq,
4409 char *extra)
4410{
4411 struct orinoco_private *priv = netdev_priv(dev);
4412 hermes_t *hw = &priv->hw;
4413 u16 val;
4414 int err;
4415 unsigned long flags;
4416
4417 if (!priv->has_sensitivity)
4418 return -EOPNOTSUPP;
4419
4420 if (orinoco_lock(priv, &flags) != 0)
4421 return -EBUSY;
4422 err = hermes_read_wordrec(hw, USER_BAP,
4423 HERMES_RID_CNFSYSTEMSCALE, &val);
4424 orinoco_unlock(priv, &flags);
4425
4426 if (err)
4427 return err;
4428
4429 srq->value = val;
4430 srq->fixed = 0; /* auto */
4431
4432 return 0;
4433}
4434
4435static int orinoco_ioctl_setsens(struct net_device *dev,
4436 struct iw_request_info *info,
4437 struct iw_param *srq,
4438 char *extra)
4439{
4440 struct orinoco_private *priv = netdev_priv(dev);
4441 int val = srq->value;
4442 unsigned long flags;
4443
4444 if (!priv->has_sensitivity)
4445 return -EOPNOTSUPP;
4446
4447 if ((val < 1) || (val > 3))
4448 return -EINVAL;
4449
4450 if (orinoco_lock(priv, &flags) != 0)
4451 return -EBUSY;
4452 priv->ap_density = val;
4453 orinoco_unlock(priv, &flags);
4454
4455 return -EINPROGRESS; /* Call commit handler */
4456}
4457
4458static int orinoco_ioctl_setrts(struct net_device *dev,
4459 struct iw_request_info *info,
4460 struct iw_param *rrq,
4461 char *extra)
4462{
4463 struct orinoco_private *priv = netdev_priv(dev);
4464 int val = rrq->value;
4465 unsigned long flags;
4466
4467 if (rrq->disabled)
4468 val = 2347;
4469
4470 if ( (val < 0) || (val > 2347) )
4471 return -EINVAL;
4472
4473 if (orinoco_lock(priv, &flags) != 0)
4474 return -EBUSY;
4475
4476 priv->rts_thresh = val;
4477 orinoco_unlock(priv, &flags);
4478
4479 return -EINPROGRESS; /* Call commit handler */
4480}
4481
4482static int orinoco_ioctl_getrts(struct net_device *dev,
4483 struct iw_request_info *info,
4484 struct iw_param *rrq,
4485 char *extra)
4486{
4487 struct orinoco_private *priv = netdev_priv(dev);
4488
4489 rrq->value = priv->rts_thresh;
4490 rrq->disabled = (rrq->value == 2347);
4491 rrq->fixed = 1;
4492
4493 return 0;
4494}
4495
4496static int orinoco_ioctl_setfrag(struct net_device *dev,
4497 struct iw_request_info *info,
4498 struct iw_param *frq,
4499 char *extra)
4500{
4501 struct orinoco_private *priv = netdev_priv(dev);
4502 int err = -EINPROGRESS; /* Call commit handler */
4503 unsigned long flags;
4504
4505 if (orinoco_lock(priv, &flags) != 0)
4506 return -EBUSY;
4507
4508 if (priv->has_mwo) {
4509 if (frq->disabled)
4510 priv->mwo_robust = 0;
4511 else {
4512 if (frq->fixed)
4513 printk(KERN_WARNING "%s: Fixed fragmentation is "
4514 "not supported on this firmware. "
4515 "Using MWO robust instead.\n", dev->name);
4516 priv->mwo_robust = 1;
4517 }
4518 } else {
4519 if (frq->disabled)
4520 priv->frag_thresh = 2346;
4521 else {
4522 if ( (frq->value < 256) || (frq->value > 2346) )
4523 err = -EINVAL;
4524 else
4525 priv->frag_thresh = frq->value & ~0x1; /* must be even */
4526 }
4527 }
4528
4529 orinoco_unlock(priv, &flags);
4530
4531 return err;
4532}
4533
4534static int orinoco_ioctl_getfrag(struct net_device *dev,
4535 struct iw_request_info *info,
4536 struct iw_param *frq,
4537 char *extra)
4538{
4539 struct orinoco_private *priv = netdev_priv(dev);
4540 hermes_t *hw = &priv->hw;
4541 int err;
4542 u16 val;
4543 unsigned long flags;
4544
4545 if (orinoco_lock(priv, &flags) != 0)
4546 return -EBUSY;
4547
4548 if (priv->has_mwo) {
4549 err = hermes_read_wordrec(hw, USER_BAP,
4550 HERMES_RID_CNFMWOROBUST_AGERE,
4551 &val);
4552 if (err)
4553 val = 0;
4554
4555 frq->value = val ? 2347 : 0;
4556 frq->disabled = ! val;
4557 frq->fixed = 0;
4558 } else {
4559 err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFFRAGMENTATIONTHRESHOLD,
4560 &val);
4561 if (err)
4562 val = 0;
4563
4564 frq->value = val;
4565 frq->disabled = (val >= 2346);
4566 frq->fixed = 1;
4567 }
4568
4569 orinoco_unlock(priv, &flags);
4570
4571 return err;
4572}
4573
4574static int orinoco_ioctl_setrate(struct net_device *dev,
4575 struct iw_request_info *info,
4576 struct iw_param *rrq,
4577 char *extra)
4578{
4579 struct orinoco_private *priv = netdev_priv(dev);
4580 int ratemode = -1;
4581 int bitrate; /* 100s of kilobits */
4582 int i;
4583 unsigned long flags;
4584
4585 /* As the user space doesn't know our highest rate, it uses -1
4586 * to ask us to set the highest rate. Test it using "iwconfig
4587 * ethX rate auto" - Jean II */
4588 if (rrq->value == -1)
4589 bitrate = 110;
4590 else {
4591 if (rrq->value % 100000)
4592 return -EINVAL;
4593 bitrate = rrq->value / 100000;
4594 }
4595
4596 if ( (bitrate != 10) && (bitrate != 20) &&
4597 (bitrate != 55) && (bitrate != 110) )
4598 return -EINVAL;
4599
4600 for (i = 0; i < BITRATE_TABLE_SIZE; i++)
4601 if ( (bitrate_table[i].bitrate == bitrate) &&
4602 (bitrate_table[i].automatic == ! rrq->fixed) ) {
4603 ratemode = i;
4604 break;
4605 }
4606
4607 if (ratemode == -1)
4608 return -EINVAL;
4609
4610 if (orinoco_lock(priv, &flags) != 0)
4611 return -EBUSY;
4612 priv->bitratemode = ratemode;
4613 orinoco_unlock(priv, &flags);
4614
4615 return -EINPROGRESS;
4616}
4617
4618static int orinoco_ioctl_getrate(struct net_device *dev,
4619 struct iw_request_info *info,
4620 struct iw_param *rrq,
4621 char *extra)
4622{
4623 struct orinoco_private *priv = netdev_priv(dev);
4624 hermes_t *hw = &priv->hw;
4625 int err = 0;
4626 int ratemode;
4627 int i;
4628 u16 val;
4629 unsigned long flags;
4630
4631 if (orinoco_lock(priv, &flags) != 0)
4632 return -EBUSY;
4633
4634 ratemode = priv->bitratemode;
4635
4636 BUG_ON((ratemode < 0) || (ratemode >= BITRATE_TABLE_SIZE));
4637
4638 rrq->value = bitrate_table[ratemode].bitrate * 100000;
4639 rrq->fixed = ! bitrate_table[ratemode].automatic;
4640 rrq->disabled = 0;
4641
4642 /* If the interface is running we try to find more about the
4643 current mode */
4644 if (netif_running(dev)) {
4645 err = hermes_read_wordrec(hw, USER_BAP,
4646 HERMES_RID_CURRENTTXRATE, &val);
4647 if (err)
4648 goto out;
4649
4650 switch (priv->firmware_type) {
4651 case FIRMWARE_TYPE_AGERE: /* Lucent style rate */
4652 /* Note : in Lucent firmware, the return value of
4653 * HERMES_RID_CURRENTTXRATE is the bitrate in Mb/s,
4654 * and therefore is totally different from the
4655 * encoding of HERMES_RID_CNFTXRATECONTROL.
4656 * Don't forget that 6Mb/s is really 5.5Mb/s */
4657 if (val == 6)
4658 rrq->value = 5500000;
4659 else
4660 rrq->value = val * 1000000;
4661 break;
4662 case FIRMWARE_TYPE_INTERSIL: /* Intersil style rate */
4663 case FIRMWARE_TYPE_SYMBOL: /* Symbol style rate */
4664 for (i = 0; i < BITRATE_TABLE_SIZE; i++)
4665 if (bitrate_table[i].intersil_txratectrl == val) {
4666 ratemode = i;
4667 break;
4668 }
4669 if (i >= BITRATE_TABLE_SIZE)
4670 printk(KERN_INFO "%s: Unable to determine current bitrate (0x%04hx)\n",
4671 dev->name, val);
4672
4673 rrq->value = bitrate_table[ratemode].bitrate * 100000;
4674 break;
4675 default:
4676 BUG();
4677 }
4678 }
4679
4680 out:
4681 orinoco_unlock(priv, &flags);
4682
4683 return err;
4684}
4685
4686static int orinoco_ioctl_setpower(struct net_device *dev,
4687 struct iw_request_info *info,
4688 struct iw_param *prq,
4689 char *extra)
4690{
4691 struct orinoco_private *priv = netdev_priv(dev);
4692 int err = -EINPROGRESS; /* Call commit handler */
4693 unsigned long flags;
4694
4695 if (orinoco_lock(priv, &flags) != 0)
4696 return -EBUSY;
4697
4698 if (prq->disabled) {
4699 priv->pm_on = 0;
4700 } else {
4701 switch (prq->flags & IW_POWER_MODE) {
4702 case IW_POWER_UNICAST_R:
4703 priv->pm_mcast = 0;
4704 priv->pm_on = 1;
4705 break;
4706 case IW_POWER_ALL_R:
4707 priv->pm_mcast = 1;
4708 priv->pm_on = 1;
4709 break;
4710 case IW_POWER_ON:
4711 /* No flags : but we may have a value - Jean II */
4712 break;
4713 default:
4714 err = -EINVAL;
4715 goto out;
4716 }
4717
4718 if (prq->flags & IW_POWER_TIMEOUT) {
4719 priv->pm_on = 1;
4720 priv->pm_timeout = prq->value / 1000;
4721 }
4722 if (prq->flags & IW_POWER_PERIOD) {
4723 priv->pm_on = 1;
4724 priv->pm_period = prq->value / 1000;
4725 }
4726 /* It's valid to not have a value if we are just toggling
4727 * the flags... Jean II */
4728 if(!priv->pm_on) {
4729 err = -EINVAL;
4730 goto out;
4731 }
4732 }
4733
4734 out:
4735 orinoco_unlock(priv, &flags);
4736
4737 return err;
4738}
4739
4740static int orinoco_ioctl_getpower(struct net_device *dev,
4741 struct iw_request_info *info,
4742 struct iw_param *prq,
4743 char *extra)
4744{
4745 struct orinoco_private *priv = netdev_priv(dev);
4746 hermes_t *hw = &priv->hw;
4747 int err = 0;
4748 u16 enable, period, timeout, mcast;
4749 unsigned long flags;
4750
4751 if (orinoco_lock(priv, &flags) != 0)
4752 return -EBUSY;
4753
4754 err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFPMENABLED, &enable);
4755 if (err)
4756 goto out;
4757
4758 err = hermes_read_wordrec(hw, USER_BAP,
4759 HERMES_RID_CNFMAXSLEEPDURATION, &period);
4760 if (err)
4761 goto out;
4762
4763 err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFPMHOLDOVERDURATION, &timeout);
4764 if (err)
4765 goto out;
4766
4767 err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFMULTICASTRECEIVE, &mcast);
4768 if (err)
4769 goto out;
4770
4771 prq->disabled = !enable;
4772 /* Note : by default, display the period */
4773 if ((prq->flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) {
4774 prq->flags = IW_POWER_TIMEOUT;
4775 prq->value = timeout * 1000;
4776 } else {
4777 prq->flags = IW_POWER_PERIOD;
4778 prq->value = period * 1000;
4779 }
4780 if (mcast)
4781 prq->flags |= IW_POWER_ALL_R;
4782 else
4783 prq->flags |= IW_POWER_UNICAST_R;
4784
4785 out:
4786 orinoco_unlock(priv, &flags);
4787
4788 return err;
4789}
4790
4791static int orinoco_ioctl_set_encodeext(struct net_device *dev,
4792 struct iw_request_info *info,
4793 union iwreq_data *wrqu,
4794 char *extra)
4795{
4796 struct orinoco_private *priv = netdev_priv(dev);
4797 struct iw_point *encoding = &wrqu->encoding;
4798 struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
4799 int idx, alg = ext->alg, set_key = 1;
4800 unsigned long flags;
4801 int err = -EINVAL;
4802 u16 key_len;
4803
4804 if (orinoco_lock(priv, &flags) != 0)
4805 return -EBUSY;
4806
4807 /* Determine and validate the key index */
4808 idx = encoding->flags & IW_ENCODE_INDEX;
4809 if (idx) {
4810 if ((idx < 1) || (idx > 4))
4811 goto out;
4812 idx--;
4813 } else
4814 idx = priv->tx_key;
4815
4816 if (encoding->flags & IW_ENCODE_DISABLED)
4817 alg = IW_ENCODE_ALG_NONE;
4818
4819 if (priv->has_wpa && (alg != IW_ENCODE_ALG_TKIP)) {
4820 /* Clear any TKIP TX key we had */
4821 (void) orinoco_clear_tkip_key(priv, priv->tx_key);
4822 }
4823
4824 if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
4825 priv->tx_key = idx;
4826 set_key = ((alg == IW_ENCODE_ALG_TKIP) ||
4827 (ext->key_len > 0)) ? 1 : 0;
4828 }
4829
4830 if (set_key) {
4831 /* Set the requested key first */
4832 switch (alg) {
4833 case IW_ENCODE_ALG_NONE:
4834 priv->encode_alg = alg;
4835 priv->keys[idx].len = 0;
4836 break;
4837
4838 case IW_ENCODE_ALG_WEP:
4839 if (ext->key_len > SMALL_KEY_SIZE)
4840 key_len = LARGE_KEY_SIZE;
4841 else if (ext->key_len > 0)
4842 key_len = SMALL_KEY_SIZE;
4843 else
4844 goto out;
4845
4846 priv->encode_alg = alg;
4847 priv->keys[idx].len = cpu_to_le16(key_len);
4848
4849 key_len = min(ext->key_len, key_len);
4850
4851 memset(priv->keys[idx].data, 0, ORINOCO_MAX_KEY_SIZE);
4852 memcpy(priv->keys[idx].data, ext->key, key_len);
4853 break;
4854
4855 case IW_ENCODE_ALG_TKIP:
4856 {
4857 hermes_t *hw = &priv->hw;
4858 u8 *tkip_iv = NULL;
4859
4860 if (!priv->has_wpa ||
4861 (ext->key_len > sizeof(priv->tkip_key[0])))
4862 goto out;
4863
4864 priv->encode_alg = alg;
4865 memset(&priv->tkip_key[idx], 0,
4866 sizeof(priv->tkip_key[idx]));
4867 memcpy(&priv->tkip_key[idx], ext->key, ext->key_len);
4868
4869 if (ext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID)
4870 tkip_iv = &ext->rx_seq[0];
4871
4872 err = __orinoco_hw_set_tkip_key(hw, idx,
4873 ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY,
4874 (u8 *) &priv->tkip_key[idx],
4875 tkip_iv, NULL);
4876 if (err)
4877 printk(KERN_ERR "%s: Error %d setting TKIP key"
4878 "\n", dev->name, err);
4879
4880 goto out;
4881 }
4882 default:
4883 goto out;
4884 }
4885 }
4886 err = -EINPROGRESS;
4887 out:
4888 orinoco_unlock(priv, &flags);
4889
4890 return err;
4891}
4892
4893static int orinoco_ioctl_get_encodeext(struct net_device *dev,
4894 struct iw_request_info *info,
4895 union iwreq_data *wrqu,
4896 char *extra)
4897{
4898 struct orinoco_private *priv = netdev_priv(dev);
4899 struct iw_point *encoding = &wrqu->encoding;
4900 struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
4901 int idx, max_key_len;
4902 unsigned long flags;
4903 int err;
4904
4905 if (orinoco_lock(priv, &flags) != 0)
4906 return -EBUSY;
4907
4908 err = -EINVAL;
4909 max_key_len = encoding->length - sizeof(*ext);
4910 if (max_key_len < 0)
4911 goto out;
4912
4913 idx = encoding->flags & IW_ENCODE_INDEX;
4914 if (idx) {
4915 if ((idx < 1) || (idx > 4))
4916 goto out;
4917 idx--;
4918 } else
4919 idx = priv->tx_key;
4920
4921 encoding->flags = idx + 1;
4922 memset(ext, 0, sizeof(*ext));
4923
4924 ext->alg = priv->encode_alg;
4925 switch (priv->encode_alg) {
4926 case IW_ENCODE_ALG_NONE:
4927 ext->key_len = 0;
4928 encoding->flags |= IW_ENCODE_DISABLED;
4929 break;
4930 case IW_ENCODE_ALG_WEP:
4931 ext->key_len = min_t(u16, le16_to_cpu(priv->keys[idx].len),
4932 max_key_len);
4933 memcpy(ext->key, priv->keys[idx].data, ext->key_len);
4934 encoding->flags |= IW_ENCODE_ENABLED;
4935 break;
4936 case IW_ENCODE_ALG_TKIP:
4937 ext->key_len = min_t(u16, sizeof(struct orinoco_tkip_key),
4938 max_key_len);
4939 memcpy(ext->key, &priv->tkip_key[idx], ext->key_len);
4940 encoding->flags |= IW_ENCODE_ENABLED;
4941 break;
4942 }
4943
4944 err = 0;
4945 out:
4946 orinoco_unlock(priv, &flags);
4947
4948 return err;
4949}
4950
4951static int orinoco_ioctl_set_auth(struct net_device *dev,
4952 struct iw_request_info *info,
4953 union iwreq_data *wrqu, char *extra)
4954{
4955 struct orinoco_private *priv = netdev_priv(dev);
4956 hermes_t *hw = &priv->hw;
4957 struct iw_param *param = &wrqu->param;
4958 unsigned long flags;
4959 int ret = -EINPROGRESS;
4960
4961 if (orinoco_lock(priv, &flags) != 0)
4962 return -EBUSY;
4963
4964 switch (param->flags & IW_AUTH_INDEX) {
4965 case IW_AUTH_WPA_VERSION:
4966 case IW_AUTH_CIPHER_PAIRWISE:
4967 case IW_AUTH_CIPHER_GROUP:
4968 case IW_AUTH_RX_UNENCRYPTED_EAPOL:
4969 case IW_AUTH_PRIVACY_INVOKED:
4970 case IW_AUTH_DROP_UNENCRYPTED:
4971 /*
4972 * orinoco does not use these parameters
4973 */
4974 break;
4975
4976 case IW_AUTH_KEY_MGMT:
4977 /* wl_lkm implies value 2 == PSK for Hermes I
4978 * which ties in with WEXT
4979 * no other hints tho :(
4980 */
4981 priv->key_mgmt = param->value;
4982 break;
4983
4984 case IW_AUTH_TKIP_COUNTERMEASURES:
4985 /* When countermeasures are enabled, shut down the
4986 * card; when disabled, re-enable the card. This must
4987 * take effect immediately.
4988 *
4989 * TODO: Make sure that the EAPOL message is getting
4990 * out before card disabled
4991 */
4992 if (param->value) {
4993 priv->tkip_cm_active = 1;
4994 ret = hermes_enable_port(hw, 0);
4995 } else {
4996 priv->tkip_cm_active = 0;
4997 ret = hermes_disable_port(hw, 0);
4998 }
4999 break;
5000
5001 case IW_AUTH_80211_AUTH_ALG:
5002 if (param->value & IW_AUTH_ALG_SHARED_KEY)
5003 priv->wep_restrict = 1;
5004 else if (param->value & IW_AUTH_ALG_OPEN_SYSTEM)
5005 priv->wep_restrict = 0;
5006 else
5007 ret = -EINVAL;
5008 break;
5009
5010 case IW_AUTH_WPA_ENABLED:
5011 if (priv->has_wpa) {
5012 priv->wpa_enabled = param->value ? 1 : 0;
5013 } else {
5014 if (param->value)
5015 ret = -EOPNOTSUPP;
5016 /* else silently accept disable of WPA */
5017 priv->wpa_enabled = 0;
5018 }
5019 break;
5020
5021 default:
5022 ret = -EOPNOTSUPP;
5023 }
5024
5025 orinoco_unlock(priv, &flags);
5026 return ret;
5027}
5028
5029static int orinoco_ioctl_get_auth(struct net_device *dev,
5030 struct iw_request_info *info,
5031 union iwreq_data *wrqu, char *extra)
5032{
5033 struct orinoco_private *priv = netdev_priv(dev);
5034 struct iw_param *param = &wrqu->param;
5035 unsigned long flags;
5036 int ret = 0;
5037
5038 if (orinoco_lock(priv, &flags) != 0)
5039 return -EBUSY;
5040
5041 switch (param->flags & IW_AUTH_INDEX) {
5042 case IW_AUTH_KEY_MGMT:
5043 param->value = priv->key_mgmt;
5044 break;
5045
5046 case IW_AUTH_TKIP_COUNTERMEASURES:
5047 param->value = priv->tkip_cm_active;
5048 break;
5049
5050 case IW_AUTH_80211_AUTH_ALG:
5051 if (priv->wep_restrict)
5052 param->value = IW_AUTH_ALG_SHARED_KEY;
5053 else
5054 param->value = IW_AUTH_ALG_OPEN_SYSTEM;
5055 break;
5056
5057 case IW_AUTH_WPA_ENABLED:
5058 param->value = priv->wpa_enabled;
5059 break;
5060
5061 default:
5062 ret = -EOPNOTSUPP;
5063 }
5064
5065 orinoco_unlock(priv, &flags);
5066 return ret;
5067}
5068
5069static int orinoco_ioctl_set_genie(struct net_device *dev,
5070 struct iw_request_info *info,
5071 union iwreq_data *wrqu, char *extra)
5072{
5073 struct orinoco_private *priv = netdev_priv(dev);
5074 u8 *buf;
5075 unsigned long flags;
5076
5077 /* cut off at IEEE80211_MAX_DATA_LEN */
5078 if ((wrqu->data.length > IEEE80211_MAX_DATA_LEN) ||
5079 (wrqu->data.length && (extra == NULL)))
5080 return -EINVAL;
5081
5082 if (wrqu->data.length) {
5083 buf = kmalloc(wrqu->data.length, GFP_KERNEL);
5084 if (buf == NULL)
5085 return -ENOMEM;
5086
5087 memcpy(buf, extra, wrqu->data.length);
5088 } else
5089 buf = NULL;
5090
5091 if (orinoco_lock(priv, &flags) != 0) {
5092 kfree(buf);
5093 return -EBUSY;
5094 }
5095
5096 kfree(priv->wpa_ie);
5097 priv->wpa_ie = buf;
5098 priv->wpa_ie_len = wrqu->data.length;
5099
5100 if (priv->wpa_ie) {
5101 /* Looks like wl_lkm wants to check the auth alg, and
5102 * somehow pass it to the firmware.
5103 * Instead it just calls the key mgmt rid
5104 * - we do this in set auth.
5105 */
5106 }
5107
5108 orinoco_unlock(priv, &flags);
5109 return 0;
5110}
5111
5112static int orinoco_ioctl_get_genie(struct net_device *dev,
5113 struct iw_request_info *info,
5114 union iwreq_data *wrqu, char *extra)
5115{
5116 struct orinoco_private *priv = netdev_priv(dev);
5117 unsigned long flags;
5118 int err = 0;
5119
5120 if (orinoco_lock(priv, &flags) != 0)
5121 return -EBUSY;
5122
5123 if ((priv->wpa_ie_len == 0) || (priv->wpa_ie == NULL)) {
5124 wrqu->data.length = 0;
5125 goto out;
5126 }
5127
5128 if (wrqu->data.length < priv->wpa_ie_len) {
5129 err = -E2BIG;
5130 goto out;
5131 }
5132
5133 wrqu->data.length = priv->wpa_ie_len;
5134 memcpy(extra, priv->wpa_ie, priv->wpa_ie_len);
5135
5136out:
5137 orinoco_unlock(priv, &flags);
5138 return err;
5139}
5140
5141static int orinoco_ioctl_set_mlme(struct net_device *dev,
5142 struct iw_request_info *info,
5143 union iwreq_data *wrqu, char *extra)
5144{
5145 struct orinoco_private *priv = netdev_priv(dev);
5146 hermes_t *hw = &priv->hw;
5147 struct iw_mlme *mlme = (struct iw_mlme *)extra;
5148 unsigned long flags;
5149 int ret = 0;
5150
5151 if (orinoco_lock(priv, &flags) != 0)
5152 return -EBUSY;
5153
5154 switch (mlme->cmd) {
5155 case IW_MLME_DEAUTH:
5156 /* silently ignore */
5157 break;
5158
5159 case IW_MLME_DISASSOC:
5160 {
5161 struct {
5162 u8 addr[ETH_ALEN];
5163 __le16 reason_code;
5164 } __attribute__ ((packed)) buf;
5165
5166 memcpy(buf.addr, mlme->addr.sa_data, ETH_ALEN);
5167 buf.reason_code = cpu_to_le16(mlme->reason_code);
5168 ret = HERMES_WRITE_RECORD(hw, USER_BAP,
5169 HERMES_RID_CNFDISASSOCIATE,
5170 &buf);
5171 break;
5172 }
5173 default:
5174 ret = -EOPNOTSUPP;
5175 }
5176
5177 orinoco_unlock(priv, &flags);
5178 return ret;
5179}
5180
5181static int orinoco_ioctl_getretry(struct net_device *dev,
5182 struct iw_request_info *info,
5183 struct iw_param *rrq,
5184 char *extra)
5185{
5186 struct orinoco_private *priv = netdev_priv(dev);
5187 hermes_t *hw = &priv->hw;
5188 int err = 0;
5189 u16 short_limit, long_limit, lifetime;
5190 unsigned long flags;
5191
5192 if (orinoco_lock(priv, &flags) != 0)
5193 return -EBUSY;
5194
5195 err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_SHORTRETRYLIMIT,
5196 &short_limit);
5197 if (err)
5198 goto out;
5199
5200 err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_LONGRETRYLIMIT,
5201 &long_limit);
5202 if (err)
5203 goto out;
5204
5205 err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_MAXTRANSMITLIFETIME,
5206 &lifetime);
5207 if (err)
5208 goto out;
5209
5210 rrq->disabled = 0; /* Can't be disabled */
5211
5212 /* Note : by default, display the retry number */
5213 if ((rrq->flags & IW_RETRY_TYPE) == IW_RETRY_LIFETIME) {
5214 rrq->flags = IW_RETRY_LIFETIME;
5215 rrq->value = lifetime * 1000; /* ??? */
5216 } else {
5217 /* By default, display the min number */
5218 if ((rrq->flags & IW_RETRY_LONG)) {
5219 rrq->flags = IW_RETRY_LIMIT | IW_RETRY_LONG;
5220 rrq->value = long_limit;
5221 } else {
5222 rrq->flags = IW_RETRY_LIMIT;
5223 rrq->value = short_limit;
5224 if(short_limit != long_limit)
5225 rrq->flags |= IW_RETRY_SHORT;
5226 }
5227 }
5228
5229 out:
5230 orinoco_unlock(priv, &flags);
5231
5232 return err;
5233}
5234
5235static int orinoco_ioctl_reset(struct net_device *dev,
5236 struct iw_request_info *info,
5237 void *wrqu,
5238 char *extra)
5239{
5240 struct orinoco_private *priv = netdev_priv(dev);
5241
5242 if (! capable(CAP_NET_ADMIN))
5243 return -EPERM;
5244
5245 if (info->cmd == (SIOCIWFIRSTPRIV + 0x1)) {
5246 printk(KERN_DEBUG "%s: Forcing reset!\n", dev->name);
5247
5248 /* Firmware reset */
5249 orinoco_reset(&priv->reset_work);
5250 } else {
5251 printk(KERN_DEBUG "%s: Force scheduling reset!\n", dev->name);
5252
5253 schedule_work(&priv->reset_work);
5254 }
5255
5256 return 0;
5257}
5258
5259static int orinoco_ioctl_setibssport(struct net_device *dev,
5260 struct iw_request_info *info,
5261 void *wrqu,
5262 char *extra)
5263
5264{
5265 struct orinoco_private *priv = netdev_priv(dev);
5266 int val = *( (int *) extra );
5267 unsigned long flags;
5268
5269 if (orinoco_lock(priv, &flags) != 0)
5270 return -EBUSY;
5271
5272 priv->ibss_port = val ;
5273
5274 /* Actually update the mode we are using */
5275 set_port_type(priv);
5276
5277 orinoco_unlock(priv, &flags);
5278 return -EINPROGRESS; /* Call commit handler */
5279}
5280
5281static int orinoco_ioctl_getibssport(struct net_device *dev,
5282 struct iw_request_info *info,
5283 void *wrqu,
5284 char *extra)
5285{
5286 struct orinoco_private *priv = netdev_priv(dev);
5287 int *val = (int *) extra;
5288
5289 *val = priv->ibss_port;
5290 return 0;
5291}
5292
5293static int orinoco_ioctl_setport3(struct net_device *dev,
5294 struct iw_request_info *info,
5295 void *wrqu,
5296 char *extra)
5297{
5298 struct orinoco_private *priv = netdev_priv(dev);
5299 int val = *( (int *) extra );
5300 int err = 0;
5301 unsigned long flags;
5302
5303 if (orinoco_lock(priv, &flags) != 0)
5304 return -EBUSY;
5305
5306 switch (val) {
5307 case 0: /* Try to do IEEE ad-hoc mode */
5308 if (! priv->has_ibss) {
5309 err = -EINVAL;
5310 break;
5311 }
5312 priv->prefer_port3 = 0;
5313
5314 break;
5315
5316 case 1: /* Try to do Lucent proprietary ad-hoc mode */
5317 if (! priv->has_port3) {
5318 err = -EINVAL;
5319 break;
5320 }
5321 priv->prefer_port3 = 1;
5322 break;
5323
5324 default:
5325 err = -EINVAL;
5326 }
5327
5328 if (! err) {
5329 /* Actually update the mode we are using */
5330 set_port_type(priv);
5331 err = -EINPROGRESS;
5332 }
5333
5334 orinoco_unlock(priv, &flags);
5335
5336 return err;
5337}
5338
5339static int orinoco_ioctl_getport3(struct net_device *dev,
5340 struct iw_request_info *info,
5341 void *wrqu,
5342 char *extra)
5343{
5344 struct orinoco_private *priv = netdev_priv(dev);
5345 int *val = (int *) extra;
5346
5347 *val = priv->prefer_port3;
5348 return 0;
5349}
5350
5351static int orinoco_ioctl_setpreamble(struct net_device *dev,
5352 struct iw_request_info *info,
5353 void *wrqu,
5354 char *extra)
5355{
5356 struct orinoco_private *priv = netdev_priv(dev);
5357 unsigned long flags;
5358 int val;
5359
5360 if (! priv->has_preamble)
5361 return -EOPNOTSUPP;
5362
5363 /* 802.11b has recently defined some short preamble.
5364 * Basically, the Phy header has been reduced in size.
5365 * This increase performance, especially at high rates
5366 * (the preamble is transmitted at 1Mb/s), unfortunately
5367 * this give compatibility troubles... - Jean II */
5368 val = *( (int *) extra );
5369
5370 if (orinoco_lock(priv, &flags) != 0)
5371 return -EBUSY;
5372
5373 if (val)
5374 priv->preamble = 1;
5375 else
5376 priv->preamble = 0;
5377
5378 orinoco_unlock(priv, &flags);
5379
5380 return -EINPROGRESS; /* Call commit handler */
5381}
5382
5383static int orinoco_ioctl_getpreamble(struct net_device *dev,
5384 struct iw_request_info *info,
5385 void *wrqu,
5386 char *extra)
5387{
5388 struct orinoco_private *priv = netdev_priv(dev);
5389 int *val = (int *) extra;
5390
5391 if (! priv->has_preamble)
5392 return -EOPNOTSUPP;
5393
5394 *val = priv->preamble;
5395 return 0;
5396}
5397
5398/* ioctl interface to hermes_read_ltv()
5399 * To use with iwpriv, pass the RID as the token argument, e.g.
5400 * iwpriv get_rid [0xfc00]
5401 * At least Wireless Tools 25 is required to use iwpriv.
5402 * For Wireless Tools 25 and 26 append "dummy" are the end. */
5403static int orinoco_ioctl_getrid(struct net_device *dev,
5404 struct iw_request_info *info,
5405 struct iw_point *data,
5406 char *extra)
5407{
5408 struct orinoco_private *priv = netdev_priv(dev);
5409 hermes_t *hw = &priv->hw;
5410 int rid = data->flags;
5411 u16 length;
5412 int err;
5413 unsigned long flags;
5414
5415 /* It's a "get" function, but we don't want users to access the
5416 * WEP key and other raw firmware data */
5417 if (! capable(CAP_NET_ADMIN))
5418 return -EPERM;
5419
5420 if (rid < 0xfc00 || rid > 0xffff)
5421 return -EINVAL;
5422
5423 if (orinoco_lock(priv, &flags) != 0)
5424 return -EBUSY;
5425
5426 err = hermes_read_ltv(hw, USER_BAP, rid, MAX_RID_LEN, &length,
5427 extra);
5428 if (err)
5429 goto out;
5430
5431 data->length = min_t(u16, HERMES_RECLEN_TO_BYTES(length),
5432 MAX_RID_LEN);
5433
5434 out:
5435 orinoco_unlock(priv, &flags);
5436 return err;
5437}
5438
5439/* Trigger a scan (look for other cells in the vicinity) */
5440static int orinoco_ioctl_setscan(struct net_device *dev,
5441 struct iw_request_info *info,
5442 struct iw_point *srq,
5443 char *extra)
5444{
5445 struct orinoco_private *priv = netdev_priv(dev);
5446 hermes_t *hw = &priv->hw;
5447 struct iw_scan_req *si = (struct iw_scan_req *) extra;
5448 int err = 0;
5449 unsigned long flags;
5450
5451 /* Note : you may have realised that, as this is a SET operation,
5452 * this is privileged and therefore a normal user can't
5453 * perform scanning.
5454 * This is not an error, while the device perform scanning,
5455 * traffic doesn't flow, so it's a perfect DoS...
5456 * Jean II */
5457
5458 if (orinoco_lock(priv, &flags) != 0)
5459 return -EBUSY;
5460
5461 /* Scanning with port 0 disabled would fail */
5462 if (!netif_running(dev)) {
5463 err = -ENETDOWN;
5464 goto out;
5465 }
5466
5467 /* In monitor mode, the scan results are always empty.
5468 * Probe responses are passed to the driver as received
5469 * frames and could be processed in software. */
5470 if (priv->iw_mode == IW_MODE_MONITOR) {
5471 err = -EOPNOTSUPP;
5472 goto out;
5473 }
5474
5475 /* Note : because we don't lock out the irq handler, the way
5476 * we access scan variables in priv is critical.
5477 * o scan_inprogress : not touched by irq handler
5478 * o scan_mode : not touched by irq handler
5479 * Before modifying anything on those variables, please think hard !
5480 * Jean II */
5481
5482 /* Save flags */
5483 priv->scan_mode = srq->flags;
5484
5485 /* Always trigger scanning, even if it's in progress.
5486 * This way, if the info frame get lost, we will recover somewhat
5487 * gracefully - Jean II */
5488
5489 if (priv->has_hostscan) {
5490 switch (priv->firmware_type) {
5491 case FIRMWARE_TYPE_SYMBOL:
5492 err = hermes_write_wordrec(hw, USER_BAP,
5493 HERMES_RID_CNFHOSTSCAN_SYMBOL,
5494 HERMES_HOSTSCAN_SYMBOL_ONCE |
5495 HERMES_HOSTSCAN_SYMBOL_BCAST);
5496 break;
5497 case FIRMWARE_TYPE_INTERSIL: {
5498 __le16 req[3];
5499
5500 req[0] = cpu_to_le16(0x3fff); /* All channels */
5501 req[1] = cpu_to_le16(0x0001); /* rate 1 Mbps */
5502 req[2] = 0; /* Any ESSID */
5503 err = HERMES_WRITE_RECORD(hw, USER_BAP,
5504 HERMES_RID_CNFHOSTSCAN, &req);
5505 }
5506 break;
5507 case FIRMWARE_TYPE_AGERE:
5508 if (priv->scan_mode & IW_SCAN_THIS_ESSID) {
5509 struct hermes_idstring idbuf;
5510 size_t len = min(sizeof(idbuf.val),
5511 (size_t) si->essid_len);
5512 idbuf.len = cpu_to_le16(len);
5513 memcpy(idbuf.val, si->essid, len);
5514
5515 err = hermes_write_ltv(hw, USER_BAP,
5516 HERMES_RID_CNFSCANSSID_AGERE,
5517 HERMES_BYTES_TO_RECLEN(len + 2),
5518 &idbuf);
5519 } else
5520 err = hermes_write_wordrec(hw, USER_BAP,
5521 HERMES_RID_CNFSCANSSID_AGERE,
5522 0); /* Any ESSID */
5523 if (err)
5524 break;
5525
5526 if (priv->has_ext_scan) {
5527 /* Clear scan results at the start of
5528 * an extended scan */
5529 orinoco_clear_scan_results(priv,
5530 msecs_to_jiffies(15000));
5531
5532 /* TODO: Is this available on older firmware?
5533 * Can we use it to scan specific channels
5534 * for IW_SCAN_THIS_FREQ? */
5535 err = hermes_write_wordrec(hw, USER_BAP,
5536 HERMES_RID_CNFSCANCHANNELS2GHZ,
5537 0x7FFF);
5538 if (err)
5539 goto out;
5540
5541 err = hermes_inquire(hw,
5542 HERMES_INQ_CHANNELINFO);
5543 } else
5544 err = hermes_inquire(hw, HERMES_INQ_SCAN);
5545 break;
5546 }
5547 } else
5548 err = hermes_inquire(hw, HERMES_INQ_SCAN);
5549
5550 /* One more client */
5551 if (! err)
5552 priv->scan_inprogress = 1;
5553
5554 out:
5555 orinoco_unlock(priv, &flags);
5556 return err;
5557}
5558
5559#define MAX_CUSTOM_LEN 64
5560
5561/* Translate scan data returned from the card to a card independant
5562 * format that the Wireless Tools will understand - Jean II */
5563static inline char *orinoco_translate_scan(struct net_device *dev,
5564 struct iw_request_info *info,
5565 char *current_ev,
5566 char *end_buf,
5567 union hermes_scan_info *bss,
5568 unsigned long last_scanned)
5569{
5570 struct orinoco_private *priv = netdev_priv(dev);
5571 u16 capabilities;
5572 u16 channel;
5573 struct iw_event iwe; /* Temporary buffer */
5574 char custom[MAX_CUSTOM_LEN];
5575
5576 memset(&iwe, 0, sizeof(iwe));
5577
5578 /* First entry *MUST* be the AP MAC address */
5579 iwe.cmd = SIOCGIWAP;
5580 iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
5581 memcpy(iwe.u.ap_addr.sa_data, bss->a.bssid, ETH_ALEN);
5582 current_ev = iwe_stream_add_event(info, current_ev, end_buf,
5583 &iwe, IW_EV_ADDR_LEN);
5584
5585 /* Other entries will be displayed in the order we give them */
5586
5587 /* Add the ESSID */
5588 iwe.u.data.length = le16_to_cpu(bss->a.essid_len);
5589 if (iwe.u.data.length > 32)
5590 iwe.u.data.length = 32;
5591 iwe.cmd = SIOCGIWESSID;
5592 iwe.u.data.flags = 1;
5593 current_ev = iwe_stream_add_point(info, current_ev, end_buf,
5594 &iwe, bss->a.essid);
5595
5596 /* Add mode */
5597 iwe.cmd = SIOCGIWMODE;
5598 capabilities = le16_to_cpu(bss->a.capabilities);
5599 if (capabilities & (WLAN_CAPABILITY_ESS | WLAN_CAPABILITY_IBSS)) {
5600 if (capabilities & WLAN_CAPABILITY_ESS)
5601 iwe.u.mode = IW_MODE_MASTER;
5602 else
5603 iwe.u.mode = IW_MODE_ADHOC;
5604 current_ev = iwe_stream_add_event(info, current_ev, end_buf,
5605 &iwe, IW_EV_UINT_LEN);
5606 }
5607
5608 channel = bss->s.channel;
5609 if ((channel >= 1) && (channel <= NUM_CHANNELS)) {
5610 /* Add channel and frequency */
5611 iwe.cmd = SIOCGIWFREQ;
5612 iwe.u.freq.m = channel;
5613 iwe.u.freq.e = 0;
5614 current_ev = iwe_stream_add_event(info, current_ev, end_buf,
5615 &iwe, IW_EV_FREQ_LEN);
5616
5617 iwe.u.freq.m = ieee80211_dsss_chan_to_freq(channel) * 100000;
5618 iwe.u.freq.e = 1;
5619 current_ev = iwe_stream_add_event(info, current_ev, end_buf,
5620 &iwe, IW_EV_FREQ_LEN);
5621 }
5622
5623 /* Add quality statistics. level and noise in dB. No link quality */
5624 iwe.cmd = IWEVQUAL;
5625 iwe.u.qual.updated = IW_QUAL_DBM | IW_QUAL_QUAL_INVALID;
5626 iwe.u.qual.level = (__u8) le16_to_cpu(bss->a.level) - 0x95;
5627 iwe.u.qual.noise = (__u8) le16_to_cpu(bss->a.noise) - 0x95;
5628 /* Wireless tools prior to 27.pre22 will show link quality
5629 * anyway, so we provide a reasonable value. */
5630 if (iwe.u.qual.level > iwe.u.qual.noise)
5631 iwe.u.qual.qual = iwe.u.qual.level - iwe.u.qual.noise;
5632 else
5633 iwe.u.qual.qual = 0;
5634 current_ev = iwe_stream_add_event(info, current_ev, end_buf,
5635 &iwe, IW_EV_QUAL_LEN);
5636
5637 /* Add encryption capability */
5638 iwe.cmd = SIOCGIWENCODE;
5639 if (capabilities & WLAN_CAPABILITY_PRIVACY)
5640 iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
5641 else
5642 iwe.u.data.flags = IW_ENCODE_DISABLED;
5643 iwe.u.data.length = 0;
5644 current_ev = iwe_stream_add_point(info, current_ev, end_buf,
5645 &iwe, NULL);
5646
5647 /* Bit rate is not available in Lucent/Agere firmwares */
5648 if (priv->firmware_type != FIRMWARE_TYPE_AGERE) {
5649 char *current_val = current_ev + iwe_stream_lcp_len(info);
5650 int i;
5651 int step;
5652
5653 if (priv->firmware_type == FIRMWARE_TYPE_SYMBOL)
5654 step = 2;
5655 else
5656 step = 1;
5657
5658 iwe.cmd = SIOCGIWRATE;
5659 /* Those two flags are ignored... */
5660 iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
5661 /* Max 10 values */
5662 for (i = 0; i < 10; i += step) {
5663 /* NULL terminated */
5664 if (bss->p.rates[i] == 0x0)
5665 break;
5666 /* Bit rate given in 500 kb/s units (+ 0x80) */
5667 iwe.u.bitrate.value =
5668 ((bss->p.rates[i] & 0x7f) * 500000);
5669 current_val = iwe_stream_add_value(info, current_ev,
5670 current_val,
5671 end_buf, &iwe,
5672 IW_EV_PARAM_LEN);
5673 }
5674 /* Check if we added any event */
5675 if ((current_val - current_ev) > iwe_stream_lcp_len(info))
5676 current_ev = current_val;
5677 }
5678
5679 /* Beacon interval */
5680 iwe.cmd = IWEVCUSTOM;
5681 iwe.u.data.length = snprintf(custom, MAX_CUSTOM_LEN,
5682 "bcn_int=%d",
5683 le16_to_cpu(bss->a.beacon_interv));
5684 if (iwe.u.data.length)
5685 current_ev = iwe_stream_add_point(info, current_ev, end_buf,
5686 &iwe, custom);
5687
5688 /* Capabilites */
5689 iwe.cmd = IWEVCUSTOM;
5690 iwe.u.data.length = snprintf(custom, MAX_CUSTOM_LEN,
5691 "capab=0x%04x",
5692 capabilities);
5693 if (iwe.u.data.length)
5694 current_ev = iwe_stream_add_point(info, current_ev, end_buf,
5695 &iwe, custom);
5696
5697 /* Add EXTRA: Age to display seconds since last beacon/probe response
5698 * for given network. */
5699 iwe.cmd = IWEVCUSTOM;
5700 iwe.u.data.length = snprintf(custom, MAX_CUSTOM_LEN,
5701 " Last beacon: %dms ago",
5702 jiffies_to_msecs(jiffies - last_scanned));
5703 if (iwe.u.data.length)
5704 current_ev = iwe_stream_add_point(info, current_ev, end_buf,
5705 &iwe, custom);
5706
5707 return current_ev;
5708}
5709
5710static inline char *orinoco_translate_ext_scan(struct net_device *dev,
5711 struct iw_request_info *info,
5712 char *current_ev,
5713 char *end_buf,
5714 struct agere_ext_scan_info *bss,
5715 unsigned long last_scanned)
5716{
5717 u16 capabilities;
5718 u16 channel;
5719 struct iw_event iwe; /* Temporary buffer */
5720 char custom[MAX_CUSTOM_LEN];
5721 u8 *ie;
5722
5723 memset(&iwe, 0, sizeof(iwe));
5724
5725 /* First entry *MUST* be the AP MAC address */
5726 iwe.cmd = SIOCGIWAP;
5727 iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
5728 memcpy(iwe.u.ap_addr.sa_data, bss->bssid, ETH_ALEN);
5729 current_ev = iwe_stream_add_event(info, current_ev, end_buf,
5730 &iwe, IW_EV_ADDR_LEN);
5731
5732 /* Other entries will be displayed in the order we give them */
5733
5734 /* Add the ESSID */
5735 ie = bss->data;
5736 iwe.u.data.length = ie[1];
5737 if (iwe.u.data.length) {
5738 if (iwe.u.data.length > 32)
5739 iwe.u.data.length = 32;
5740 iwe.cmd = SIOCGIWESSID;
5741 iwe.u.data.flags = 1;
5742 current_ev = iwe_stream_add_point(info, current_ev, end_buf,
5743 &iwe, &ie[2]);
5744 }
5745
5746 /* Add mode */
5747 capabilities = le16_to_cpu(bss->capabilities);
5748 if (capabilities & (WLAN_CAPABILITY_ESS | WLAN_CAPABILITY_IBSS)) {
5749 iwe.cmd = SIOCGIWMODE;
5750 if (capabilities & WLAN_CAPABILITY_ESS)
5751 iwe.u.mode = IW_MODE_MASTER;
5752 else
5753 iwe.u.mode = IW_MODE_ADHOC;
5754 current_ev = iwe_stream_add_event(info, current_ev, end_buf,
5755 &iwe, IW_EV_UINT_LEN);
5756 }
5757
5758 ie = orinoco_get_ie(bss->data, sizeof(bss->data), WLAN_EID_DS_PARAMS);
5759 channel = ie ? ie[2] : 0;
5760 if ((channel >= 1) && (channel <= NUM_CHANNELS)) {
5761 /* Add channel and frequency */
5762 iwe.cmd = SIOCGIWFREQ;
5763 iwe.u.freq.m = channel;
5764 iwe.u.freq.e = 0;
5765 current_ev = iwe_stream_add_event(info, current_ev, end_buf,
5766 &iwe, IW_EV_FREQ_LEN);
5767
5768 iwe.u.freq.m = ieee80211_dsss_chan_to_freq(channel) * 100000;
5769 iwe.u.freq.e = 1;
5770 current_ev = iwe_stream_add_event(info, current_ev, end_buf,
5771 &iwe, IW_EV_FREQ_LEN);
5772 }
5773
5774 /* Add quality statistics. level and noise in dB. No link quality */
5775 iwe.cmd = IWEVQUAL;
5776 iwe.u.qual.updated = IW_QUAL_DBM | IW_QUAL_QUAL_INVALID;
5777 iwe.u.qual.level = bss->level - 0x95;
5778 iwe.u.qual.noise = bss->noise - 0x95;
5779 /* Wireless tools prior to 27.pre22 will show link quality
5780 * anyway, so we provide a reasonable value. */
5781 if (iwe.u.qual.level > iwe.u.qual.noise)
5782 iwe.u.qual.qual = iwe.u.qual.level - iwe.u.qual.noise;
5783 else
5784 iwe.u.qual.qual = 0;
5785 current_ev = iwe_stream_add_event(info, current_ev, end_buf,
5786 &iwe, IW_EV_QUAL_LEN);
5787
5788 /* Add encryption capability */
5789 iwe.cmd = SIOCGIWENCODE;
5790 if (capabilities & WLAN_CAPABILITY_PRIVACY)
5791 iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
5792 else
5793 iwe.u.data.flags = IW_ENCODE_DISABLED;
5794 iwe.u.data.length = 0;
5795 current_ev = iwe_stream_add_point(info, current_ev, end_buf,
5796 &iwe, NULL);
5797
5798 /* WPA IE */
5799 ie = orinoco_get_wpa_ie(bss->data, sizeof(bss->data));
5800 if (ie) {
5801 iwe.cmd = IWEVGENIE;
5802 iwe.u.data.length = ie[1] + 2;
5803 current_ev = iwe_stream_add_point(info, current_ev, end_buf,
5804 &iwe, ie);
5805 }
5806
5807 /* RSN IE */
5808 ie = orinoco_get_ie(bss->data, sizeof(bss->data), WLAN_EID_RSN);
5809 if (ie) {
5810 iwe.cmd = IWEVGENIE;
5811 iwe.u.data.length = ie[1] + 2;
5812 current_ev = iwe_stream_add_point(info, current_ev, end_buf,
5813 &iwe, ie);
5814 }
5815
5816 ie = orinoco_get_ie(bss->data, sizeof(bss->data), WLAN_EID_SUPP_RATES);
5817 if (ie) {
5818 char *p = current_ev + iwe_stream_lcp_len(info);
5819 int i;
5820
5821 iwe.cmd = SIOCGIWRATE;
5822 /* Those two flags are ignored... */
5823 iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
5824
5825 for (i = 2; i < (ie[1] + 2); i++) {
5826 iwe.u.bitrate.value = ((ie[i] & 0x7F) * 500000);
5827 p = iwe_stream_add_value(info, current_ev, p, end_buf,
5828 &iwe, IW_EV_PARAM_LEN);
5829 }
5830 /* Check if we added any event */
5831 if (p > (current_ev + iwe_stream_lcp_len(info)))
5832 current_ev = p;
5833 }
5834
5835 /* Timestamp */
5836 iwe.cmd = IWEVCUSTOM;
5837 iwe.u.data.length =
5838 snprintf(custom, MAX_CUSTOM_LEN, "tsf=%016llx",
5839 (unsigned long long) le64_to_cpu(bss->timestamp));
5840 if (iwe.u.data.length)
5841 current_ev = iwe_stream_add_point(info, current_ev, end_buf,
5842 &iwe, custom);
5843
5844 /* Beacon interval */
5845 iwe.cmd = IWEVCUSTOM;
5846 iwe.u.data.length = snprintf(custom, MAX_CUSTOM_LEN,
5847 "bcn_int=%d",
5848 le16_to_cpu(bss->beacon_interval));
5849 if (iwe.u.data.length)
5850 current_ev = iwe_stream_add_point(info, current_ev, end_buf,
5851 &iwe, custom);
5852
5853 /* Capabilites */
5854 iwe.cmd = IWEVCUSTOM;
5855 iwe.u.data.length = snprintf(custom, MAX_CUSTOM_LEN,
5856 "capab=0x%04x",
5857 capabilities);
5858 if (iwe.u.data.length)
5859 current_ev = iwe_stream_add_point(info, current_ev, end_buf,
5860 &iwe, custom);
5861
5862 /* Add EXTRA: Age to display seconds since last beacon/probe response
5863 * for given network. */
5864 iwe.cmd = IWEVCUSTOM;
5865 iwe.u.data.length = snprintf(custom, MAX_CUSTOM_LEN,
5866 " Last beacon: %dms ago",
5867 jiffies_to_msecs(jiffies - last_scanned));
5868 if (iwe.u.data.length)
5869 current_ev = iwe_stream_add_point(info, current_ev, end_buf,
5870 &iwe, custom);
5871
5872 return current_ev;
5873}
5874
5875/* Return results of a scan */
5876static int orinoco_ioctl_getscan(struct net_device *dev,
5877 struct iw_request_info *info,
5878 struct iw_point *srq,
5879 char *extra)
5880{
5881 struct orinoco_private *priv = netdev_priv(dev);
5882 int err = 0;
5883 unsigned long flags;
5884 char *current_ev = extra;
5885
5886 if (orinoco_lock(priv, &flags) != 0)
5887 return -EBUSY;
5888
5889 if (priv->scan_inprogress) {
5890 /* Important note : we don't want to block the caller
5891 * until results are ready for various reasons.
5892 * First, managing wait queues is complex and racy.
5893 * Second, we grab some rtnetlink lock before comming
5894 * here (in dev_ioctl()).
5895 * Third, we generate an Wireless Event, so the
5896 * caller can wait itself on that - Jean II */
5897 err = -EAGAIN;
5898 goto out;
5899 }
5900
5901 if (priv->has_ext_scan) {
5902 struct xbss_element *bss;
5903
5904 list_for_each_entry(bss, &priv->bss_list, list) {
5905 /* Translate this entry to WE format */
5906 current_ev =
5907 orinoco_translate_ext_scan(dev, info,
5908 current_ev,
5909 extra + srq->length,
5910 &bss->bss,
5911 bss->last_scanned);
5912
5913 /* Check if there is space for one more entry */
5914 if ((extra + srq->length - current_ev)
5915 <= IW_EV_ADDR_LEN) {
5916 /* Ask user space to try again with a
5917 * bigger buffer */
5918 err = -E2BIG;
5919 goto out;
5920 }
5921 }
5922
5923 } else {
5924 struct bss_element *bss;
5925
5926 list_for_each_entry(bss, &priv->bss_list, list) {
5927 /* Translate this entry to WE format */
5928 current_ev = orinoco_translate_scan(dev, info,
5929 current_ev,
5930 extra + srq->length,
5931 &bss->bss,
5932 bss->last_scanned);
5933
5934 /* Check if there is space for one more entry */
5935 if ((extra + srq->length - current_ev)
5936 <= IW_EV_ADDR_LEN) {
5937 /* Ask user space to try again with a
5938 * bigger buffer */
5939 err = -E2BIG;
5940 goto out;
5941 }
5942 }
5943 }
5944
5945 srq->length = (current_ev - extra);
5946 srq->flags = (__u16) priv->scan_mode;
5947
5948out:
5949 orinoco_unlock(priv, &flags);
5950 return err;
5951}
5952
5953/* Commit handler, called after set operations */
5954static int orinoco_ioctl_commit(struct net_device *dev,
5955 struct iw_request_info *info,
5956 void *wrqu,
5957 char *extra)
5958{
5959 struct orinoco_private *priv = netdev_priv(dev);
5960 struct hermes *hw = &priv->hw;
5961 unsigned long flags;
5962 int err = 0;
5963
5964 if (!priv->open)
5965 return 0;
5966
5967 if (priv->broken_disableport) {
5968 orinoco_reset(&priv->reset_work);
5969 return 0;
5970 }
5971
5972 if (orinoco_lock(priv, &flags) != 0)
5973 return err;
5974
5975 err = hermes_disable_port(hw, 0);
5976 if (err) {
5977 printk(KERN_WARNING "%s: Unable to disable port "
5978 "while reconfiguring card\n", dev->name);
5979 priv->broken_disableport = 1;
5980 goto out;
5981 }
5982
5983 err = __orinoco_program_rids(dev);
5984 if (err) {
5985 printk(KERN_WARNING "%s: Unable to reconfigure card\n",
5986 dev->name);
5987 goto out;
5988 }
5989
5990 err = hermes_enable_port(hw, 0);
5991 if (err) {
5992 printk(KERN_WARNING "%s: Unable to enable port while reconfiguring card\n",
5993 dev->name);
5994 goto out;
5995 }
5996
5997 out:
5998 if (err) {
5999 printk(KERN_WARNING "%s: Resetting instead...\n", dev->name);
6000 schedule_work(&priv->reset_work);
6001 err = 0;
6002 }
6003
6004 orinoco_unlock(priv, &flags);
6005 return err;
6006}
6007
6008static const struct iw_priv_args orinoco_privtab[] = {
6009 { SIOCIWFIRSTPRIV + 0x0, 0, 0, "force_reset" },
6010 { SIOCIWFIRSTPRIV + 0x1, 0, 0, "card_reset" },
6011 { SIOCIWFIRSTPRIV + 0x2, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
6012 0, "set_port3" },
6013 { SIOCIWFIRSTPRIV + 0x3, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
6014 "get_port3" },
6015 { SIOCIWFIRSTPRIV + 0x4, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
6016 0, "set_preamble" },
6017 { SIOCIWFIRSTPRIV + 0x5, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
6018 "get_preamble" },
6019 { SIOCIWFIRSTPRIV + 0x6, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
6020 0, "set_ibssport" },
6021 { SIOCIWFIRSTPRIV + 0x7, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
6022 "get_ibssport" },
6023 { SIOCIWFIRSTPRIV + 0x9, 0, IW_PRIV_TYPE_BYTE | MAX_RID_LEN,
6024 "get_rid" },
6025};
6026
6027
6028/*
6029 * Structures to export the Wireless Handlers
6030 */
6031
6032#define STD_IW_HANDLER(id, func) \
6033 [IW_IOCTL_IDX(id)] = (iw_handler) func
6034static const iw_handler orinoco_handler[] = {
6035 STD_IW_HANDLER(SIOCSIWCOMMIT, orinoco_ioctl_commit),
6036 STD_IW_HANDLER(SIOCGIWNAME, orinoco_ioctl_getname),
6037 STD_IW_HANDLER(SIOCSIWFREQ, orinoco_ioctl_setfreq),
6038 STD_IW_HANDLER(SIOCGIWFREQ, orinoco_ioctl_getfreq),
6039 STD_IW_HANDLER(SIOCSIWMODE, orinoco_ioctl_setmode),
6040 STD_IW_HANDLER(SIOCGIWMODE, orinoco_ioctl_getmode),
6041 STD_IW_HANDLER(SIOCSIWSENS, orinoco_ioctl_setsens),
6042 STD_IW_HANDLER(SIOCGIWSENS, orinoco_ioctl_getsens),
6043 STD_IW_HANDLER(SIOCGIWRANGE, orinoco_ioctl_getiwrange),
6044 STD_IW_HANDLER(SIOCSIWSPY, iw_handler_set_spy),
6045 STD_IW_HANDLER(SIOCGIWSPY, iw_handler_get_spy),
6046 STD_IW_HANDLER(SIOCSIWTHRSPY, iw_handler_set_thrspy),
6047 STD_IW_HANDLER(SIOCGIWTHRSPY, iw_handler_get_thrspy),
6048 STD_IW_HANDLER(SIOCSIWAP, orinoco_ioctl_setwap),
6049 STD_IW_HANDLER(SIOCGIWAP, orinoco_ioctl_getwap),
6050 STD_IW_HANDLER(SIOCSIWSCAN, orinoco_ioctl_setscan),
6051 STD_IW_HANDLER(SIOCGIWSCAN, orinoco_ioctl_getscan),
6052 STD_IW_HANDLER(SIOCSIWESSID, orinoco_ioctl_setessid),
6053 STD_IW_HANDLER(SIOCGIWESSID, orinoco_ioctl_getessid),
6054 STD_IW_HANDLER(SIOCSIWNICKN, orinoco_ioctl_setnick),
6055 STD_IW_HANDLER(SIOCGIWNICKN, orinoco_ioctl_getnick),
6056 STD_IW_HANDLER(SIOCSIWRATE, orinoco_ioctl_setrate),
6057 STD_IW_HANDLER(SIOCGIWRATE, orinoco_ioctl_getrate),
6058 STD_IW_HANDLER(SIOCSIWRTS, orinoco_ioctl_setrts),
6059 STD_IW_HANDLER(SIOCGIWRTS, orinoco_ioctl_getrts),
6060 STD_IW_HANDLER(SIOCSIWFRAG, orinoco_ioctl_setfrag),
6061 STD_IW_HANDLER(SIOCGIWFRAG, orinoco_ioctl_getfrag),
6062 STD_IW_HANDLER(SIOCGIWRETRY, orinoco_ioctl_getretry),
6063 STD_IW_HANDLER(SIOCSIWENCODE, orinoco_ioctl_setiwencode),
6064 STD_IW_HANDLER(SIOCGIWENCODE, orinoco_ioctl_getiwencode),
6065 STD_IW_HANDLER(SIOCSIWPOWER, orinoco_ioctl_setpower),
6066 STD_IW_HANDLER(SIOCGIWPOWER, orinoco_ioctl_getpower),
6067 STD_IW_HANDLER(SIOCSIWGENIE, orinoco_ioctl_set_genie),
6068 STD_IW_HANDLER(SIOCGIWGENIE, orinoco_ioctl_get_genie),
6069 STD_IW_HANDLER(SIOCSIWMLME, orinoco_ioctl_set_mlme),
6070 STD_IW_HANDLER(SIOCSIWAUTH, orinoco_ioctl_set_auth),
6071 STD_IW_HANDLER(SIOCGIWAUTH, orinoco_ioctl_get_auth),
6072 STD_IW_HANDLER(SIOCSIWENCODEEXT, orinoco_ioctl_set_encodeext),
6073 STD_IW_HANDLER(SIOCGIWENCODEEXT, orinoco_ioctl_get_encodeext),
6074};
6075
6076
6077/*
6078 Added typecasting since we no longer use iwreq_data -- Moustafa
6079 */
6080static const iw_handler orinoco_private_handler[] = {
6081 [0] = (iw_handler) orinoco_ioctl_reset,
6082 [1] = (iw_handler) orinoco_ioctl_reset,
6083 [2] = (iw_handler) orinoco_ioctl_setport3,
6084 [3] = (iw_handler) orinoco_ioctl_getport3,
6085 [4] = (iw_handler) orinoco_ioctl_setpreamble,
6086 [5] = (iw_handler) orinoco_ioctl_getpreamble,
6087 [6] = (iw_handler) orinoco_ioctl_setibssport,
6088 [7] = (iw_handler) orinoco_ioctl_getibssport,
6089 [9] = (iw_handler) orinoco_ioctl_getrid,
6090};
6091
6092static const struct iw_handler_def orinoco_handler_def = {
6093 .num_standard = ARRAY_SIZE(orinoco_handler),
6094 .num_private = ARRAY_SIZE(orinoco_private_handler),
6095 .num_private_args = ARRAY_SIZE(orinoco_privtab),
6096 .standard = orinoco_handler,
6097 .private = orinoco_private_handler,
6098 .private_args = orinoco_privtab,
6099 .get_wireless_stats = orinoco_get_wireless_stats,
6100};
6101
6102static void orinoco_get_drvinfo(struct net_device *dev,
6103 struct ethtool_drvinfo *info)
6104{
6105 struct orinoco_private *priv = netdev_priv(dev);
6106
6107 strncpy(info->driver, DRIVER_NAME, sizeof(info->driver) - 1);
6108 strncpy(info->version, DRIVER_VERSION, sizeof(info->version) - 1);
6109 strncpy(info->fw_version, priv->fw_name, sizeof(info->fw_version) - 1);
6110 if (dev->dev.parent)
6111 strncpy(info->bus_info, dev_name(dev->dev.parent),
6112 sizeof(info->bus_info) - 1);
6113 else
6114 snprintf(info->bus_info, sizeof(info->bus_info) - 1,
6115 "PCMCIA %p", priv->hw.iobase);
6116}
6117
6118static const struct ethtool_ops orinoco_ethtool_ops = {
6119 .get_drvinfo = orinoco_get_drvinfo,
6120 .get_link = ethtool_op_get_link,
6121};
6122
6123/********************************************************************/
6124/* Module initialization */
6125/********************************************************************/
6126
6127EXPORT_SYMBOL(alloc_orinocodev);
6128EXPORT_SYMBOL(free_orinocodev);
6129
6130EXPORT_SYMBOL(__orinoco_up);
6131EXPORT_SYMBOL(__orinoco_down);
6132EXPORT_SYMBOL(orinoco_reinit_firmware);
6133
6134EXPORT_SYMBOL(orinoco_interrupt);
6135
6136/* Can't be declared "const" or the whole __initdata section will
6137 * become const */
6138static char version[] __initdata = DRIVER_NAME " " DRIVER_VERSION
6139 " (David Gibson <hermes@gibson.dropbear.id.au>, "
6140 "Pavel Roskin <proski@gnu.org>, et al)";
6141
6142static int __init init_orinoco(void)
6143{
6144 printk(KERN_DEBUG "%s\n", version);
6145 return 0;
6146}
6147
6148static void __exit exit_orinoco(void)
6149{
6150}
6151
6152module_init(init_orinoco);
6153module_exit(exit_orinoco);
diff --git a/drivers/net/wireless/orinoco/orinoco_cs.c b/drivers/net/wireless/orinoco/orinoco_cs.c
index d194b3e0311d..b381aed24d73 100644
--- a/drivers/net/wireless/orinoco/orinoco_cs.c
+++ b/drivers/net/wireless/orinoco/orinoco_cs.c
@@ -7,7 +7,7 @@
7 * Linksys, D-Link and Farallon Skyline. It should also work on Symbol 7 * Linksys, D-Link and Farallon Skyline. It should also work on Symbol
8 * cards such as the 3Com AirConnect and Ericsson WLAN. 8 * cards such as the 3Com AirConnect and Ericsson WLAN.
9 * 9 *
10 * Copyright notice & release notes in file orinoco.c 10 * Copyright notice & release notes in file main.c
11 */ 11 */
12 12
13#define DRIVER_NAME "orinoco_cs" 13#define DRIVER_NAME "orinoco_cs"
diff --git a/drivers/net/wireless/orinoco/orinoco_pci.h b/drivers/net/wireless/orinoco/orinoco_pci.h
index 88df3ee98078..c655b4a3de16 100644
--- a/drivers/net/wireless/orinoco/orinoco_pci.h
+++ b/drivers/net/wireless/orinoco/orinoco_pci.h
@@ -4,7 +4,7 @@
4 * both native PCI and PCMCIA-to-PCI bridges. 4 * both native PCI and PCMCIA-to-PCI bridges.
5 * 5 *
6 * Copyright (C) 2005, Pavel Roskin. 6 * Copyright (C) 2005, Pavel Roskin.
7 * See orinoco.c for license. 7 * See main.c for license.
8 */ 8 */
9 9
10#ifndef _ORINOCO_PCI_H 10#ifndef _ORINOCO_PCI_H
diff --git a/drivers/net/wireless/orinoco/orinoco_tmd.c b/drivers/net/wireless/orinoco/orinoco_tmd.c
index e77c4042d43a..cda0e6e4d7a1 100644
--- a/drivers/net/wireless/orinoco/orinoco_tmd.c
+++ b/drivers/net/wireless/orinoco/orinoco_tmd.c
@@ -27,7 +27,7 @@
27 * provisions above, a recipient may use your version of this file 27 * provisions above, a recipient may use your version of this file
28 * under either the MPL or the GPL. 28 * under either the MPL or the GPL.
29 * 29 *
30 * The actual driving is done by orinoco.c, this is just resource 30 * The actual driving is done by main.c, this is just resource
31 * allocation stuff. 31 * allocation stuff.
32 * 32 *
33 * This driver is modeled after the orinoco_plx driver. The main 33 * This driver is modeled after the orinoco_plx driver. The main
diff --git a/drivers/net/wireless/orinoco/scan.c b/drivers/net/wireless/orinoco/scan.c
new file mode 100644
index 000000000000..89d699d4dfe6
--- /dev/null
+++ b/drivers/net/wireless/orinoco/scan.c
@@ -0,0 +1,233 @@
1/* Helpers for managing scan queues
2 *
3 * See copyright notice in main.c
4 */
5
6#include <linux/kernel.h>
7#include <linux/string.h>
8#include <linux/etherdevice.h>
9
10#include "hermes.h"
11#include "orinoco.h"
12
13#include "scan.h"
14
15#define ORINOCO_MAX_BSS_COUNT 64
16
17#define PRIV_BSS ((struct bss_element *)priv->bss_xbss_data)
18#define PRIV_XBSS ((struct xbss_element *)priv->bss_xbss_data)
19
20int orinoco_bss_data_allocate(struct orinoco_private *priv)
21{
22 if (priv->bss_xbss_data)
23 return 0;
24
25 if (priv->has_ext_scan)
26 priv->bss_xbss_data = kzalloc(ORINOCO_MAX_BSS_COUNT *
27 sizeof(struct xbss_element),
28 GFP_KERNEL);
29 else
30 priv->bss_xbss_data = kzalloc(ORINOCO_MAX_BSS_COUNT *
31 sizeof(struct bss_element),
32 GFP_KERNEL);
33
34 if (!priv->bss_xbss_data) {
35 printk(KERN_WARNING "Out of memory allocating beacons");
36 return -ENOMEM;
37 }
38 return 0;
39}
40
41void orinoco_bss_data_free(struct orinoco_private *priv)
42{
43 kfree(priv->bss_xbss_data);
44 priv->bss_xbss_data = NULL;
45}
46
47void orinoco_bss_data_init(struct orinoco_private *priv)
48{
49 int i;
50
51 INIT_LIST_HEAD(&priv->bss_free_list);
52 INIT_LIST_HEAD(&priv->bss_list);
53 if (priv->has_ext_scan)
54 for (i = 0; i < ORINOCO_MAX_BSS_COUNT; i++)
55 list_add_tail(&(PRIV_XBSS[i].list),
56 &priv->bss_free_list);
57 else
58 for (i = 0; i < ORINOCO_MAX_BSS_COUNT; i++)
59 list_add_tail(&(PRIV_BSS[i].list),
60 &priv->bss_free_list);
61
62}
63
64void orinoco_clear_scan_results(struct orinoco_private *priv,
65 unsigned long scan_age)
66{
67 if (priv->has_ext_scan) {
68 struct xbss_element *bss;
69 struct xbss_element *tmp_bss;
70
71 /* Blow away current list of scan results */
72 list_for_each_entry_safe(bss, tmp_bss, &priv->bss_list, list) {
73 if (!scan_age ||
74 time_after(jiffies, bss->last_scanned + scan_age)) {
75 list_move_tail(&bss->list,
76 &priv->bss_free_list);
77 /* Don't blow away ->list, just BSS data */
78 memset(&bss->bss, 0, sizeof(bss->bss));
79 bss->last_scanned = 0;
80 }
81 }
82 } else {
83 struct bss_element *bss;
84 struct bss_element *tmp_bss;
85
86 /* Blow away current list of scan results */
87 list_for_each_entry_safe(bss, tmp_bss, &priv->bss_list, list) {
88 if (!scan_age ||
89 time_after(jiffies, bss->last_scanned + scan_age)) {
90 list_move_tail(&bss->list,
91 &priv->bss_free_list);
92 /* Don't blow away ->list, just BSS data */
93 memset(&bss->bss, 0, sizeof(bss->bss));
94 bss->last_scanned = 0;
95 }
96 }
97 }
98}
99
100void orinoco_add_ext_scan_result(struct orinoco_private *priv,
101 struct agere_ext_scan_info *atom)
102{
103 struct xbss_element *bss = NULL;
104 int found = 0;
105
106 /* Try to update an existing bss first */
107 list_for_each_entry(bss, &priv->bss_list, list) {
108 if (compare_ether_addr(bss->bss.bssid, atom->bssid))
109 continue;
110 /* ESSID lengths */
111 if (bss->bss.data[1] != atom->data[1])
112 continue;
113 if (memcmp(&bss->bss.data[2], &atom->data[2],
114 atom->data[1]))
115 continue;
116 found = 1;
117 break;
118 }
119
120 /* Grab a bss off the free list */
121 if (!found && !list_empty(&priv->bss_free_list)) {
122 bss = list_entry(priv->bss_free_list.next,
123 struct xbss_element, list);
124 list_del(priv->bss_free_list.next);
125
126 list_add_tail(&bss->list, &priv->bss_list);
127 }
128
129 if (bss) {
130 /* Always update the BSS to get latest beacon info */
131 memcpy(&bss->bss, atom, sizeof(bss->bss));
132 bss->last_scanned = jiffies;
133 }
134}
135
136int orinoco_process_scan_results(struct orinoco_private *priv,
137 unsigned char *buf,
138 int len)
139{
140 int offset; /* In the scan data */
141 union hermes_scan_info *atom;
142 int atom_len;
143
144 switch (priv->firmware_type) {
145 case FIRMWARE_TYPE_AGERE:
146 atom_len = sizeof(struct agere_scan_apinfo);
147 offset = 0;
148 break;
149 case FIRMWARE_TYPE_SYMBOL:
150 /* Lack of documentation necessitates this hack.
151 * Different firmwares have 68 or 76 byte long atoms.
152 * We try modulo first. If the length divides by both,
153 * we check what would be the channel in the second
154 * frame for a 68-byte atom. 76-byte atoms have 0 there.
155 * Valid channel cannot be 0. */
156 if (len % 76)
157 atom_len = 68;
158 else if (len % 68)
159 atom_len = 76;
160 else if (len >= 1292 && buf[68] == 0)
161 atom_len = 76;
162 else
163 atom_len = 68;
164 offset = 0;
165 break;
166 case FIRMWARE_TYPE_INTERSIL:
167 offset = 4;
168 if (priv->has_hostscan) {
169 atom_len = le16_to_cpup((__le16 *)buf);
170 /* Sanity check for atom_len */
171 if (atom_len < sizeof(struct prism2_scan_apinfo)) {
172 printk(KERN_ERR "%s: Invalid atom_len in scan "
173 "data: %d\n", priv->ndev->name,
174 atom_len);
175 return -EIO;
176 }
177 } else
178 atom_len = offsetof(struct prism2_scan_apinfo, atim);
179 break;
180 default:
181 return -EOPNOTSUPP;
182 }
183
184 /* Check that we got an whole number of atoms */
185 if ((len - offset) % atom_len) {
186 printk(KERN_ERR "%s: Unexpected scan data length %d, "
187 "atom_len %d, offset %d\n", priv->ndev->name, len,
188 atom_len, offset);
189 return -EIO;
190 }
191
192 orinoco_clear_scan_results(priv, msecs_to_jiffies(15000));
193
194 /* Read the entries one by one */
195 for (; offset + atom_len <= len; offset += atom_len) {
196 int found = 0;
197 struct bss_element *bss = NULL;
198
199 /* Get next atom */
200 atom = (union hermes_scan_info *) (buf + offset);
201
202 /* Try to update an existing bss first */
203 list_for_each_entry(bss, &priv->bss_list, list) {
204 if (compare_ether_addr(bss->bss.a.bssid, atom->a.bssid))
205 continue;
206 if (le16_to_cpu(bss->bss.a.essid_len) !=
207 le16_to_cpu(atom->a.essid_len))
208 continue;
209 if (memcmp(bss->bss.a.essid, atom->a.essid,
210 le16_to_cpu(atom->a.essid_len)))
211 continue;
212 found = 1;
213 break;
214 }
215
216 /* Grab a bss off the free list */
217 if (!found && !list_empty(&priv->bss_free_list)) {
218 bss = list_entry(priv->bss_free_list.next,
219 struct bss_element, list);
220 list_del(priv->bss_free_list.next);
221
222 list_add_tail(&bss->list, &priv->bss_list);
223 }
224
225 if (bss) {
226 /* Always update the BSS to get latest beacon info */
227 memcpy(&bss->bss, atom, sizeof(bss->bss));
228 bss->last_scanned = jiffies;
229 }
230 }
231
232 return 0;
233}
diff --git a/drivers/net/wireless/orinoco/scan.h b/drivers/net/wireless/orinoco/scan.h
new file mode 100644
index 000000000000..f319f7466af1
--- /dev/null
+++ b/drivers/net/wireless/orinoco/scan.h
@@ -0,0 +1,29 @@
1/* Helpers for managing scan queues
2 *
3 * See copyright notice in main.c
4 */
5#ifndef _ORINOCO_SCAN_H_
6#define _ORINOCO_SCAN_H_
7
8/* Forward declarations */
9struct orinoco_private;
10struct agere_ext_scan_info;
11
12/* Setup and free memory for scan results */
13int orinoco_bss_data_allocate(struct orinoco_private *priv);
14void orinoco_bss_data_free(struct orinoco_private *priv);
15void orinoco_bss_data_init(struct orinoco_private *priv);
16
17/* Add scan results */
18void orinoco_add_ext_scan_result(struct orinoco_private *priv,
19 struct agere_ext_scan_info *atom);
20int orinoco_process_scan_results(struct orinoco_private *dev,
21 unsigned char *buf,
22 int len);
23
24/* Clear scan results */
25void orinoco_clear_scan_results(struct orinoco_private *priv,
26 unsigned long scan_age);
27
28
29#endif /* _ORINOCO_SCAN_H_ */
diff --git a/drivers/net/wireless/orinoco/spectrum_cs.c b/drivers/net/wireless/orinoco/spectrum_cs.c
index 9aefe19dbac2..38e5198e44c7 100644
--- a/drivers/net/wireless/orinoco/spectrum_cs.c
+++ b/drivers/net/wireless/orinoco/spectrum_cs.c
@@ -4,7 +4,7 @@
4 * Communications and Intel PRO/Wireless 2011B. 4 * Communications and Intel PRO/Wireless 2011B.
5 * 5 *
6 * The driver implements Symbol firmware download. The rest is handled 6 * The driver implements Symbol firmware download. The rest is handled
7 * in hermes.c and orinoco.c. 7 * in hermes.c and main.c.
8 * 8 *
9 * Utilities for downloading the Symbol firmware are available at 9 * Utilities for downloading the Symbol firmware are available at
10 * http://sourceforge.net/projects/orinoco/ 10 * http://sourceforge.net/projects/orinoco/
@@ -15,7 +15,7 @@
15 * Portions based on Spectrum24tDnld.c from original spectrum24 driver: 15 * Portions based on Spectrum24tDnld.c from original spectrum24 driver:
16 * Copyright (C) Symbol Technologies. 16 * Copyright (C) Symbol Technologies.
17 * 17 *
18 * See copyright notice in file orinoco.c. 18 * See copyright notice in file main.c.
19 */ 19 */
20 20
21#define DRIVER_NAME "spectrum_cs" 21#define DRIVER_NAME "spectrum_cs"
diff --git a/drivers/net/wireless/orinoco/wext.c b/drivers/net/wireless/orinoco/wext.c
new file mode 100644
index 000000000000..3f0814234392
--- /dev/null
+++ b/drivers/net/wireless/orinoco/wext.c
@@ -0,0 +1,2325 @@
1/* Wireless extensions support.
2 *
3 * See copyright notice in main.c
4 */
5#include <linux/kernel.h>
6#include <linux/if_arp.h>
7#include <linux/wireless.h>
8#include <linux/ieee80211.h>
9#include <net/iw_handler.h>
10
11#include "hermes.h"
12#include "hermes_rid.h"
13#include "orinoco.h"
14
15#include "hw.h"
16#include "mic.h"
17#include "scan.h"
18#include "main.h"
19
20#include "wext.h"
21
22#define MAX_RID_LEN 1024
23
24static struct iw_statistics *orinoco_get_wireless_stats(struct net_device *dev)
25{
26 struct orinoco_private *priv = netdev_priv(dev);
27 hermes_t *hw = &priv->hw;
28 struct iw_statistics *wstats = &priv->wstats;
29 int err;
30 unsigned long flags;
31
32 if (!netif_device_present(dev)) {
33 printk(KERN_WARNING "%s: get_wireless_stats() called while device not present\n",
34 dev->name);
35 return NULL; /* FIXME: Can we do better than this? */
36 }
37
38 /* If busy, return the old stats. Returning NULL may cause
39 * the interface to disappear from /proc/net/wireless */
40 if (orinoco_lock(priv, &flags) != 0)
41 return wstats;
42
43 /* We can't really wait for the tallies inquiry command to
44 * complete, so we just use the previous results and trigger
45 * a new tallies inquiry command for next time - Jean II */
46 /* FIXME: Really we should wait for the inquiry to come back -
47 * as it is the stats we give don't make a whole lot of sense.
48 * Unfortunately, it's not clear how to do that within the
49 * wireless extensions framework: I think we're in user
50 * context, but a lock seems to be held by the time we get in
51 * here so we're not safe to sleep here. */
52 hermes_inquire(hw, HERMES_INQ_TALLIES);
53
54 if (priv->iw_mode == IW_MODE_ADHOC) {
55 memset(&wstats->qual, 0, sizeof(wstats->qual));
56 /* If a spy address is defined, we report stats of the
57 * first spy address - Jean II */
58 if (SPY_NUMBER(priv)) {
59 wstats->qual.qual = priv->spy_data.spy_stat[0].qual;
60 wstats->qual.level = priv->spy_data.spy_stat[0].level;
61 wstats->qual.noise = priv->spy_data.spy_stat[0].noise;
62 wstats->qual.updated =
63 priv->spy_data.spy_stat[0].updated;
64 }
65 } else {
66 struct {
67 __le16 qual, signal, noise, unused;
68 } __attribute__ ((packed)) cq;
69
70 err = HERMES_READ_RECORD(hw, USER_BAP,
71 HERMES_RID_COMMSQUALITY, &cq);
72
73 if (!err) {
74 wstats->qual.qual = (int)le16_to_cpu(cq.qual);
75 wstats->qual.level = (int)le16_to_cpu(cq.signal) - 0x95;
76 wstats->qual.noise = (int)le16_to_cpu(cq.noise) - 0x95;
77 wstats->qual.updated =
78 IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
79 }
80 }
81
82 orinoco_unlock(priv, &flags);
83 return wstats;
84}
85
86/********************************************************************/
87/* Wireless extensions */
88/********************************************************************/
89
90static int orinoco_ioctl_getname(struct net_device *dev,
91 struct iw_request_info *info,
92 char *name,
93 char *extra)
94{
95 struct orinoco_private *priv = netdev_priv(dev);
96 int numrates;
97 int err;
98
99 err = orinoco_hw_get_bitratelist(priv, &numrates, NULL, 0);
100
101 if (!err && (numrates > 2))
102 strcpy(name, "IEEE 802.11b");
103 else
104 strcpy(name, "IEEE 802.11-DS");
105
106 return 0;
107}
108
109static int orinoco_ioctl_setwap(struct net_device *dev,
110 struct iw_request_info *info,
111 struct sockaddr *ap_addr,
112 char *extra)
113{
114 struct orinoco_private *priv = netdev_priv(dev);
115 int err = -EINPROGRESS; /* Call commit handler */
116 unsigned long flags;
117 static const u8 off_addr[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
118 static const u8 any_addr[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
119
120 if (orinoco_lock(priv, &flags) != 0)
121 return -EBUSY;
122
123 /* Enable automatic roaming - no sanity checks are needed */
124 if (memcmp(&ap_addr->sa_data, off_addr, ETH_ALEN) == 0 ||
125 memcmp(&ap_addr->sa_data, any_addr, ETH_ALEN) == 0) {
126 priv->bssid_fixed = 0;
127 memset(priv->desired_bssid, 0, ETH_ALEN);
128
129 /* "off" means keep existing connection */
130 if (ap_addr->sa_data[0] == 0) {
131 __orinoco_hw_set_wap(priv);
132 err = 0;
133 }
134 goto out;
135 }
136
137 if (priv->firmware_type == FIRMWARE_TYPE_AGERE) {
138 printk(KERN_WARNING "%s: Lucent/Agere firmware doesn't "
139 "support manual roaming\n",
140 dev->name);
141 err = -EOPNOTSUPP;
142 goto out;
143 }
144
145 if (priv->iw_mode != IW_MODE_INFRA) {
146 printk(KERN_WARNING "%s: Manual roaming supported only in "
147 "managed mode\n", dev->name);
148 err = -EOPNOTSUPP;
149 goto out;
150 }
151
152 /* Intersil firmware hangs without Desired ESSID */
153 if (priv->firmware_type == FIRMWARE_TYPE_INTERSIL &&
154 strlen(priv->desired_essid) == 0) {
155 printk(KERN_WARNING "%s: Desired ESSID must be set for "
156 "manual roaming\n", dev->name);
157 err = -EOPNOTSUPP;
158 goto out;
159 }
160
161 /* Finally, enable manual roaming */
162 priv->bssid_fixed = 1;
163 memcpy(priv->desired_bssid, &ap_addr->sa_data, ETH_ALEN);
164
165 out:
166 orinoco_unlock(priv, &flags);
167 return err;
168}
169
170static int orinoco_ioctl_getwap(struct net_device *dev,
171 struct iw_request_info *info,
172 struct sockaddr *ap_addr,
173 char *extra)
174{
175 struct orinoco_private *priv = netdev_priv(dev);
176
177 hermes_t *hw = &priv->hw;
178 int err = 0;
179 unsigned long flags;
180
181 if (orinoco_lock(priv, &flags) != 0)
182 return -EBUSY;
183
184 ap_addr->sa_family = ARPHRD_ETHER;
185 err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CURRENTBSSID,
186 ETH_ALEN, NULL, ap_addr->sa_data);
187
188 orinoco_unlock(priv, &flags);
189
190 return err;
191}
192
193static int orinoco_ioctl_setmode(struct net_device *dev,
194 struct iw_request_info *info,
195 u32 *mode,
196 char *extra)
197{
198 struct orinoco_private *priv = netdev_priv(dev);
199 int err = -EINPROGRESS; /* Call commit handler */
200 unsigned long flags;
201
202 if (priv->iw_mode == *mode)
203 return 0;
204
205 if (orinoco_lock(priv, &flags) != 0)
206 return -EBUSY;
207
208 switch (*mode) {
209 case IW_MODE_ADHOC:
210 if (!priv->has_ibss && !priv->has_port3)
211 err = -EOPNOTSUPP;
212 break;
213
214 case IW_MODE_INFRA:
215 break;
216
217 case IW_MODE_MONITOR:
218 if (priv->broken_monitor && !force_monitor) {
219 printk(KERN_WARNING "%s: Monitor mode support is "
220 "buggy in this firmware, not enabling\n",
221 dev->name);
222 err = -EOPNOTSUPP;
223 }
224 break;
225
226 default:
227 err = -EOPNOTSUPP;
228 break;
229 }
230
231 if (err == -EINPROGRESS) {
232 priv->iw_mode = *mode;
233 set_port_type(priv);
234 }
235
236 orinoco_unlock(priv, &flags);
237
238 return err;
239}
240
241static int orinoco_ioctl_getmode(struct net_device *dev,
242 struct iw_request_info *info,
243 u32 *mode,
244 char *extra)
245{
246 struct orinoco_private *priv = netdev_priv(dev);
247
248 *mode = priv->iw_mode;
249 return 0;
250}
251
252static int orinoco_ioctl_getiwrange(struct net_device *dev,
253 struct iw_request_info *info,
254 struct iw_point *rrq,
255 char *extra)
256{
257 struct orinoco_private *priv = netdev_priv(dev);
258 int err = 0;
259 struct iw_range *range = (struct iw_range *) extra;
260 int numrates;
261 int i, k;
262
263 rrq->length = sizeof(struct iw_range);
264 memset(range, 0, sizeof(struct iw_range));
265
266 range->we_version_compiled = WIRELESS_EXT;
267 range->we_version_source = 22;
268
269 /* Set available channels/frequencies */
270 range->num_channels = NUM_CHANNELS;
271 k = 0;
272 for (i = 0; i < NUM_CHANNELS; i++) {
273 if (priv->channel_mask & (1 << i)) {
274 range->freq[k].i = i + 1;
275 range->freq[k].m = (ieee80211_dsss_chan_to_freq(i + 1) *
276 100000);
277 range->freq[k].e = 1;
278 k++;
279 }
280
281 if (k >= IW_MAX_FREQUENCIES)
282 break;
283 }
284 range->num_frequency = k;
285 range->sensitivity = 3;
286
287 if (priv->has_wep) {
288 range->max_encoding_tokens = ORINOCO_MAX_KEYS;
289 range->encoding_size[0] = SMALL_KEY_SIZE;
290 range->num_encoding_sizes = 1;
291
292 if (priv->has_big_wep) {
293 range->encoding_size[1] = LARGE_KEY_SIZE;
294 range->num_encoding_sizes = 2;
295 }
296 }
297
298 if (priv->has_wpa)
299 range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_CIPHER_TKIP;
300
301 if ((priv->iw_mode == IW_MODE_ADHOC) && (!SPY_NUMBER(priv))) {
302 /* Quality stats meaningless in ad-hoc mode */
303 } else {
304 range->max_qual.qual = 0x8b - 0x2f;
305 range->max_qual.level = 0x2f - 0x95 - 1;
306 range->max_qual.noise = 0x2f - 0x95 - 1;
307 /* Need to get better values */
308 range->avg_qual.qual = 0x24;
309 range->avg_qual.level = 0xC2;
310 range->avg_qual.noise = 0x9E;
311 }
312
313 err = orinoco_hw_get_bitratelist(priv, &numrates,
314 range->bitrate, IW_MAX_BITRATES);
315 if (err)
316 return err;
317 range->num_bitrates = numrates;
318
319 /* Set an indication of the max TCP throughput in bit/s that we can
320 * expect using this interface. May be use for QoS stuff...
321 * Jean II */
322 if (numrates > 2)
323 range->throughput = 5 * 1000 * 1000; /* ~5 Mb/s */
324 else
325 range->throughput = 1.5 * 1000 * 1000; /* ~1.5 Mb/s */
326
327 range->min_rts = 0;
328 range->max_rts = 2347;
329 range->min_frag = 256;
330 range->max_frag = 2346;
331
332 range->min_pmp = 0;
333 range->max_pmp = 65535000;
334 range->min_pmt = 0;
335 range->max_pmt = 65535 * 1000; /* ??? */
336 range->pmp_flags = IW_POWER_PERIOD;
337 range->pmt_flags = IW_POWER_TIMEOUT;
338 range->pm_capa = (IW_POWER_PERIOD | IW_POWER_TIMEOUT |
339 IW_POWER_UNICAST_R);
340
341 range->retry_capa = IW_RETRY_LIMIT | IW_RETRY_LIFETIME;
342 range->retry_flags = IW_RETRY_LIMIT;
343 range->r_time_flags = IW_RETRY_LIFETIME;
344 range->min_retry = 0;
345 range->max_retry = 65535; /* ??? */
346 range->min_r_time = 0;
347 range->max_r_time = 65535 * 1000; /* ??? */
348
349 if (priv->firmware_type == FIRMWARE_TYPE_AGERE)
350 range->scan_capa = IW_SCAN_CAPA_ESSID;
351 else
352 range->scan_capa = IW_SCAN_CAPA_NONE;
353
354 /* Event capability (kernel) */
355 IW_EVENT_CAPA_SET_KERNEL(range->event_capa);
356 /* Event capability (driver) */
357 IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWTHRSPY);
358 IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWAP);
359 IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWSCAN);
360 IW_EVENT_CAPA_SET(range->event_capa, IWEVTXDROP);
361
362 return 0;
363}
364
365static int orinoco_ioctl_setiwencode(struct net_device *dev,
366 struct iw_request_info *info,
367 struct iw_point *erq,
368 char *keybuf)
369{
370 struct orinoco_private *priv = netdev_priv(dev);
371 int index = (erq->flags & IW_ENCODE_INDEX) - 1;
372 int setindex = priv->tx_key;
373 int encode_alg = priv->encode_alg;
374 int restricted = priv->wep_restrict;
375 u16 xlen = 0;
376 int err = -EINPROGRESS; /* Call commit handler */
377 unsigned long flags;
378
379 if (!priv->has_wep)
380 return -EOPNOTSUPP;
381
382 if (erq->pointer) {
383 /* We actually have a key to set - check its length */
384 if (erq->length > LARGE_KEY_SIZE)
385 return -E2BIG;
386
387 if ((erq->length > SMALL_KEY_SIZE) && !priv->has_big_wep)
388 return -E2BIG;
389 }
390
391 if (orinoco_lock(priv, &flags) != 0)
392 return -EBUSY;
393
394 /* Clear any TKIP key we have */
395 if ((priv->has_wpa) && (priv->encode_alg == IW_ENCODE_ALG_TKIP))
396 (void) orinoco_clear_tkip_key(priv, setindex);
397
398 if (erq->length > 0) {
399 if ((index < 0) || (index >= ORINOCO_MAX_KEYS))
400 index = priv->tx_key;
401
402 /* Adjust key length to a supported value */
403 if (erq->length > SMALL_KEY_SIZE)
404 xlen = LARGE_KEY_SIZE;
405 else if (erq->length > 0)
406 xlen = SMALL_KEY_SIZE;
407 else
408 xlen = 0;
409
410 /* Switch on WEP if off */
411 if ((encode_alg != IW_ENCODE_ALG_WEP) && (xlen > 0)) {
412 setindex = index;
413 encode_alg = IW_ENCODE_ALG_WEP;
414 }
415 } else {
416 /* Important note : if the user do "iwconfig eth0 enc off",
417 * we will arrive there with an index of -1. This is valid
418 * but need to be taken care off... Jean II */
419 if ((index < 0) || (index >= ORINOCO_MAX_KEYS)) {
420 if ((index != -1) || (erq->flags == 0)) {
421 err = -EINVAL;
422 goto out;
423 }
424 } else {
425 /* Set the index : Check that the key is valid */
426 if (priv->keys[index].len == 0) {
427 err = -EINVAL;
428 goto out;
429 }
430 setindex = index;
431 }
432 }
433
434 if (erq->flags & IW_ENCODE_DISABLED)
435 encode_alg = IW_ENCODE_ALG_NONE;
436 if (erq->flags & IW_ENCODE_OPEN)
437 restricted = 0;
438 if (erq->flags & IW_ENCODE_RESTRICTED)
439 restricted = 1;
440
441 if (erq->pointer && erq->length > 0) {
442 priv->keys[index].len = cpu_to_le16(xlen);
443 memset(priv->keys[index].data, 0,
444 sizeof(priv->keys[index].data));
445 memcpy(priv->keys[index].data, keybuf, erq->length);
446 }
447 priv->tx_key = setindex;
448
449 /* Try fast key change if connected and only keys are changed */
450 if ((priv->encode_alg == encode_alg) &&
451 (priv->wep_restrict == restricted) &&
452 netif_carrier_ok(dev)) {
453 err = __orinoco_hw_setup_wepkeys(priv);
454 /* No need to commit if successful */
455 goto out;
456 }
457
458 priv->encode_alg = encode_alg;
459 priv->wep_restrict = restricted;
460
461 out:
462 orinoco_unlock(priv, &flags);
463
464 return err;
465}
466
467static int orinoco_ioctl_getiwencode(struct net_device *dev,
468 struct iw_request_info *info,
469 struct iw_point *erq,
470 char *keybuf)
471{
472 struct orinoco_private *priv = netdev_priv(dev);
473 int index = (erq->flags & IW_ENCODE_INDEX) - 1;
474 u16 xlen = 0;
475 unsigned long flags;
476
477 if (!priv->has_wep)
478 return -EOPNOTSUPP;
479
480 if (orinoco_lock(priv, &flags) != 0)
481 return -EBUSY;
482
483 if ((index < 0) || (index >= ORINOCO_MAX_KEYS))
484 index = priv->tx_key;
485
486 erq->flags = 0;
487 if (!priv->encode_alg)
488 erq->flags |= IW_ENCODE_DISABLED;
489 erq->flags |= index + 1;
490
491 if (priv->wep_restrict)
492 erq->flags |= IW_ENCODE_RESTRICTED;
493 else
494 erq->flags |= IW_ENCODE_OPEN;
495
496 xlen = le16_to_cpu(priv->keys[index].len);
497
498 erq->length = xlen;
499
500 memcpy(keybuf, priv->keys[index].data, ORINOCO_MAX_KEY_SIZE);
501
502 orinoco_unlock(priv, &flags);
503 return 0;
504}
505
506static int orinoco_ioctl_setessid(struct net_device *dev,
507 struct iw_request_info *info,
508 struct iw_point *erq,
509 char *essidbuf)
510{
511 struct orinoco_private *priv = netdev_priv(dev);
512 unsigned long flags;
513
514 /* Note : ESSID is ignored in Ad-Hoc demo mode, but we can set it
515 * anyway... - Jean II */
516
517 /* Hum... Should not use Wireless Extension constant (may change),
518 * should use our own... - Jean II */
519 if (erq->length > IW_ESSID_MAX_SIZE)
520 return -E2BIG;
521
522 if (orinoco_lock(priv, &flags) != 0)
523 return -EBUSY;
524
525 /* NULL the string (for NULL termination & ESSID = ANY) - Jean II */
526 memset(priv->desired_essid, 0, sizeof(priv->desired_essid));
527
528 /* If not ANY, get the new ESSID */
529 if (erq->flags)
530 memcpy(priv->desired_essid, essidbuf, erq->length);
531
532 orinoco_unlock(priv, &flags);
533
534 return -EINPROGRESS; /* Call commit handler */
535}
536
537static int orinoco_ioctl_getessid(struct net_device *dev,
538 struct iw_request_info *info,
539 struct iw_point *erq,
540 char *essidbuf)
541{
542 struct orinoco_private *priv = netdev_priv(dev);
543 int active;
544 int err = 0;
545 unsigned long flags;
546
547 if (netif_running(dev)) {
548 err = orinoco_hw_get_essid(priv, &active, essidbuf);
549 if (err < 0)
550 return err;
551 erq->length = err;
552 } else {
553 if (orinoco_lock(priv, &flags) != 0)
554 return -EBUSY;
555 memcpy(essidbuf, priv->desired_essid, IW_ESSID_MAX_SIZE);
556 erq->length = strlen(priv->desired_essid);
557 orinoco_unlock(priv, &flags);
558 }
559
560 erq->flags = 1;
561
562 return 0;
563}
564
565static int orinoco_ioctl_setnick(struct net_device *dev,
566 struct iw_request_info *info,
567 struct iw_point *nrq,
568 char *nickbuf)
569{
570 struct orinoco_private *priv = netdev_priv(dev);
571 unsigned long flags;
572
573 if (nrq->length > IW_ESSID_MAX_SIZE)
574 return -E2BIG;
575
576 if (orinoco_lock(priv, &flags) != 0)
577 return -EBUSY;
578
579 memset(priv->nick, 0, sizeof(priv->nick));
580 memcpy(priv->nick, nickbuf, nrq->length);
581
582 orinoco_unlock(priv, &flags);
583
584 return -EINPROGRESS; /* Call commit handler */
585}
586
587static int orinoco_ioctl_getnick(struct net_device *dev,
588 struct iw_request_info *info,
589 struct iw_point *nrq,
590 char *nickbuf)
591{
592 struct orinoco_private *priv = netdev_priv(dev);
593 unsigned long flags;
594
595 if (orinoco_lock(priv, &flags) != 0)
596 return -EBUSY;
597
598 memcpy(nickbuf, priv->nick, IW_ESSID_MAX_SIZE);
599 orinoco_unlock(priv, &flags);
600
601 nrq->length = strlen(priv->nick);
602
603 return 0;
604}
605
606static int orinoco_ioctl_setfreq(struct net_device *dev,
607 struct iw_request_info *info,
608 struct iw_freq *frq,
609 char *extra)
610{
611 struct orinoco_private *priv = netdev_priv(dev);
612 int chan = -1;
613 unsigned long flags;
614 int err = -EINPROGRESS; /* Call commit handler */
615
616 /* In infrastructure mode the AP sets the channel */
617 if (priv->iw_mode == IW_MODE_INFRA)
618 return -EBUSY;
619
620 if ((frq->e == 0) && (frq->m <= 1000)) {
621 /* Setting by channel number */
622 chan = frq->m;
623 } else {
624 /* Setting by frequency */
625 int denom = 1;
626 int i;
627
628 /* Calculate denominator to rescale to MHz */
629 for (i = 0; i < (6 - frq->e); i++)
630 denom *= 10;
631
632 chan = ieee80211_freq_to_dsss_chan(frq->m / denom);
633 }
634
635 if ((chan < 1) || (chan > NUM_CHANNELS) ||
636 !(priv->channel_mask & (1 << (chan-1))))
637 return -EINVAL;
638
639 if (orinoco_lock(priv, &flags) != 0)
640 return -EBUSY;
641
642 priv->channel = chan;
643 if (priv->iw_mode == IW_MODE_MONITOR) {
644 /* Fast channel change - no commit if successful */
645 hermes_t *hw = &priv->hw;
646 err = hermes_docmd_wait(hw, HERMES_CMD_TEST |
647 HERMES_TEST_SET_CHANNEL,
648 chan, NULL);
649 }
650 orinoco_unlock(priv, &flags);
651
652 return err;
653}
654
655static int orinoco_ioctl_getfreq(struct net_device *dev,
656 struct iw_request_info *info,
657 struct iw_freq *frq,
658 char *extra)
659{
660 struct orinoco_private *priv = netdev_priv(dev);
661 int tmp;
662
663 /* Locking done in there */
664 tmp = orinoco_hw_get_freq(priv);
665 if (tmp < 0)
666 return tmp;
667
668 frq->m = tmp * 100000;
669 frq->e = 1;
670
671 return 0;
672}
673
674static int orinoco_ioctl_getsens(struct net_device *dev,
675 struct iw_request_info *info,
676 struct iw_param *srq,
677 char *extra)
678{
679 struct orinoco_private *priv = netdev_priv(dev);
680 hermes_t *hw = &priv->hw;
681 u16 val;
682 int err;
683 unsigned long flags;
684
685 if (!priv->has_sensitivity)
686 return -EOPNOTSUPP;
687
688 if (orinoco_lock(priv, &flags) != 0)
689 return -EBUSY;
690 err = hermes_read_wordrec(hw, USER_BAP,
691 HERMES_RID_CNFSYSTEMSCALE, &val);
692 orinoco_unlock(priv, &flags);
693
694 if (err)
695 return err;
696
697 srq->value = val;
698 srq->fixed = 0; /* auto */
699
700 return 0;
701}
702
703static int orinoco_ioctl_setsens(struct net_device *dev,
704 struct iw_request_info *info,
705 struct iw_param *srq,
706 char *extra)
707{
708 struct orinoco_private *priv = netdev_priv(dev);
709 int val = srq->value;
710 unsigned long flags;
711
712 if (!priv->has_sensitivity)
713 return -EOPNOTSUPP;
714
715 if ((val < 1) || (val > 3))
716 return -EINVAL;
717
718 if (orinoco_lock(priv, &flags) != 0)
719 return -EBUSY;
720 priv->ap_density = val;
721 orinoco_unlock(priv, &flags);
722
723 return -EINPROGRESS; /* Call commit handler */
724}
725
726static int orinoco_ioctl_setrts(struct net_device *dev,
727 struct iw_request_info *info,
728 struct iw_param *rrq,
729 char *extra)
730{
731 struct orinoco_private *priv = netdev_priv(dev);
732 int val = rrq->value;
733 unsigned long flags;
734
735 if (rrq->disabled)
736 val = 2347;
737
738 if ((val < 0) || (val > 2347))
739 return -EINVAL;
740
741 if (orinoco_lock(priv, &flags) != 0)
742 return -EBUSY;
743
744 priv->rts_thresh = val;
745 orinoco_unlock(priv, &flags);
746
747 return -EINPROGRESS; /* Call commit handler */
748}
749
750static int orinoco_ioctl_getrts(struct net_device *dev,
751 struct iw_request_info *info,
752 struct iw_param *rrq,
753 char *extra)
754{
755 struct orinoco_private *priv = netdev_priv(dev);
756
757 rrq->value = priv->rts_thresh;
758 rrq->disabled = (rrq->value == 2347);
759 rrq->fixed = 1;
760
761 return 0;
762}
763
764static int orinoco_ioctl_setfrag(struct net_device *dev,
765 struct iw_request_info *info,
766 struct iw_param *frq,
767 char *extra)
768{
769 struct orinoco_private *priv = netdev_priv(dev);
770 int err = -EINPROGRESS; /* Call commit handler */
771 unsigned long flags;
772
773 if (orinoco_lock(priv, &flags) != 0)
774 return -EBUSY;
775
776 if (priv->has_mwo) {
777 if (frq->disabled)
778 priv->mwo_robust = 0;
779 else {
780 if (frq->fixed)
781 printk(KERN_WARNING "%s: Fixed fragmentation "
782 "is not supported on this firmware. "
783 "Using MWO robust instead.\n",
784 dev->name);
785 priv->mwo_robust = 1;
786 }
787 } else {
788 if (frq->disabled)
789 priv->frag_thresh = 2346;
790 else {
791 if ((frq->value < 256) || (frq->value > 2346))
792 err = -EINVAL;
793 else
794 /* must be even */
795 priv->frag_thresh = frq->value & ~0x1;
796 }
797 }
798
799 orinoco_unlock(priv, &flags);
800
801 return err;
802}
803
804static int orinoco_ioctl_getfrag(struct net_device *dev,
805 struct iw_request_info *info,
806 struct iw_param *frq,
807 char *extra)
808{
809 struct orinoco_private *priv = netdev_priv(dev);
810 hermes_t *hw = &priv->hw;
811 int err;
812 u16 val;
813 unsigned long flags;
814
815 if (orinoco_lock(priv, &flags) != 0)
816 return -EBUSY;
817
818 if (priv->has_mwo) {
819 err = hermes_read_wordrec(hw, USER_BAP,
820 HERMES_RID_CNFMWOROBUST_AGERE,
821 &val);
822 if (err)
823 val = 0;
824
825 frq->value = val ? 2347 : 0;
826 frq->disabled = !val;
827 frq->fixed = 0;
828 } else {
829 err = hermes_read_wordrec(hw, USER_BAP,
830 HERMES_RID_CNFFRAGMENTATIONTHRESHOLD,
831 &val);
832 if (err)
833 val = 0;
834
835 frq->value = val;
836 frq->disabled = (val >= 2346);
837 frq->fixed = 1;
838 }
839
840 orinoco_unlock(priv, &flags);
841
842 return err;
843}
844
845static int orinoco_ioctl_setrate(struct net_device *dev,
846 struct iw_request_info *info,
847 struct iw_param *rrq,
848 char *extra)
849{
850 struct orinoco_private *priv = netdev_priv(dev);
851 int ratemode;
852 int bitrate; /* 100s of kilobits */
853 unsigned long flags;
854
855 /* As the user space doesn't know our highest rate, it uses -1
856 * to ask us to set the highest rate. Test it using "iwconfig
857 * ethX rate auto" - Jean II */
858 if (rrq->value == -1)
859 bitrate = 110;
860 else {
861 if (rrq->value % 100000)
862 return -EINVAL;
863 bitrate = rrq->value / 100000;
864 }
865
866 ratemode = orinoco_get_bitratemode(bitrate, !rrq->fixed);
867
868 if (ratemode == -1)
869 return -EINVAL;
870
871 if (orinoco_lock(priv, &flags) != 0)
872 return -EBUSY;
873 priv->bitratemode = ratemode;
874 orinoco_unlock(priv, &flags);
875
876 return -EINPROGRESS;
877}
878
879static int orinoco_ioctl_getrate(struct net_device *dev,
880 struct iw_request_info *info,
881 struct iw_param *rrq,
882 char *extra)
883{
884 struct orinoco_private *priv = netdev_priv(dev);
885 int err = 0;
886 int bitrate, automatic;
887 unsigned long flags;
888
889 if (orinoco_lock(priv, &flags) != 0)
890 return -EBUSY;
891
892 orinoco_get_ratemode_cfg(priv->bitratemode, &bitrate, &automatic);
893
894 /* If the interface is running we try to find more about the
895 current mode */
896 if (netif_running(dev))
897 err = orinoco_hw_get_act_bitrate(priv, &bitrate);
898
899 orinoco_unlock(priv, &flags);
900
901 rrq->value = bitrate;
902 rrq->fixed = !automatic;
903 rrq->disabled = 0;
904
905 return err;
906}
907
908static int orinoco_ioctl_setpower(struct net_device *dev,
909 struct iw_request_info *info,
910 struct iw_param *prq,
911 char *extra)
912{
913 struct orinoco_private *priv = netdev_priv(dev);
914 int err = -EINPROGRESS; /* Call commit handler */
915 unsigned long flags;
916
917 if (orinoco_lock(priv, &flags) != 0)
918 return -EBUSY;
919
920 if (prq->disabled) {
921 priv->pm_on = 0;
922 } else {
923 switch (prq->flags & IW_POWER_MODE) {
924 case IW_POWER_UNICAST_R:
925 priv->pm_mcast = 0;
926 priv->pm_on = 1;
927 break;
928 case IW_POWER_ALL_R:
929 priv->pm_mcast = 1;
930 priv->pm_on = 1;
931 break;
932 case IW_POWER_ON:
933 /* No flags : but we may have a value - Jean II */
934 break;
935 default:
936 err = -EINVAL;
937 goto out;
938 }
939
940 if (prq->flags & IW_POWER_TIMEOUT) {
941 priv->pm_on = 1;
942 priv->pm_timeout = prq->value / 1000;
943 }
944 if (prq->flags & IW_POWER_PERIOD) {
945 priv->pm_on = 1;
946 priv->pm_period = prq->value / 1000;
947 }
948 /* It's valid to not have a value if we are just toggling
949 * the flags... Jean II */
950 if (!priv->pm_on) {
951 err = -EINVAL;
952 goto out;
953 }
954 }
955
956 out:
957 orinoco_unlock(priv, &flags);
958
959 return err;
960}
961
962static int orinoco_ioctl_getpower(struct net_device *dev,
963 struct iw_request_info *info,
964 struct iw_param *prq,
965 char *extra)
966{
967 struct orinoco_private *priv = netdev_priv(dev);
968 hermes_t *hw = &priv->hw;
969 int err = 0;
970 u16 enable, period, timeout, mcast;
971 unsigned long flags;
972
973 if (orinoco_lock(priv, &flags) != 0)
974 return -EBUSY;
975
976 err = hermes_read_wordrec(hw, USER_BAP,
977 HERMES_RID_CNFPMENABLED, &enable);
978 if (err)
979 goto out;
980
981 err = hermes_read_wordrec(hw, USER_BAP,
982 HERMES_RID_CNFMAXSLEEPDURATION, &period);
983 if (err)
984 goto out;
985
986 err = hermes_read_wordrec(hw, USER_BAP,
987 HERMES_RID_CNFPMHOLDOVERDURATION, &timeout);
988 if (err)
989 goto out;
990
991 err = hermes_read_wordrec(hw, USER_BAP,
992 HERMES_RID_CNFMULTICASTRECEIVE, &mcast);
993 if (err)
994 goto out;
995
996 prq->disabled = !enable;
997 /* Note : by default, display the period */
998 if ((prq->flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) {
999 prq->flags = IW_POWER_TIMEOUT;
1000 prq->value = timeout * 1000;
1001 } else {
1002 prq->flags = IW_POWER_PERIOD;
1003 prq->value = period * 1000;
1004 }
1005 if (mcast)
1006 prq->flags |= IW_POWER_ALL_R;
1007 else
1008 prq->flags |= IW_POWER_UNICAST_R;
1009
1010 out:
1011 orinoco_unlock(priv, &flags);
1012
1013 return err;
1014}
1015
1016static int orinoco_ioctl_set_encodeext(struct net_device *dev,
1017 struct iw_request_info *info,
1018 union iwreq_data *wrqu,
1019 char *extra)
1020{
1021 struct orinoco_private *priv = netdev_priv(dev);
1022 struct iw_point *encoding = &wrqu->encoding;
1023 struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
1024 int idx, alg = ext->alg, set_key = 1;
1025 unsigned long flags;
1026 int err = -EINVAL;
1027 u16 key_len;
1028
1029 if (orinoco_lock(priv, &flags) != 0)
1030 return -EBUSY;
1031
1032 /* Determine and validate the key index */
1033 idx = encoding->flags & IW_ENCODE_INDEX;
1034 if (idx) {
1035 if ((idx < 1) || (idx > 4))
1036 goto out;
1037 idx--;
1038 } else
1039 idx = priv->tx_key;
1040
1041 if (encoding->flags & IW_ENCODE_DISABLED)
1042 alg = IW_ENCODE_ALG_NONE;
1043
1044 if (priv->has_wpa && (alg != IW_ENCODE_ALG_TKIP)) {
1045 /* Clear any TKIP TX key we had */
1046 (void) orinoco_clear_tkip_key(priv, priv->tx_key);
1047 }
1048
1049 if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
1050 priv->tx_key = idx;
1051 set_key = ((alg == IW_ENCODE_ALG_TKIP) ||
1052 (ext->key_len > 0)) ? 1 : 0;
1053 }
1054
1055 if (set_key) {
1056 /* Set the requested key first */
1057 switch (alg) {
1058 case IW_ENCODE_ALG_NONE:
1059 priv->encode_alg = alg;
1060 priv->keys[idx].len = 0;
1061 break;
1062
1063 case IW_ENCODE_ALG_WEP:
1064 if (ext->key_len > SMALL_KEY_SIZE)
1065 key_len = LARGE_KEY_SIZE;
1066 else if (ext->key_len > 0)
1067 key_len = SMALL_KEY_SIZE;
1068 else
1069 goto out;
1070
1071 priv->encode_alg = alg;
1072 priv->keys[idx].len = cpu_to_le16(key_len);
1073
1074 key_len = min(ext->key_len, key_len);
1075
1076 memset(priv->keys[idx].data, 0, ORINOCO_MAX_KEY_SIZE);
1077 memcpy(priv->keys[idx].data, ext->key, key_len);
1078 break;
1079
1080 case IW_ENCODE_ALG_TKIP:
1081 {
1082 hermes_t *hw = &priv->hw;
1083 u8 *tkip_iv = NULL;
1084
1085 if (!priv->has_wpa ||
1086 (ext->key_len > sizeof(priv->tkip_key[0])))
1087 goto out;
1088
1089 priv->encode_alg = alg;
1090 memset(&priv->tkip_key[idx], 0,
1091 sizeof(priv->tkip_key[idx]));
1092 memcpy(&priv->tkip_key[idx], ext->key, ext->key_len);
1093
1094 if (ext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID)
1095 tkip_iv = &ext->rx_seq[0];
1096
1097 err = __orinoco_hw_set_tkip_key(hw, idx,
1098 ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY,
1099 (u8 *) &priv->tkip_key[idx],
1100 tkip_iv, NULL);
1101 if (err)
1102 printk(KERN_ERR "%s: Error %d setting TKIP key"
1103 "\n", dev->name, err);
1104
1105 goto out;
1106 }
1107 default:
1108 goto out;
1109 }
1110 }
1111 err = -EINPROGRESS;
1112 out:
1113 orinoco_unlock(priv, &flags);
1114
1115 return err;
1116}
1117
1118static int orinoco_ioctl_get_encodeext(struct net_device *dev,
1119 struct iw_request_info *info,
1120 union iwreq_data *wrqu,
1121 char *extra)
1122{
1123 struct orinoco_private *priv = netdev_priv(dev);
1124 struct iw_point *encoding = &wrqu->encoding;
1125 struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
1126 int idx, max_key_len;
1127 unsigned long flags;
1128 int err;
1129
1130 if (orinoco_lock(priv, &flags) != 0)
1131 return -EBUSY;
1132
1133 err = -EINVAL;
1134 max_key_len = encoding->length - sizeof(*ext);
1135 if (max_key_len < 0)
1136 goto out;
1137
1138 idx = encoding->flags & IW_ENCODE_INDEX;
1139 if (idx) {
1140 if ((idx < 1) || (idx > 4))
1141 goto out;
1142 idx--;
1143 } else
1144 idx = priv->tx_key;
1145
1146 encoding->flags = idx + 1;
1147 memset(ext, 0, sizeof(*ext));
1148
1149 ext->alg = priv->encode_alg;
1150 switch (priv->encode_alg) {
1151 case IW_ENCODE_ALG_NONE:
1152 ext->key_len = 0;
1153 encoding->flags |= IW_ENCODE_DISABLED;
1154 break;
1155 case IW_ENCODE_ALG_WEP:
1156 ext->key_len = min_t(u16, le16_to_cpu(priv->keys[idx].len),
1157 max_key_len);
1158 memcpy(ext->key, priv->keys[idx].data, ext->key_len);
1159 encoding->flags |= IW_ENCODE_ENABLED;
1160 break;
1161 case IW_ENCODE_ALG_TKIP:
1162 ext->key_len = min_t(u16, sizeof(struct orinoco_tkip_key),
1163 max_key_len);
1164 memcpy(ext->key, &priv->tkip_key[idx], ext->key_len);
1165 encoding->flags |= IW_ENCODE_ENABLED;
1166 break;
1167 }
1168
1169 err = 0;
1170 out:
1171 orinoco_unlock(priv, &flags);
1172
1173 return err;
1174}
1175
1176static int orinoco_ioctl_set_auth(struct net_device *dev,
1177 struct iw_request_info *info,
1178 union iwreq_data *wrqu, char *extra)
1179{
1180 struct orinoco_private *priv = netdev_priv(dev);
1181 hermes_t *hw = &priv->hw;
1182 struct iw_param *param = &wrqu->param;
1183 unsigned long flags;
1184 int ret = -EINPROGRESS;
1185
1186 if (orinoco_lock(priv, &flags) != 0)
1187 return -EBUSY;
1188
1189 switch (param->flags & IW_AUTH_INDEX) {
1190 case IW_AUTH_WPA_VERSION:
1191 case IW_AUTH_CIPHER_PAIRWISE:
1192 case IW_AUTH_CIPHER_GROUP:
1193 case IW_AUTH_RX_UNENCRYPTED_EAPOL:
1194 case IW_AUTH_PRIVACY_INVOKED:
1195 case IW_AUTH_DROP_UNENCRYPTED:
1196 /*
1197 * orinoco does not use these parameters
1198 */
1199 break;
1200
1201 case IW_AUTH_KEY_MGMT:
1202 /* wl_lkm implies value 2 == PSK for Hermes I
1203 * which ties in with WEXT
1204 * no other hints tho :(
1205 */
1206 priv->key_mgmt = param->value;
1207 break;
1208
1209 case IW_AUTH_TKIP_COUNTERMEASURES:
1210 /* When countermeasures are enabled, shut down the
1211 * card; when disabled, re-enable the card. This must
1212 * take effect immediately.
1213 *
1214 * TODO: Make sure that the EAPOL message is getting
1215 * out before card disabled
1216 */
1217 if (param->value) {
1218 priv->tkip_cm_active = 1;
1219 ret = hermes_enable_port(hw, 0);
1220 } else {
1221 priv->tkip_cm_active = 0;
1222 ret = hermes_disable_port(hw, 0);
1223 }
1224 break;
1225
1226 case IW_AUTH_80211_AUTH_ALG:
1227 if (param->value & IW_AUTH_ALG_SHARED_KEY)
1228 priv->wep_restrict = 1;
1229 else if (param->value & IW_AUTH_ALG_OPEN_SYSTEM)
1230 priv->wep_restrict = 0;
1231 else
1232 ret = -EINVAL;
1233 break;
1234
1235 case IW_AUTH_WPA_ENABLED:
1236 if (priv->has_wpa) {
1237 priv->wpa_enabled = param->value ? 1 : 0;
1238 } else {
1239 if (param->value)
1240 ret = -EOPNOTSUPP;
1241 /* else silently accept disable of WPA */
1242 priv->wpa_enabled = 0;
1243 }
1244 break;
1245
1246 default:
1247 ret = -EOPNOTSUPP;
1248 }
1249
1250 orinoco_unlock(priv, &flags);
1251 return ret;
1252}
1253
1254static int orinoco_ioctl_get_auth(struct net_device *dev,
1255 struct iw_request_info *info,
1256 union iwreq_data *wrqu, char *extra)
1257{
1258 struct orinoco_private *priv = netdev_priv(dev);
1259 struct iw_param *param = &wrqu->param;
1260 unsigned long flags;
1261 int ret = 0;
1262
1263 if (orinoco_lock(priv, &flags) != 0)
1264 return -EBUSY;
1265
1266 switch (param->flags & IW_AUTH_INDEX) {
1267 case IW_AUTH_KEY_MGMT:
1268 param->value = priv->key_mgmt;
1269 break;
1270
1271 case IW_AUTH_TKIP_COUNTERMEASURES:
1272 param->value = priv->tkip_cm_active;
1273 break;
1274
1275 case IW_AUTH_80211_AUTH_ALG:
1276 if (priv->wep_restrict)
1277 param->value = IW_AUTH_ALG_SHARED_KEY;
1278 else
1279 param->value = IW_AUTH_ALG_OPEN_SYSTEM;
1280 break;
1281
1282 case IW_AUTH_WPA_ENABLED:
1283 param->value = priv->wpa_enabled;
1284 break;
1285
1286 default:
1287 ret = -EOPNOTSUPP;
1288 }
1289
1290 orinoco_unlock(priv, &flags);
1291 return ret;
1292}
1293
1294static int orinoco_ioctl_set_genie(struct net_device *dev,
1295 struct iw_request_info *info,
1296 union iwreq_data *wrqu, char *extra)
1297{
1298 struct orinoco_private *priv = netdev_priv(dev);
1299 u8 *buf;
1300 unsigned long flags;
1301
1302 /* cut off at IEEE80211_MAX_DATA_LEN */
1303 if ((wrqu->data.length > IEEE80211_MAX_DATA_LEN) ||
1304 (wrqu->data.length && (extra == NULL)))
1305 return -EINVAL;
1306
1307 if (wrqu->data.length) {
1308 buf = kmalloc(wrqu->data.length, GFP_KERNEL);
1309 if (buf == NULL)
1310 return -ENOMEM;
1311
1312 memcpy(buf, extra, wrqu->data.length);
1313 } else
1314 buf = NULL;
1315
1316 if (orinoco_lock(priv, &flags) != 0) {
1317 kfree(buf);
1318 return -EBUSY;
1319 }
1320
1321 kfree(priv->wpa_ie);
1322 priv->wpa_ie = buf;
1323 priv->wpa_ie_len = wrqu->data.length;
1324
1325 if (priv->wpa_ie) {
1326 /* Looks like wl_lkm wants to check the auth alg, and
1327 * somehow pass it to the firmware.
1328 * Instead it just calls the key mgmt rid
1329 * - we do this in set auth.
1330 */
1331 }
1332
1333 orinoco_unlock(priv, &flags);
1334 return 0;
1335}
1336
1337static int orinoco_ioctl_get_genie(struct net_device *dev,
1338 struct iw_request_info *info,
1339 union iwreq_data *wrqu, char *extra)
1340{
1341 struct orinoco_private *priv = netdev_priv(dev);
1342 unsigned long flags;
1343 int err = 0;
1344
1345 if (orinoco_lock(priv, &flags) != 0)
1346 return -EBUSY;
1347
1348 if ((priv->wpa_ie_len == 0) || (priv->wpa_ie == NULL)) {
1349 wrqu->data.length = 0;
1350 goto out;
1351 }
1352
1353 if (wrqu->data.length < priv->wpa_ie_len) {
1354 err = -E2BIG;
1355 goto out;
1356 }
1357
1358 wrqu->data.length = priv->wpa_ie_len;
1359 memcpy(extra, priv->wpa_ie, priv->wpa_ie_len);
1360
1361out:
1362 orinoco_unlock(priv, &flags);
1363 return err;
1364}
1365
1366static int orinoco_ioctl_set_mlme(struct net_device *dev,
1367 struct iw_request_info *info,
1368 union iwreq_data *wrqu, char *extra)
1369{
1370 struct orinoco_private *priv = netdev_priv(dev);
1371 hermes_t *hw = &priv->hw;
1372 struct iw_mlme *mlme = (struct iw_mlme *)extra;
1373 unsigned long flags;
1374 int ret = 0;
1375
1376 if (orinoco_lock(priv, &flags) != 0)
1377 return -EBUSY;
1378
1379 switch (mlme->cmd) {
1380 case IW_MLME_DEAUTH:
1381 /* silently ignore */
1382 break;
1383
1384 case IW_MLME_DISASSOC:
1385 {
1386 struct {
1387 u8 addr[ETH_ALEN];
1388 __le16 reason_code;
1389 } __attribute__ ((packed)) buf;
1390
1391 memcpy(buf.addr, mlme->addr.sa_data, ETH_ALEN);
1392 buf.reason_code = cpu_to_le16(mlme->reason_code);
1393 ret = HERMES_WRITE_RECORD(hw, USER_BAP,
1394 HERMES_RID_CNFDISASSOCIATE,
1395 &buf);
1396 break;
1397 }
1398 default:
1399 ret = -EOPNOTSUPP;
1400 }
1401
1402 orinoco_unlock(priv, &flags);
1403 return ret;
1404}
1405
1406static int orinoco_ioctl_getretry(struct net_device *dev,
1407 struct iw_request_info *info,
1408 struct iw_param *rrq,
1409 char *extra)
1410{
1411 struct orinoco_private *priv = netdev_priv(dev);
1412 hermes_t *hw = &priv->hw;
1413 int err = 0;
1414 u16 short_limit, long_limit, lifetime;
1415 unsigned long flags;
1416
1417 if (orinoco_lock(priv, &flags) != 0)
1418 return -EBUSY;
1419
1420 err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_SHORTRETRYLIMIT,
1421 &short_limit);
1422 if (err)
1423 goto out;
1424
1425 err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_LONGRETRYLIMIT,
1426 &long_limit);
1427 if (err)
1428 goto out;
1429
1430 err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_MAXTRANSMITLIFETIME,
1431 &lifetime);
1432 if (err)
1433 goto out;
1434
1435 rrq->disabled = 0; /* Can't be disabled */
1436
1437 /* Note : by default, display the retry number */
1438 if ((rrq->flags & IW_RETRY_TYPE) == IW_RETRY_LIFETIME) {
1439 rrq->flags = IW_RETRY_LIFETIME;
1440 rrq->value = lifetime * 1000; /* ??? */
1441 } else {
1442 /* By default, display the min number */
1443 if ((rrq->flags & IW_RETRY_LONG)) {
1444 rrq->flags = IW_RETRY_LIMIT | IW_RETRY_LONG;
1445 rrq->value = long_limit;
1446 } else {
1447 rrq->flags = IW_RETRY_LIMIT;
1448 rrq->value = short_limit;
1449 if (short_limit != long_limit)
1450 rrq->flags |= IW_RETRY_SHORT;
1451 }
1452 }
1453
1454 out:
1455 orinoco_unlock(priv, &flags);
1456
1457 return err;
1458}
1459
1460static int orinoco_ioctl_reset(struct net_device *dev,
1461 struct iw_request_info *info,
1462 void *wrqu,
1463 char *extra)
1464{
1465 struct orinoco_private *priv = netdev_priv(dev);
1466
1467 if (!capable(CAP_NET_ADMIN))
1468 return -EPERM;
1469
1470 if (info->cmd == (SIOCIWFIRSTPRIV + 0x1)) {
1471 printk(KERN_DEBUG "%s: Forcing reset!\n", dev->name);
1472
1473 /* Firmware reset */
1474 orinoco_reset(&priv->reset_work);
1475 } else {
1476 printk(KERN_DEBUG "%s: Force scheduling reset!\n", dev->name);
1477
1478 schedule_work(&priv->reset_work);
1479 }
1480
1481 return 0;
1482}
1483
1484static int orinoco_ioctl_setibssport(struct net_device *dev,
1485 struct iw_request_info *info,
1486 void *wrqu,
1487 char *extra)
1488
1489{
1490 struct orinoco_private *priv = netdev_priv(dev);
1491 int val = *((int *) extra);
1492 unsigned long flags;
1493
1494 if (orinoco_lock(priv, &flags) != 0)
1495 return -EBUSY;
1496
1497 priv->ibss_port = val ;
1498
1499 /* Actually update the mode we are using */
1500 set_port_type(priv);
1501
1502 orinoco_unlock(priv, &flags);
1503 return -EINPROGRESS; /* Call commit handler */
1504}
1505
1506static int orinoco_ioctl_getibssport(struct net_device *dev,
1507 struct iw_request_info *info,
1508 void *wrqu,
1509 char *extra)
1510{
1511 struct orinoco_private *priv = netdev_priv(dev);
1512 int *val = (int *) extra;
1513
1514 *val = priv->ibss_port;
1515 return 0;
1516}
1517
1518static int orinoco_ioctl_setport3(struct net_device *dev,
1519 struct iw_request_info *info,
1520 void *wrqu,
1521 char *extra)
1522{
1523 struct orinoco_private *priv = netdev_priv(dev);
1524 int val = *((int *) extra);
1525 int err = 0;
1526 unsigned long flags;
1527
1528 if (orinoco_lock(priv, &flags) != 0)
1529 return -EBUSY;
1530
1531 switch (val) {
1532 case 0: /* Try to do IEEE ad-hoc mode */
1533 if (!priv->has_ibss) {
1534 err = -EINVAL;
1535 break;
1536 }
1537 priv->prefer_port3 = 0;
1538
1539 break;
1540
1541 case 1: /* Try to do Lucent proprietary ad-hoc mode */
1542 if (!priv->has_port3) {
1543 err = -EINVAL;
1544 break;
1545 }
1546 priv->prefer_port3 = 1;
1547 break;
1548
1549 default:
1550 err = -EINVAL;
1551 }
1552
1553 if (!err) {
1554 /* Actually update the mode we are using */
1555 set_port_type(priv);
1556 err = -EINPROGRESS;
1557 }
1558
1559 orinoco_unlock(priv, &flags);
1560
1561 return err;
1562}
1563
1564static int orinoco_ioctl_getport3(struct net_device *dev,
1565 struct iw_request_info *info,
1566 void *wrqu,
1567 char *extra)
1568{
1569 struct orinoco_private *priv = netdev_priv(dev);
1570 int *val = (int *) extra;
1571
1572 *val = priv->prefer_port3;
1573 return 0;
1574}
1575
1576static int orinoco_ioctl_setpreamble(struct net_device *dev,
1577 struct iw_request_info *info,
1578 void *wrqu,
1579 char *extra)
1580{
1581 struct orinoco_private *priv = netdev_priv(dev);
1582 unsigned long flags;
1583 int val;
1584
1585 if (!priv->has_preamble)
1586 return -EOPNOTSUPP;
1587
1588 /* 802.11b has recently defined some short preamble.
1589 * Basically, the Phy header has been reduced in size.
1590 * This increase performance, especially at high rates
1591 * (the preamble is transmitted at 1Mb/s), unfortunately
1592 * this give compatibility troubles... - Jean II */
1593 val = *((int *) extra);
1594
1595 if (orinoco_lock(priv, &flags) != 0)
1596 return -EBUSY;
1597
1598 if (val)
1599 priv->preamble = 1;
1600 else
1601 priv->preamble = 0;
1602
1603 orinoco_unlock(priv, &flags);
1604
1605 return -EINPROGRESS; /* Call commit handler */
1606}
1607
1608static int orinoco_ioctl_getpreamble(struct net_device *dev,
1609 struct iw_request_info *info,
1610 void *wrqu,
1611 char *extra)
1612{
1613 struct orinoco_private *priv = netdev_priv(dev);
1614 int *val = (int *) extra;
1615
1616 if (!priv->has_preamble)
1617 return -EOPNOTSUPP;
1618
1619 *val = priv->preamble;
1620 return 0;
1621}
1622
1623/* ioctl interface to hermes_read_ltv()
1624 * To use with iwpriv, pass the RID as the token argument, e.g.
1625 * iwpriv get_rid [0xfc00]
1626 * At least Wireless Tools 25 is required to use iwpriv.
1627 * For Wireless Tools 25 and 26 append "dummy" are the end. */
1628static int orinoco_ioctl_getrid(struct net_device *dev,
1629 struct iw_request_info *info,
1630 struct iw_point *data,
1631 char *extra)
1632{
1633 struct orinoco_private *priv = netdev_priv(dev);
1634 hermes_t *hw = &priv->hw;
1635 int rid = data->flags;
1636 u16 length;
1637 int err;
1638 unsigned long flags;
1639
1640 /* It's a "get" function, but we don't want users to access the
1641 * WEP key and other raw firmware data */
1642 if (!capable(CAP_NET_ADMIN))
1643 return -EPERM;
1644
1645 if (rid < 0xfc00 || rid > 0xffff)
1646 return -EINVAL;
1647
1648 if (orinoco_lock(priv, &flags) != 0)
1649 return -EBUSY;
1650
1651 err = hermes_read_ltv(hw, USER_BAP, rid, MAX_RID_LEN, &length,
1652 extra);
1653 if (err)
1654 goto out;
1655
1656 data->length = min_t(u16, HERMES_RECLEN_TO_BYTES(length),
1657 MAX_RID_LEN);
1658
1659 out:
1660 orinoco_unlock(priv, &flags);
1661 return err;
1662}
1663
1664/* Trigger a scan (look for other cells in the vicinity) */
1665static int orinoco_ioctl_setscan(struct net_device *dev,
1666 struct iw_request_info *info,
1667 struct iw_point *srq,
1668 char *extra)
1669{
1670 struct orinoco_private *priv = netdev_priv(dev);
1671 hermes_t *hw = &priv->hw;
1672 struct iw_scan_req *si = (struct iw_scan_req *) extra;
1673 int err = 0;
1674 unsigned long flags;
1675
1676 /* Note : you may have realised that, as this is a SET operation,
1677 * this is privileged and therefore a normal user can't
1678 * perform scanning.
1679 * This is not an error, while the device perform scanning,
1680 * traffic doesn't flow, so it's a perfect DoS...
1681 * Jean II */
1682
1683 if (orinoco_lock(priv, &flags) != 0)
1684 return -EBUSY;
1685
1686 /* Scanning with port 0 disabled would fail */
1687 if (!netif_running(dev)) {
1688 err = -ENETDOWN;
1689 goto out;
1690 }
1691
1692 /* In monitor mode, the scan results are always empty.
1693 * Probe responses are passed to the driver as received
1694 * frames and could be processed in software. */
1695 if (priv->iw_mode == IW_MODE_MONITOR) {
1696 err = -EOPNOTSUPP;
1697 goto out;
1698 }
1699
1700 /* Note : because we don't lock out the irq handler, the way
1701 * we access scan variables in priv is critical.
1702 * o scan_inprogress : not touched by irq handler
1703 * o scan_mode : not touched by irq handler
1704 * Before modifying anything on those variables, please think hard !
1705 * Jean II */
1706
1707 /* Save flags */
1708 priv->scan_mode = srq->flags;
1709
1710 /* Always trigger scanning, even if it's in progress.
1711 * This way, if the info frame get lost, we will recover somewhat
1712 * gracefully - Jean II */
1713
1714 if (priv->has_hostscan) {
1715 switch (priv->firmware_type) {
1716 case FIRMWARE_TYPE_SYMBOL:
1717 err = hermes_write_wordrec(hw, USER_BAP,
1718 HERMES_RID_CNFHOSTSCAN_SYMBOL,
1719 HERMES_HOSTSCAN_SYMBOL_ONCE |
1720 HERMES_HOSTSCAN_SYMBOL_BCAST);
1721 break;
1722 case FIRMWARE_TYPE_INTERSIL: {
1723 __le16 req[3];
1724
1725 req[0] = cpu_to_le16(0x3fff); /* All channels */
1726 req[1] = cpu_to_le16(0x0001); /* rate 1 Mbps */
1727 req[2] = 0; /* Any ESSID */
1728 err = HERMES_WRITE_RECORD(hw, USER_BAP,
1729 HERMES_RID_CNFHOSTSCAN, &req);
1730 }
1731 break;
1732 case FIRMWARE_TYPE_AGERE:
1733 if (priv->scan_mode & IW_SCAN_THIS_ESSID) {
1734 struct hermes_idstring idbuf;
1735 size_t len = min(sizeof(idbuf.val),
1736 (size_t) si->essid_len);
1737 idbuf.len = cpu_to_le16(len);
1738 memcpy(idbuf.val, si->essid, len);
1739
1740 err = hermes_write_ltv(hw, USER_BAP,
1741 HERMES_RID_CNFSCANSSID_AGERE,
1742 HERMES_BYTES_TO_RECLEN(len + 2),
1743 &idbuf);
1744 } else
1745 err = hermes_write_wordrec(hw, USER_BAP,
1746 HERMES_RID_CNFSCANSSID_AGERE,
1747 0); /* Any ESSID */
1748 if (err)
1749 break;
1750
1751 if (priv->has_ext_scan) {
1752 /* Clear scan results at the start of
1753 * an extended scan */
1754 orinoco_clear_scan_results(priv,
1755 msecs_to_jiffies(15000));
1756
1757 /* TODO: Is this available on older firmware?
1758 * Can we use it to scan specific channels
1759 * for IW_SCAN_THIS_FREQ? */
1760 err = hermes_write_wordrec(hw, USER_BAP,
1761 HERMES_RID_CNFSCANCHANNELS2GHZ,
1762 0x7FFF);
1763 if (err)
1764 goto out;
1765
1766 err = hermes_inquire(hw,
1767 HERMES_INQ_CHANNELINFO);
1768 } else
1769 err = hermes_inquire(hw, HERMES_INQ_SCAN);
1770 break;
1771 }
1772 } else
1773 err = hermes_inquire(hw, HERMES_INQ_SCAN);
1774
1775 /* One more client */
1776 if (!err)
1777 priv->scan_inprogress = 1;
1778
1779 out:
1780 orinoco_unlock(priv, &flags);
1781 return err;
1782}
1783
1784#define MAX_CUSTOM_LEN 64
1785
1786/* Translate scan data returned from the card to a card independant
1787 * format that the Wireless Tools will understand - Jean II */
1788static inline char *orinoco_translate_scan(struct net_device *dev,
1789 struct iw_request_info *info,
1790 char *current_ev,
1791 char *end_buf,
1792 union hermes_scan_info *bss,
1793 unsigned long last_scanned)
1794{
1795 struct orinoco_private *priv = netdev_priv(dev);
1796 u16 capabilities;
1797 u16 channel;
1798 struct iw_event iwe; /* Temporary buffer */
1799 char custom[MAX_CUSTOM_LEN];
1800
1801 memset(&iwe, 0, sizeof(iwe));
1802
1803 /* First entry *MUST* be the AP MAC address */
1804 iwe.cmd = SIOCGIWAP;
1805 iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
1806 memcpy(iwe.u.ap_addr.sa_data, bss->a.bssid, ETH_ALEN);
1807 current_ev = iwe_stream_add_event(info, current_ev, end_buf,
1808 &iwe, IW_EV_ADDR_LEN);
1809
1810 /* Other entries will be displayed in the order we give them */
1811
1812 /* Add the ESSID */
1813 iwe.u.data.length = le16_to_cpu(bss->a.essid_len);
1814 if (iwe.u.data.length > 32)
1815 iwe.u.data.length = 32;
1816 iwe.cmd = SIOCGIWESSID;
1817 iwe.u.data.flags = 1;
1818 current_ev = iwe_stream_add_point(info, current_ev, end_buf,
1819 &iwe, bss->a.essid);
1820
1821 /* Add mode */
1822 iwe.cmd = SIOCGIWMODE;
1823 capabilities = le16_to_cpu(bss->a.capabilities);
1824 if (capabilities & (WLAN_CAPABILITY_ESS | WLAN_CAPABILITY_IBSS)) {
1825 if (capabilities & WLAN_CAPABILITY_ESS)
1826 iwe.u.mode = IW_MODE_MASTER;
1827 else
1828 iwe.u.mode = IW_MODE_ADHOC;
1829 current_ev = iwe_stream_add_event(info, current_ev, end_buf,
1830 &iwe, IW_EV_UINT_LEN);
1831 }
1832
1833 channel = bss->s.channel;
1834 if ((channel >= 1) && (channel <= NUM_CHANNELS)) {
1835 /* Add channel and frequency */
1836 iwe.cmd = SIOCGIWFREQ;
1837 iwe.u.freq.m = channel;
1838 iwe.u.freq.e = 0;
1839 current_ev = iwe_stream_add_event(info, current_ev, end_buf,
1840 &iwe, IW_EV_FREQ_LEN);
1841
1842 iwe.u.freq.m = ieee80211_dsss_chan_to_freq(channel) * 100000;
1843 iwe.u.freq.e = 1;
1844 current_ev = iwe_stream_add_event(info, current_ev, end_buf,
1845 &iwe, IW_EV_FREQ_LEN);
1846 }
1847
1848 /* Add quality statistics. level and noise in dB. No link quality */
1849 iwe.cmd = IWEVQUAL;
1850 iwe.u.qual.updated = IW_QUAL_DBM | IW_QUAL_QUAL_INVALID;
1851 iwe.u.qual.level = (__u8) le16_to_cpu(bss->a.level) - 0x95;
1852 iwe.u.qual.noise = (__u8) le16_to_cpu(bss->a.noise) - 0x95;
1853 /* Wireless tools prior to 27.pre22 will show link quality
1854 * anyway, so we provide a reasonable value. */
1855 if (iwe.u.qual.level > iwe.u.qual.noise)
1856 iwe.u.qual.qual = iwe.u.qual.level - iwe.u.qual.noise;
1857 else
1858 iwe.u.qual.qual = 0;
1859 current_ev = iwe_stream_add_event(info, current_ev, end_buf,
1860 &iwe, IW_EV_QUAL_LEN);
1861
1862 /* Add encryption capability */
1863 iwe.cmd = SIOCGIWENCODE;
1864 if (capabilities & WLAN_CAPABILITY_PRIVACY)
1865 iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
1866 else
1867 iwe.u.data.flags = IW_ENCODE_DISABLED;
1868 iwe.u.data.length = 0;
1869 current_ev = iwe_stream_add_point(info, current_ev, end_buf,
1870 &iwe, NULL);
1871
1872 /* Bit rate is not available in Lucent/Agere firmwares */
1873 if (priv->firmware_type != FIRMWARE_TYPE_AGERE) {
1874 char *current_val = current_ev + iwe_stream_lcp_len(info);
1875 int i;
1876 int step;
1877
1878 if (priv->firmware_type == FIRMWARE_TYPE_SYMBOL)
1879 step = 2;
1880 else
1881 step = 1;
1882
1883 iwe.cmd = SIOCGIWRATE;
1884 /* Those two flags are ignored... */
1885 iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
1886 /* Max 10 values */
1887 for (i = 0; i < 10; i += step) {
1888 /* NULL terminated */
1889 if (bss->p.rates[i] == 0x0)
1890 break;
1891 /* Bit rate given in 500 kb/s units (+ 0x80) */
1892 iwe.u.bitrate.value =
1893 ((bss->p.rates[i] & 0x7f) * 500000);
1894 current_val = iwe_stream_add_value(info, current_ev,
1895 current_val,
1896 end_buf, &iwe,
1897 IW_EV_PARAM_LEN);
1898 }
1899 /* Check if we added any event */
1900 if ((current_val - current_ev) > iwe_stream_lcp_len(info))
1901 current_ev = current_val;
1902 }
1903
1904 /* Beacon interval */
1905 iwe.cmd = IWEVCUSTOM;
1906 iwe.u.data.length = snprintf(custom, MAX_CUSTOM_LEN,
1907 "bcn_int=%d",
1908 le16_to_cpu(bss->a.beacon_interv));
1909 if (iwe.u.data.length)
1910 current_ev = iwe_stream_add_point(info, current_ev, end_buf,
1911 &iwe, custom);
1912
1913 /* Capabilites */
1914 iwe.cmd = IWEVCUSTOM;
1915 iwe.u.data.length = snprintf(custom, MAX_CUSTOM_LEN,
1916 "capab=0x%04x",
1917 capabilities);
1918 if (iwe.u.data.length)
1919 current_ev = iwe_stream_add_point(info, current_ev, end_buf,
1920 &iwe, custom);
1921
1922 /* Add EXTRA: Age to display seconds since last beacon/probe response
1923 * for given network. */
1924 iwe.cmd = IWEVCUSTOM;
1925 iwe.u.data.length = snprintf(custom, MAX_CUSTOM_LEN,
1926 " Last beacon: %dms ago",
1927 jiffies_to_msecs(jiffies - last_scanned));
1928 if (iwe.u.data.length)
1929 current_ev = iwe_stream_add_point(info, current_ev, end_buf,
1930 &iwe, custom);
1931
1932 return current_ev;
1933}
1934
1935static inline char *orinoco_translate_ext_scan(struct net_device *dev,
1936 struct iw_request_info *info,
1937 char *current_ev,
1938 char *end_buf,
1939 struct agere_ext_scan_info *bss,
1940 unsigned long last_scanned)
1941{
1942 u16 capabilities;
1943 u16 channel;
1944 struct iw_event iwe; /* Temporary buffer */
1945 char custom[MAX_CUSTOM_LEN];
1946 u8 *ie;
1947
1948 memset(&iwe, 0, sizeof(iwe));
1949
1950 /* First entry *MUST* be the AP MAC address */
1951 iwe.cmd = SIOCGIWAP;
1952 iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
1953 memcpy(iwe.u.ap_addr.sa_data, bss->bssid, ETH_ALEN);
1954 current_ev = iwe_stream_add_event(info, current_ev, end_buf,
1955 &iwe, IW_EV_ADDR_LEN);
1956
1957 /* Other entries will be displayed in the order we give them */
1958
1959 /* Add the ESSID */
1960 ie = bss->data;
1961 iwe.u.data.length = ie[1];
1962 if (iwe.u.data.length) {
1963 if (iwe.u.data.length > 32)
1964 iwe.u.data.length = 32;
1965 iwe.cmd = SIOCGIWESSID;
1966 iwe.u.data.flags = 1;
1967 current_ev = iwe_stream_add_point(info, current_ev, end_buf,
1968 &iwe, &ie[2]);
1969 }
1970
1971 /* Add mode */
1972 capabilities = le16_to_cpu(bss->capabilities);
1973 if (capabilities & (WLAN_CAPABILITY_ESS | WLAN_CAPABILITY_IBSS)) {
1974 iwe.cmd = SIOCGIWMODE;
1975 if (capabilities & WLAN_CAPABILITY_ESS)
1976 iwe.u.mode = IW_MODE_MASTER;
1977 else
1978 iwe.u.mode = IW_MODE_ADHOC;
1979 current_ev = iwe_stream_add_event(info, current_ev, end_buf,
1980 &iwe, IW_EV_UINT_LEN);
1981 }
1982
1983 ie = orinoco_get_ie(bss->data, sizeof(bss->data), WLAN_EID_DS_PARAMS);
1984 channel = ie ? ie[2] : 0;
1985 if ((channel >= 1) && (channel <= NUM_CHANNELS)) {
1986 /* Add channel and frequency */
1987 iwe.cmd = SIOCGIWFREQ;
1988 iwe.u.freq.m = channel;
1989 iwe.u.freq.e = 0;
1990 current_ev = iwe_stream_add_event(info, current_ev, end_buf,
1991 &iwe, IW_EV_FREQ_LEN);
1992
1993 iwe.u.freq.m = ieee80211_dsss_chan_to_freq(channel) * 100000;
1994 iwe.u.freq.e = 1;
1995 current_ev = iwe_stream_add_event(info, current_ev, end_buf,
1996 &iwe, IW_EV_FREQ_LEN);
1997 }
1998
1999 /* Add quality statistics. level and noise in dB. No link quality */
2000 iwe.cmd = IWEVQUAL;
2001 iwe.u.qual.updated = IW_QUAL_DBM | IW_QUAL_QUAL_INVALID;
2002 iwe.u.qual.level = bss->level - 0x95;
2003 iwe.u.qual.noise = bss->noise - 0x95;
2004 /* Wireless tools prior to 27.pre22 will show link quality
2005 * anyway, so we provide a reasonable value. */
2006 if (iwe.u.qual.level > iwe.u.qual.noise)
2007 iwe.u.qual.qual = iwe.u.qual.level - iwe.u.qual.noise;
2008 else
2009 iwe.u.qual.qual = 0;
2010 current_ev = iwe_stream_add_event(info, current_ev, end_buf,
2011 &iwe, IW_EV_QUAL_LEN);
2012
2013 /* Add encryption capability */
2014 iwe.cmd = SIOCGIWENCODE;
2015 if (capabilities & WLAN_CAPABILITY_PRIVACY)
2016 iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
2017 else
2018 iwe.u.data.flags = IW_ENCODE_DISABLED;
2019 iwe.u.data.length = 0;
2020 current_ev = iwe_stream_add_point(info, current_ev, end_buf,
2021 &iwe, NULL);
2022
2023 /* WPA IE */
2024 ie = orinoco_get_wpa_ie(bss->data, sizeof(bss->data));
2025 if (ie) {
2026 iwe.cmd = IWEVGENIE;
2027 iwe.u.data.length = ie[1] + 2;
2028 current_ev = iwe_stream_add_point(info, current_ev, end_buf,
2029 &iwe, ie);
2030 }
2031
2032 /* RSN IE */
2033 ie = orinoco_get_ie(bss->data, sizeof(bss->data), WLAN_EID_RSN);
2034 if (ie) {
2035 iwe.cmd = IWEVGENIE;
2036 iwe.u.data.length = ie[1] + 2;
2037 current_ev = iwe_stream_add_point(info, current_ev, end_buf,
2038 &iwe, ie);
2039 }
2040
2041 ie = orinoco_get_ie(bss->data, sizeof(bss->data), WLAN_EID_SUPP_RATES);
2042 if (ie) {
2043 char *p = current_ev + iwe_stream_lcp_len(info);
2044 int i;
2045
2046 iwe.cmd = SIOCGIWRATE;
2047 /* Those two flags are ignored... */
2048 iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
2049
2050 for (i = 2; i < (ie[1] + 2); i++) {
2051 iwe.u.bitrate.value = ((ie[i] & 0x7F) * 500000);
2052 p = iwe_stream_add_value(info, current_ev, p, end_buf,
2053 &iwe, IW_EV_PARAM_LEN);
2054 }
2055 /* Check if we added any event */
2056 if (p > (current_ev + iwe_stream_lcp_len(info)))
2057 current_ev = p;
2058 }
2059
2060 /* Timestamp */
2061 iwe.cmd = IWEVCUSTOM;
2062 iwe.u.data.length =
2063 snprintf(custom, MAX_CUSTOM_LEN, "tsf=%016llx",
2064 (unsigned long long) le64_to_cpu(bss->timestamp));
2065 if (iwe.u.data.length)
2066 current_ev = iwe_stream_add_point(info, current_ev, end_buf,
2067 &iwe, custom);
2068
2069 /* Beacon interval */
2070 iwe.cmd = IWEVCUSTOM;
2071 iwe.u.data.length = snprintf(custom, MAX_CUSTOM_LEN,
2072 "bcn_int=%d",
2073 le16_to_cpu(bss->beacon_interval));
2074 if (iwe.u.data.length)
2075 current_ev = iwe_stream_add_point(info, current_ev, end_buf,
2076 &iwe, custom);
2077
2078 /* Capabilites */
2079 iwe.cmd = IWEVCUSTOM;
2080 iwe.u.data.length = snprintf(custom, MAX_CUSTOM_LEN,
2081 "capab=0x%04x",
2082 capabilities);
2083 if (iwe.u.data.length)
2084 current_ev = iwe_stream_add_point(info, current_ev, end_buf,
2085 &iwe, custom);
2086
2087 /* Add EXTRA: Age to display seconds since last beacon/probe response
2088 * for given network. */
2089 iwe.cmd = IWEVCUSTOM;
2090 iwe.u.data.length = snprintf(custom, MAX_CUSTOM_LEN,
2091 " Last beacon: %dms ago",
2092 jiffies_to_msecs(jiffies - last_scanned));
2093 if (iwe.u.data.length)
2094 current_ev = iwe_stream_add_point(info, current_ev, end_buf,
2095 &iwe, custom);
2096
2097 return current_ev;
2098}
2099
2100/* Return results of a scan */
2101static int orinoco_ioctl_getscan(struct net_device *dev,
2102 struct iw_request_info *info,
2103 struct iw_point *srq,
2104 char *extra)
2105{
2106 struct orinoco_private *priv = netdev_priv(dev);
2107 int err = 0;
2108 unsigned long flags;
2109 char *current_ev = extra;
2110
2111 if (orinoco_lock(priv, &flags) != 0)
2112 return -EBUSY;
2113
2114 if (priv->scan_inprogress) {
2115 /* Important note : we don't want to block the caller
2116 * until results are ready for various reasons.
2117 * First, managing wait queues is complex and racy.
2118 * Second, we grab some rtnetlink lock before comming
2119 * here (in dev_ioctl()).
2120 * Third, we generate an Wireless Event, so the
2121 * caller can wait itself on that - Jean II */
2122 err = -EAGAIN;
2123 goto out;
2124 }
2125
2126 if (priv->has_ext_scan) {
2127 struct xbss_element *bss;
2128
2129 list_for_each_entry(bss, &priv->bss_list, list) {
2130 /* Translate this entry to WE format */
2131 current_ev =
2132 orinoco_translate_ext_scan(dev, info,
2133 current_ev,
2134 extra + srq->length,
2135 &bss->bss,
2136 bss->last_scanned);
2137
2138 /* Check if there is space for one more entry */
2139 if ((extra + srq->length - current_ev)
2140 <= IW_EV_ADDR_LEN) {
2141 /* Ask user space to try again with a
2142 * bigger buffer */
2143 err = -E2BIG;
2144 goto out;
2145 }
2146 }
2147
2148 } else {
2149 struct bss_element *bss;
2150
2151 list_for_each_entry(bss, &priv->bss_list, list) {
2152 /* Translate this entry to WE format */
2153 current_ev = orinoco_translate_scan(dev, info,
2154 current_ev,
2155 extra + srq->length,
2156 &bss->bss,
2157 bss->last_scanned);
2158
2159 /* Check if there is space for one more entry */
2160 if ((extra + srq->length - current_ev)
2161 <= IW_EV_ADDR_LEN) {
2162 /* Ask user space to try again with a
2163 * bigger buffer */
2164 err = -E2BIG;
2165 goto out;
2166 }
2167 }
2168 }
2169
2170 srq->length = (current_ev - extra);
2171 srq->flags = (__u16) priv->scan_mode;
2172
2173out:
2174 orinoco_unlock(priv, &flags);
2175 return err;
2176}
2177
2178/* Commit handler, called after set operations */
2179static int orinoco_ioctl_commit(struct net_device *dev,
2180 struct iw_request_info *info,
2181 void *wrqu,
2182 char *extra)
2183{
2184 struct orinoco_private *priv = netdev_priv(dev);
2185 struct hermes *hw = &priv->hw;
2186 unsigned long flags;
2187 int err = 0;
2188
2189 if (!priv->open)
2190 return 0;
2191
2192 if (priv->broken_disableport) {
2193 orinoco_reset(&priv->reset_work);
2194 return 0;
2195 }
2196
2197 if (orinoco_lock(priv, &flags) != 0)
2198 return err;
2199
2200 err = hermes_disable_port(hw, 0);
2201 if (err) {
2202 printk(KERN_WARNING "%s: Unable to disable port "
2203 "while reconfiguring card\n", dev->name);
2204 priv->broken_disableport = 1;
2205 goto out;
2206 }
2207
2208 err = __orinoco_program_rids(dev);
2209 if (err) {
2210 printk(KERN_WARNING "%s: Unable to reconfigure card\n",
2211 dev->name);
2212 goto out;
2213 }
2214
2215 err = hermes_enable_port(hw, 0);
2216 if (err) {
2217 printk(KERN_WARNING "%s: Unable to enable port while reconfiguring card\n",
2218 dev->name);
2219 goto out;
2220 }
2221
2222 out:
2223 if (err) {
2224 printk(KERN_WARNING "%s: Resetting instead...\n", dev->name);
2225 schedule_work(&priv->reset_work);
2226 err = 0;
2227 }
2228
2229 orinoco_unlock(priv, &flags);
2230 return err;
2231}
2232
2233static const struct iw_priv_args orinoco_privtab[] = {
2234 { SIOCIWFIRSTPRIV + 0x0, 0, 0, "force_reset" },
2235 { SIOCIWFIRSTPRIV + 0x1, 0, 0, "card_reset" },
2236 { SIOCIWFIRSTPRIV + 0x2, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
2237 0, "set_port3" },
2238 { SIOCIWFIRSTPRIV + 0x3, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
2239 "get_port3" },
2240 { SIOCIWFIRSTPRIV + 0x4, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
2241 0, "set_preamble" },
2242 { SIOCIWFIRSTPRIV + 0x5, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
2243 "get_preamble" },
2244 { SIOCIWFIRSTPRIV + 0x6, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
2245 0, "set_ibssport" },
2246 { SIOCIWFIRSTPRIV + 0x7, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
2247 "get_ibssport" },
2248 { SIOCIWFIRSTPRIV + 0x9, 0, IW_PRIV_TYPE_BYTE | MAX_RID_LEN,
2249 "get_rid" },
2250};
2251
2252
2253/*
2254 * Structures to export the Wireless Handlers
2255 */
2256
2257#define STD_IW_HANDLER(id, func) \
2258 [IW_IOCTL_IDX(id)] = (iw_handler) func
2259static const iw_handler orinoco_handler[] = {
2260 STD_IW_HANDLER(SIOCSIWCOMMIT, orinoco_ioctl_commit),
2261 STD_IW_HANDLER(SIOCGIWNAME, orinoco_ioctl_getname),
2262 STD_IW_HANDLER(SIOCSIWFREQ, orinoco_ioctl_setfreq),
2263 STD_IW_HANDLER(SIOCGIWFREQ, orinoco_ioctl_getfreq),
2264 STD_IW_HANDLER(SIOCSIWMODE, orinoco_ioctl_setmode),
2265 STD_IW_HANDLER(SIOCGIWMODE, orinoco_ioctl_getmode),
2266 STD_IW_HANDLER(SIOCSIWSENS, orinoco_ioctl_setsens),
2267 STD_IW_HANDLER(SIOCGIWSENS, orinoco_ioctl_getsens),
2268 STD_IW_HANDLER(SIOCGIWRANGE, orinoco_ioctl_getiwrange),
2269 STD_IW_HANDLER(SIOCSIWSPY, iw_handler_set_spy),
2270 STD_IW_HANDLER(SIOCGIWSPY, iw_handler_get_spy),
2271 STD_IW_HANDLER(SIOCSIWTHRSPY, iw_handler_set_thrspy),
2272 STD_IW_HANDLER(SIOCGIWTHRSPY, iw_handler_get_thrspy),
2273 STD_IW_HANDLER(SIOCSIWAP, orinoco_ioctl_setwap),
2274 STD_IW_HANDLER(SIOCGIWAP, orinoco_ioctl_getwap),
2275 STD_IW_HANDLER(SIOCSIWSCAN, orinoco_ioctl_setscan),
2276 STD_IW_HANDLER(SIOCGIWSCAN, orinoco_ioctl_getscan),
2277 STD_IW_HANDLER(SIOCSIWESSID, orinoco_ioctl_setessid),
2278 STD_IW_HANDLER(SIOCGIWESSID, orinoco_ioctl_getessid),
2279 STD_IW_HANDLER(SIOCSIWNICKN, orinoco_ioctl_setnick),
2280 STD_IW_HANDLER(SIOCGIWNICKN, orinoco_ioctl_getnick),
2281 STD_IW_HANDLER(SIOCSIWRATE, orinoco_ioctl_setrate),
2282 STD_IW_HANDLER(SIOCGIWRATE, orinoco_ioctl_getrate),
2283 STD_IW_HANDLER(SIOCSIWRTS, orinoco_ioctl_setrts),
2284 STD_IW_HANDLER(SIOCGIWRTS, orinoco_ioctl_getrts),
2285 STD_IW_HANDLER(SIOCSIWFRAG, orinoco_ioctl_setfrag),
2286 STD_IW_HANDLER(SIOCGIWFRAG, orinoco_ioctl_getfrag),
2287 STD_IW_HANDLER(SIOCGIWRETRY, orinoco_ioctl_getretry),
2288 STD_IW_HANDLER(SIOCSIWENCODE, orinoco_ioctl_setiwencode),
2289 STD_IW_HANDLER(SIOCGIWENCODE, orinoco_ioctl_getiwencode),
2290 STD_IW_HANDLER(SIOCSIWPOWER, orinoco_ioctl_setpower),
2291 STD_IW_HANDLER(SIOCGIWPOWER, orinoco_ioctl_getpower),
2292 STD_IW_HANDLER(SIOCSIWGENIE, orinoco_ioctl_set_genie),
2293 STD_IW_HANDLER(SIOCGIWGENIE, orinoco_ioctl_get_genie),
2294 STD_IW_HANDLER(SIOCSIWMLME, orinoco_ioctl_set_mlme),
2295 STD_IW_HANDLER(SIOCSIWAUTH, orinoco_ioctl_set_auth),
2296 STD_IW_HANDLER(SIOCGIWAUTH, orinoco_ioctl_get_auth),
2297 STD_IW_HANDLER(SIOCSIWENCODEEXT, orinoco_ioctl_set_encodeext),
2298 STD_IW_HANDLER(SIOCGIWENCODEEXT, orinoco_ioctl_get_encodeext),
2299};
2300
2301
2302/*
2303 Added typecasting since we no longer use iwreq_data -- Moustafa
2304 */
2305static const iw_handler orinoco_private_handler[] = {
2306 [0] = (iw_handler) orinoco_ioctl_reset,
2307 [1] = (iw_handler) orinoco_ioctl_reset,
2308 [2] = (iw_handler) orinoco_ioctl_setport3,
2309 [3] = (iw_handler) orinoco_ioctl_getport3,
2310 [4] = (iw_handler) orinoco_ioctl_setpreamble,
2311 [5] = (iw_handler) orinoco_ioctl_getpreamble,
2312 [6] = (iw_handler) orinoco_ioctl_setibssport,
2313 [7] = (iw_handler) orinoco_ioctl_getibssport,
2314 [9] = (iw_handler) orinoco_ioctl_getrid,
2315};
2316
2317const struct iw_handler_def orinoco_handler_def = {
2318 .num_standard = ARRAY_SIZE(orinoco_handler),
2319 .num_private = ARRAY_SIZE(orinoco_private_handler),
2320 .num_private_args = ARRAY_SIZE(orinoco_privtab),
2321 .standard = orinoco_handler,
2322 .private = orinoco_private_handler,
2323 .private_args = orinoco_privtab,
2324 .get_wireless_stats = orinoco_get_wireless_stats,
2325};
diff --git a/drivers/net/wireless/orinoco/wext.h b/drivers/net/wireless/orinoco/wext.h
new file mode 100644
index 000000000000..1479f4e26dde
--- /dev/null
+++ b/drivers/net/wireless/orinoco/wext.h
@@ -0,0 +1,13 @@
1/* Wireless extensions support.
2 *
3 * See copyright notice in main.c
4 */
5#ifndef _ORINOCO_WEXT_H_
6#define _ORINOCO_WEXT_H_
7
8#include <net/iw_handler.h>
9
10/* Structure defining all our WEXT handlers */
11extern const struct iw_handler_def orinoco_handler_def;
12
13#endif /* _ORINOCO_WEXT_H_ */
diff --git a/drivers/net/wireless/zd1211rw/zd_def.h b/drivers/net/wireless/zd1211rw/zd_def.h
index 5200db405610..6ac597ffd3b9 100644
--- a/drivers/net/wireless/zd1211rw/zd_def.h
+++ b/drivers/net/wireless/zd1211rw/zd_def.h
@@ -33,8 +33,13 @@ typedef u16 __nocast zd_addr_t;
33#ifdef DEBUG 33#ifdef DEBUG
34# define dev_dbg_f(dev, fmt, args...) \ 34# define dev_dbg_f(dev, fmt, args...) \
35 dev_printk_f(KERN_DEBUG, dev, fmt, ## args) 35 dev_printk_f(KERN_DEBUG, dev, fmt, ## args)
36# define dev_dbg_f_limit(dev, fmt, args...) do { \
37 if (net_ratelimit()) \
38 dev_printk_f(KERN_DEBUG, dev, fmt, ## args); \
39} while (0)
36#else 40#else
37# define dev_dbg_f(dev, fmt, args...) do { (void)(dev); } while (0) 41# define dev_dbg_f(dev, fmt, args...) do { (void)(dev); } while (0)
42# define dev_dbg_f_limit(dev, fmt, args...) do { (void)(dev); } while (0)
38#endif /* DEBUG */ 43#endif /* DEBUG */
39 44
40#ifdef DEBUG 45#ifdef DEBUG
diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c
index 651807dfb508..7579af27edbd 100644
--- a/drivers/net/wireless/zd1211rw/zd_mac.c
+++ b/drivers/net/wireless/zd1211rw/zd_mac.c
@@ -768,13 +768,23 @@ static int zd_op_config_interface(struct ieee80211_hw *hw,
768 if (!beacon) 768 if (!beacon)
769 return -ENOMEM; 769 return -ENOMEM;
770 r = zd_mac_config_beacon(hw, beacon); 770 r = zd_mac_config_beacon(hw, beacon);
771 kfree_skb(beacon);
772
771 if (r < 0) 773 if (r < 0)
772 return r; 774 return r;
773 r = zd_set_beacon_interval(&mac->chip, BCN_MODE_IBSS | 775 }
774 hw->conf.beacon_int); 776
777 if (conf->changed & IEEE80211_IFCC_BEACON_ENABLED) {
778 u32 interval;
779
780 if (conf->enable_beacon)
781 interval = BCN_MODE_IBSS | hw->conf.beacon_int;
782 else
783 interval = 0;
784
785 r = zd_set_beacon_interval(&mac->chip, interval);
775 if (r < 0) 786 if (r < 0)
776 return r; 787 return r;
777 kfree_skb(beacon);
778 } 788 }
779 } else 789 } else
780 associated = is_valid_ether_addr(conf->bssid); 790 associated = is_valid_ether_addr(conf->bssid);
@@ -793,10 +803,9 @@ static void zd_process_intr(struct work_struct *work)
793 struct zd_mac *mac = container_of(work, struct zd_mac, process_intr); 803 struct zd_mac *mac = container_of(work, struct zd_mac, process_intr);
794 804
795 int_status = le16_to_cpu(*(__le16 *)(mac->intr_buffer+4)); 805 int_status = le16_to_cpu(*(__le16 *)(mac->intr_buffer+4));
796 if (int_status & INT_CFG_NEXT_BCN) { 806 if (int_status & INT_CFG_NEXT_BCN)
797 if (net_ratelimit()) 807 dev_dbg_f_limit(zd_mac_dev(mac), "INT_CFG_NEXT_BCN\n");
798 dev_dbg_f(zd_mac_dev(mac), "INT_CFG_NEXT_BCN\n"); 808 else
799 } else
800 dev_dbg_f(zd_mac_dev(mac), "Unsupported interrupt\n"); 809 dev_dbg_f(zd_mac_dev(mac), "Unsupported interrupt\n");
801 810
802 zd_chip_enable_hwint(&mac->chip); 811 zd_chip_enable_hwint(&mac->chip);