aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath5k/hw.c
diff options
context:
space:
mode:
authorNick Kossifidis <mick@madwifi.org>2008-04-16 11:49:02 -0400
committerJohn W. Linville <linville@tuxdriver.com>2008-04-16 16:00:03 -0400
commit194828a292db3cf421ae7f82232f2fc655fbbc3c (patch)
tree1525b49d4db5b979d8cc4058207b855a4386fc28 /drivers/net/wireless/ath5k/hw.c
parent136bfc798fe5378c7c1b5f5294abcfd1428438b3 (diff)
ath5k: Misc fixes/cleanups
*Handle MIB interrupts and pass low level stats to mac80211 *Add Power On Self Test function *Update to match recent dumps *Let RF2425 attach so we can further test it *Remove unused files regdom.c and regdom.h base.c Changes-licensed-under: 3-clause-BSD rest Changes-licensed-under: ISC Signed-off-by: Nick Kossifidis <mickflemm@gmail.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/ath5k/hw.c')
-rw-r--r--drivers/net/wireless/ath5k/hw.c138
1 files changed, 127 insertions, 11 deletions
diff --git a/drivers/net/wireless/ath5k/hw.c b/drivers/net/wireless/ath5k/hw.c
index 9e16bc09f1fd..87e782291a01 100644
--- a/drivers/net/wireless/ath5k/hw.c
+++ b/drivers/net/wireless/ath5k/hw.c
@@ -120,11 +120,69 @@ int ath5k_hw_register_timeout(struct ath5k_hw *ah, u32 reg, u32 flag, u32 val,
120\***************************************/ 120\***************************************/
121 121
122/* 122/*
123 * Power On Self Test helper function
124 */
125static int ath5k_hw_post(struct ath5k_hw *ah)
126{
127
128 int i, c;
129 u16 cur_reg;
130 u16 regs[2] = {AR5K_STA_ID0, AR5K_PHY(8)};
131 u32 var_pattern;
132 u32 static_pattern[4] = {
133 0x55555555, 0xaaaaaaaa,
134 0x66666666, 0x99999999
135 };
136 u32 init_val;
137 u32 cur_val;
138
139 for (c = 0; c < 2; c++) {
140
141 cur_reg = regs[c];
142 init_val = ath5k_hw_reg_read(ah, cur_reg);
143
144 for (i = 0; i < 256; i++) {
145 var_pattern = i << 16 | i;
146 ath5k_hw_reg_write(ah, var_pattern, cur_reg);
147 cur_val = ath5k_hw_reg_read(ah, cur_reg);
148
149 if (cur_val != var_pattern) {
150 ATH5K_ERR(ah->ah_sc, "POST Failed !!!\n");
151 return -EAGAIN;
152 }
153
154 /* Found on ndiswrapper dumps */
155 var_pattern = 0x0039080f;
156 ath5k_hw_reg_write(ah, var_pattern, cur_reg);
157 }
158
159 for (i = 0; i < 4; i++) {
160 var_pattern = static_pattern[i];
161 ath5k_hw_reg_write(ah, var_pattern, cur_reg);
162 cur_val = ath5k_hw_reg_read(ah, cur_reg);
163
164 if (cur_val != var_pattern) {
165 ATH5K_ERR(ah->ah_sc, "POST Failed !!!\n");
166 return -EAGAIN;
167 }
168
169 /* Found on ndiswrapper dumps */
170 var_pattern = 0x003b080f;
171 ath5k_hw_reg_write(ah, var_pattern, cur_reg);
172 }
173 }
174
175 return 0;
176
177}
178
179/*
123 * Check if the device is supported and initialize the needed structs 180 * Check if the device is supported and initialize the needed structs
124 */ 181 */
125struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc, u8 mac_version) 182struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc, u8 mac_version)
126{ 183{
127 struct ath5k_hw *ah; 184 struct ath5k_hw *ah;
185 struct pci_dev *pdev = sc->pdev;
128 u8 mac[ETH_ALEN]; 186 u8 mac[ETH_ALEN];
129 int ret; 187 int ret;
130 u32 srev; 188 u32 srev;
@@ -204,10 +262,13 @@ struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc, u8 mac_version)
204 CHANNEL_2GHZ); 262 CHANNEL_2GHZ);
205 263
206 /* Return on unsuported chips (unsupported eeprom etc) */ 264 /* Return on unsuported chips (unsupported eeprom etc) */
207 if (srev >= AR5K_SREV_VER_AR5416) { 265 if ((srev >= AR5K_SREV_VER_AR5416) &&
266 (srev < AR5K_SREV_VER_AR2425)) {
208 ATH5K_ERR(sc, "Device not yet supported.\n"); 267 ATH5K_ERR(sc, "Device not yet supported.\n");
209 ret = -ENODEV; 268 ret = -ENODEV;
210 goto err_free; 269 goto err_free;
270 } else if (srev == AR5K_SREV_VER_AR2425) {
271 ATH5K_WARN(sc, "Support for RF2425 is under development.\n");
211 } 272 }
212 273
213 /* Identify single chip solutions */ 274 /* Identify single chip solutions */
@@ -251,8 +312,13 @@ struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc, u8 mac_version)
251 ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5424; 312 ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5424;
252 else 313 else
253 ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5112A; 314 ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5112A;
254 315 /*
255 } else if (ah->ah_radio_5ghz_revision < AR5K_SREV_RAD_5133) { 316 * Register returns 0x4 for radio revision
317 * so ath5k_hw_radio_revision doesn't parse the value
318 * correctly. For now we are based on mac's srev to
319 * identify RF2425 radio.
320 */
321 } else if (srev == AR5K_SREV_VER_AR2425) {
256 ah->ah_radio = AR5K_RF2425; 322 ah->ah_radio = AR5K_RF2425;
257 ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5112; 323 ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5112;
258 } 324 }
@@ -260,6 +326,44 @@ struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc, u8 mac_version)
260 ah->ah_phy = AR5K_PHY(0); 326 ah->ah_phy = AR5K_PHY(0);
261 327
262 /* 328 /*
329 * Identify AR5212-based PCI-E cards
330 * And write some initial settings.
331 *
332 * (doing a "strings" on ndis driver
333 * -ar5211.sys- reveals the following
334 * pci-e related functions:
335 *
336 * pcieClockReq
337 * pcieRxErrNotify
338 * pcieL1SKPEnable
339 * pcieAspm
340 * pcieDisableAspmOnRfWake
341 * pciePowerSaveEnable
342 *
343 * I guess these point to ClockReq but
344 * i'm not sure.)
345 */
346 if ((ah->ah_version == AR5K_AR5212) && (pdev->is_pcie)) {
347 ath5k_hw_reg_write(ah, 0x9248fc00, 0x4080);
348 ath5k_hw_reg_write(ah, 0x24924924, 0x4080);
349 ath5k_hw_reg_write(ah, 0x28000039, 0x4080);
350 ath5k_hw_reg_write(ah, 0x53160824, 0x4080);
351 ath5k_hw_reg_write(ah, 0xe5980579, 0x4080);
352 ath5k_hw_reg_write(ah, 0x001defff, 0x4080);
353 ath5k_hw_reg_write(ah, 0x1aaabe40, 0x4080);
354 ath5k_hw_reg_write(ah, 0xbe105554, 0x4080);
355 ath5k_hw_reg_write(ah, 0x000e3007, 0x4080);
356 ath5k_hw_reg_write(ah, 0x00000000, 0x4084);
357 }
358
359 /*
360 * POST
361 */
362 ret = ath5k_hw_post(ah);
363 if (ret)
364 goto err_free;
365
366 /*
263 * Get card capabilities, values, ... 367 * Get card capabilities, values, ...
264 */ 368 */
265 369
@@ -2851,15 +2955,19 @@ int ath5k_hw_beaconq_finish(struct ath5k_hw *ah, unsigned long phys_addr)
2851 * Update mib counters (statistics) 2955 * Update mib counters (statistics)
2852 */ 2956 */
2853void ath5k_hw_update_mib_counters(struct ath5k_hw *ah, 2957void ath5k_hw_update_mib_counters(struct ath5k_hw *ah,
2854 struct ath5k_mib_stats *statistics) 2958 struct ieee80211_low_level_stats *stats)
2855{ 2959{
2856 ATH5K_TRACE(ah->ah_sc); 2960 ATH5K_TRACE(ah->ah_sc);
2961
2857 /* Read-And-Clear */ 2962 /* Read-And-Clear */
2858 statistics->ackrcv_bad += ath5k_hw_reg_read(ah, AR5K_ACK_FAIL); 2963 stats->dot11ACKFailureCount += ath5k_hw_reg_read(ah, AR5K_ACK_FAIL);
2859 statistics->rts_bad += ath5k_hw_reg_read(ah, AR5K_RTS_FAIL); 2964 stats->dot11RTSFailureCount += ath5k_hw_reg_read(ah, AR5K_RTS_FAIL);
2860 statistics->rts_good += ath5k_hw_reg_read(ah, AR5K_RTS_OK); 2965 stats->dot11RTSSuccessCount += ath5k_hw_reg_read(ah, AR5K_RTS_OK);
2861 statistics->fcs_bad += ath5k_hw_reg_read(ah, AR5K_FCS_FAIL); 2966 stats->dot11FCSErrorCount += ath5k_hw_reg_read(ah, AR5K_FCS_FAIL);
2862 statistics->beacons += ath5k_hw_reg_read(ah, AR5K_BEACON_CNT); 2967
2968 /* XXX: Should we use this to track beacon count ?
2969 * -we read it anyway to clear the register */
2970 ath5k_hw_reg_read(ah, AR5K_BEACON_CNT);
2863 2971
2864 /* Reset profile count registers on 5212*/ 2972 /* Reset profile count registers on 5212*/
2865 if (ah->ah_version == AR5K_AR5212) { 2973 if (ah->ah_version == AR5K_AR5212) {
@@ -2960,8 +3068,16 @@ int ath5k_hw_reset_key(struct ath5k_hw *ah, u16 entry)
2960 for (i = 0; i < AR5K_KEYCACHE_SIZE; i++) 3068 for (i = 0; i < AR5K_KEYCACHE_SIZE; i++)
2961 ath5k_hw_reg_write(ah, 0, AR5K_KEYTABLE_OFF(entry, i)); 3069 ath5k_hw_reg_write(ah, 0, AR5K_KEYTABLE_OFF(entry, i));
2962 3070
2963 /* Set NULL encryption on non-5210*/ 3071 /*
2964 if (ah->ah_version != AR5K_AR5210) 3072 * Set NULL encryption on AR5212+
3073 *
3074 * Note: AR5K_KEYTABLE_TYPE -> AR5K_KEYTABLE_OFF(entry, 5)
3075 * AR5K_KEYTABLE_TYPE_NULL -> 0x00000007
3076 *
3077 * Note2: Windows driver (ndiswrapper) sets this to
3078 * 0x00000714 instead of 0x00000007
3079 */
3080 if (ah->ah_version > AR5K_AR5211)
2965 ath5k_hw_reg_write(ah, AR5K_KEYTABLE_TYPE_NULL, 3081 ath5k_hw_reg_write(ah, AR5K_KEYTABLE_TYPE_NULL,
2966 AR5K_KEYTABLE_TYPE(entry)); 3082 AR5K_KEYTABLE_TYPE(entry));
2967 3083