diff options
author | Nick Kossifidis <mick@madwifi.org> | 2008-04-16 11:49:02 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2008-04-16 16:00:03 -0400 |
commit | 194828a292db3cf421ae7f82232f2fc655fbbc3c (patch) | |
tree | 1525b49d4db5b979d8cc4058207b855a4386fc28 /drivers/net/wireless/ath5k/hw.c | |
parent | 136bfc798fe5378c7c1b5f5294abcfd1428438b3 (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.c | 138 |
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 | */ | ||
125 | static 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 | */ |
125 | struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc, u8 mac_version) | 182 | struct 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 | */ |
2853 | void ath5k_hw_update_mib_counters(struct ath5k_hw *ah, | 2957 | void 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 | ||