diff options
author | Nick Kossifidis <mick@madwifi.org> | 2008-09-28 18:18:16 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2008-09-30 14:07:26 -0400 |
commit | ee81c5544bbf49ea5b301784a605d865947ac1b0 (patch) | |
tree | 90af7f2f1d96584dad9c5946ca627406377cb00b /drivers/net | |
parent | 1d280ddcfd6666a45915ccc3a76dee033a6b917b (diff) |
ath5k: Use new srevs to properly attach radio chips
* Use new SREV values and PHY srevs to identify radio type durring attach
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')
-rw-r--r-- | drivers/net/wireless/ath5k/attach.c | 182 |
1 files changed, 113 insertions, 69 deletions
diff --git a/drivers/net/wireless/ath5k/attach.c b/drivers/net/wireless/ath5k/attach.c index d92b4a12567c..51d569883cdd 100644 --- a/drivers/net/wireless/ath5k/attach.c +++ b/drivers/net/wireless/ath5k/attach.c | |||
@@ -137,7 +137,7 @@ struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc, u8 mac_version) | |||
137 | ah->ah_ant_diversity = AR5K_TUNE_ANT_DIVERSITY; | 137 | ah->ah_ant_diversity = AR5K_TUNE_ANT_DIVERSITY; |
138 | 138 | ||
139 | /* | 139 | /* |
140 | * Set the mac revision based on the pci id | 140 | * Set the mac version based on the pci id |
141 | */ | 141 | */ |
142 | ah->ah_version = mac_version; | 142 | ah->ah_version = mac_version; |
143 | 143 | ||
@@ -160,87 +160,132 @@ struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc, u8 mac_version) | |||
160 | 0xffffffff; | 160 | 0xffffffff; |
161 | ah->ah_radio_5ghz_revision = ath5k_hw_radio_revision(ah, | 161 | ah->ah_radio_5ghz_revision = ath5k_hw_radio_revision(ah, |
162 | CHANNEL_5GHZ); | 162 | CHANNEL_5GHZ); |
163 | ah->ah_phy = AR5K_PHY(0); | ||
163 | 164 | ||
164 | if (ah->ah_version == AR5K_AR5210) | 165 | /* Try to identify radio chip based on it's srev */ |
165 | ah->ah_radio_2ghz_revision = 0; | 166 | switch (ah->ah_radio_5ghz_revision & 0xf0) { |
166 | else | 167 | case AR5K_SREV_RAD_5111: |
167 | ah->ah_radio_2ghz_revision = ath5k_hw_radio_revision(ah, | ||
168 | CHANNEL_2GHZ); | ||
169 | |||
170 | /* Return on unsuported chips (unsupported eeprom etc) */ | ||
171 | if ((srev >= AR5K_SREV_AR5416) && | ||
172 | (srev < AR5K_SREV_AR2425)) { | ||
173 | ATH5K_ERR(sc, "Device not yet supported.\n"); | ||
174 | ret = -ENODEV; | ||
175 | goto err_free; | ||
176 | } else if (srev == AR5K_SREV_AR2425) { | ||
177 | ATH5K_WARN(sc, "Support for RF2425 is under development.\n"); | ||
178 | } | ||
179 | |||
180 | /* Identify single chip solutions */ | ||
181 | if (((srev <= AR5K_SREV_AR5414) && | ||
182 | (srev >= AR5K_SREV_AR2413)) || | ||
183 | (srev == AR5K_SREV_AR2425)) { | ||
184 | ah->ah_single_chip = true; | ||
185 | } else { | ||
186 | ah->ah_single_chip = false; | ||
187 | } | ||
188 | |||
189 | /* Single chip radio */ | ||
190 | if (ah->ah_radio_2ghz_revision == ah->ah_radio_5ghz_revision) | ||
191 | ah->ah_radio_2ghz_revision = 0; | ||
192 | |||
193 | /* Identify the radio chip*/ | ||
194 | if (ah->ah_version == AR5K_AR5210) { | ||
195 | ah->ah_radio = AR5K_RF5110; | ||
196 | /* | ||
197 | * Register returns 0x0/0x04 for radio revision | ||
198 | * so ath5k_hw_radio_revision doesn't parse the value | ||
199 | * correctly. For now we are based on mac's srev to | ||
200 | * identify RF2425 radio. | ||
201 | */ | ||
202 | } else if (srev == AR5K_SREV_AR2425) { | ||
203 | ah->ah_radio = AR5K_RF2425; | ||
204 | ah->ah_phy_spending = AR5K_PHY_SPENDING_RF2425; | ||
205 | } else if (ah->ah_radio_5ghz_revision < AR5K_SREV_RAD_5112) { | ||
206 | ah->ah_radio = AR5K_RF5111; | 168 | ah->ah_radio = AR5K_RF5111; |
169 | ah->ah_single_chip = false; | ||
170 | ah->ah_radio_2ghz_revision = ath5k_hw_radio_revision(ah, | ||
171 | CHANNEL_2GHZ); | ||
207 | ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5111; | 172 | ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5111; |
208 | } else if (ah->ah_radio_5ghz_revision < AR5K_SREV_RAD_2413) { | 173 | break; |
174 | case AR5K_SREV_RAD_5112: | ||
175 | case AR5K_SREV_RAD_2112: | ||
209 | ah->ah_radio = AR5K_RF5112; | 176 | ah->ah_radio = AR5K_RF5112; |
177 | ah->ah_single_chip = false; | ||
178 | ah->ah_radio_2ghz_revision = ath5k_hw_radio_revision(ah, | ||
179 | CHANNEL_2GHZ); | ||
210 | ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5112; | 180 | ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5112; |
211 | } else if (ah->ah_radio_5ghz_revision < AR5K_SREV_RAD_5413) { | 181 | break; |
182 | case AR5K_SREV_RAD_2413: | ||
212 | ah->ah_radio = AR5K_RF2413; | 183 | ah->ah_radio = AR5K_RF2413; |
184 | ah->ah_single_chip = true; | ||
213 | ah->ah_phy_spending = AR5K_PHY_SPENDING_RF2413; | 185 | ah->ah_phy_spending = AR5K_PHY_SPENDING_RF2413; |
214 | } else if (ah->ah_radio_5ghz_revision < AR5K_SREV_RAD_2316) { | 186 | break; |
187 | case AR5K_SREV_RAD_5413: | ||
215 | ah->ah_radio = AR5K_RF5413; | 188 | ah->ah_radio = AR5K_RF5413; |
189 | ah->ah_single_chip = true; | ||
216 | ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5413; | 190 | ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5413; |
217 | } else if (ah->ah_radio_5ghz_revision < AR5K_SREV_RAD_5133) { | 191 | break; |
218 | /* AR5424 */ | 192 | case AR5K_SREV_RAD_2316: |
219 | if (srev >= AR5K_SREV_AR5424) { | 193 | ah->ah_radio = AR5K_RF2316; |
194 | ah->ah_single_chip = true; | ||
195 | ah->ah_phy_spending = AR5K_PHY_SPENDING_RF2316; | ||
196 | break; | ||
197 | case AR5K_SREV_RAD_2317: | ||
198 | ah->ah_radio = AR5K_RF2317; | ||
199 | ah->ah_single_chip = true; | ||
200 | ah->ah_phy_spending = AR5K_PHY_SPENDING_RF2317; | ||
201 | break; | ||
202 | case AR5K_SREV_RAD_5424: | ||
203 | if (ah->ah_mac_version == AR5K_SREV_AR2425 || | ||
204 | ah->ah_mac_version == AR5K_SREV_AR2417){ | ||
205 | ah->ah_radio = AR5K_RF2425; | ||
206 | ah->ah_single_chip = true; | ||
207 | ah->ah_phy_spending = AR5K_PHY_SPENDING_RF2425; | ||
208 | } else { | ||
220 | ah->ah_radio = AR5K_RF5413; | 209 | ah->ah_radio = AR5K_RF5413; |
210 | ah->ah_single_chip = true; | ||
221 | ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5413; | 211 | ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5413; |
222 | /* AR2424 */ | 212 | } |
223 | } else { | 213 | break; |
224 | ah->ah_radio = AR5K_RF2413; /* For testing */ | 214 | default: |
215 | /* Identify radio based on mac/phy srev */ | ||
216 | if (ah->ah_version == AR5K_AR5210) { | ||
217 | ah->ah_radio = AR5K_RF5110; | ||
218 | ah->ah_single_chip = false; | ||
219 | } else if (ah->ah_version == AR5K_AR5211) { | ||
220 | ah->ah_radio = AR5K_RF5111; | ||
221 | ah->ah_single_chip = false; | ||
222 | ah->ah_radio_2ghz_revision = ath5k_hw_radio_revision(ah, | ||
223 | CHANNEL_2GHZ); | ||
224 | } else if (ah->ah_mac_version == (AR5K_SREV_AR2425 >> 4) || | ||
225 | ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4) || | ||
226 | ah->ah_phy_revision == AR5K_SREV_PHY_2425) { | ||
227 | ah->ah_radio = AR5K_RF2425; | ||
228 | ah->ah_single_chip = true; | ||
229 | 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 && | ||
232 | ah->ah_phy_revision == AR5K_SREV_PHY_2112B) { | ||
233 | ah->ah_radio = AR5K_RF5112; | ||
234 | ah->ah_single_chip = false; | ||
235 | ah->ah_radio_5ghz_revision = AR5K_SREV_RAD_2112B; | ||
236 | } else if (ah->ah_mac_version == (AR5K_SREV_AR2415 >> 4)) { | ||
237 | ah->ah_radio = AR5K_RF2316; | ||
238 | ah->ah_single_chip = true; | ||
239 | 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) || | ||
242 | ah->ah_phy_revision == AR5K_SREV_PHY_5413) { | ||
243 | ah->ah_radio = AR5K_RF5413; | ||
244 | ah->ah_single_chip = true; | ||
245 | 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) || | ||
248 | ah->ah_phy_revision == AR5K_SREV_PHY_2413) { | ||
249 | ah->ah_radio = AR5K_RF2413; | ||
250 | ah->ah_single_chip = true; | ||
251 | ah->ah_radio_5ghz_revision = AR5K_SREV_RAD_2413; | ||
225 | ah->ah_phy_spending = AR5K_PHY_SPENDING_RF2413; | 252 | ah->ah_phy_spending = AR5K_PHY_SPENDING_RF2413; |
253 | } else { | ||
254 | ATH5K_ERR(sc, "Couldn't identify radio revision.\n"); | ||
255 | ret = -ENODEV; | ||
256 | goto err_free; | ||
226 | } | 257 | } |
227 | } | 258 | } |
228 | ah->ah_phy = AR5K_PHY(0); | 259 | |
260 | |||
261 | /* Return on unsuported chips (unsupported eeprom etc) */ | ||
262 | if ((srev >= AR5K_SREV_AR5416) && | ||
263 | (srev < AR5K_SREV_AR2425)) { | ||
264 | ATH5K_ERR(sc, "Device not yet supported.\n"); | ||
265 | ret = -ENODEV; | ||
266 | goto err_free; | ||
267 | } | ||
229 | 268 | ||
230 | /* | 269 | /* |
231 | * Write PCI-E power save settings | 270 | * Write PCI-E power save settings |
232 | */ | 271 | */ |
233 | if ((ah->ah_version == AR5K_AR5212) && (pdev->is_pcie)) { | 272 | if ((ah->ah_version == AR5K_AR5212) && (pdev->is_pcie)) { |
234 | ath5k_hw_reg_write(ah, 0x9248fc00, 0x4080); | 273 | ath5k_hw_reg_write(ah, 0x9248fc00, AR5K_PCIE_SERDES); |
235 | ath5k_hw_reg_write(ah, 0x24924924, 0x4080); | 274 | ath5k_hw_reg_write(ah, 0x24924924, AR5K_PCIE_SERDES); |
236 | ath5k_hw_reg_write(ah, 0x28000039, 0x4080); | 275 | /* Shut off RX when elecidle is asserted */ |
237 | ath5k_hw_reg_write(ah, 0x53160824, 0x4080); | 276 | ath5k_hw_reg_write(ah, 0x28000039, AR5K_PCIE_SERDES); |
238 | ath5k_hw_reg_write(ah, 0xe5980579, 0x4080); | 277 | ath5k_hw_reg_write(ah, 0x53160824, AR5K_PCIE_SERDES); |
239 | ath5k_hw_reg_write(ah, 0x001defff, 0x4080); | 278 | /* TODO: EEPROM work */ |
240 | ath5k_hw_reg_write(ah, 0x1aaabe40, 0x4080); | 279 | ath5k_hw_reg_write(ah, 0xe5980579, AR5K_PCIE_SERDES); |
241 | ath5k_hw_reg_write(ah, 0xbe105554, 0x4080); | 280 | /* Shut off PLL and CLKREQ active in L1 */ |
242 | ath5k_hw_reg_write(ah, 0x000e3007, 0x4080); | 281 | ath5k_hw_reg_write(ah, 0x001defff, AR5K_PCIE_SERDES); |
243 | ath5k_hw_reg_write(ah, 0x00000000, 0x4084); | 282 | /* Preserce other settings */ |
283 | ath5k_hw_reg_write(ah, 0x1aaabe40, AR5K_PCIE_SERDES); | ||
284 | ath5k_hw_reg_write(ah, 0xbe105554, AR5K_PCIE_SERDES); | ||
285 | ath5k_hw_reg_write(ah, 0x000e3007, AR5K_PCIE_SERDES); | ||
286 | /* Reset SERDES to load new settings */ | ||
287 | ath5k_hw_reg_write(ah, 0x00000000, AR5K_PCIE_SERDES_RESET); | ||
288 | mdelay(1); | ||
244 | } | 289 | } |
245 | 290 | ||
246 | /* | 291 | /* |
@@ -250,14 +295,13 @@ struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc, u8 mac_version) | |||
250 | if (ret) | 295 | if (ret) |
251 | goto err_free; | 296 | goto err_free; |
252 | 297 | ||
253 | /* Write AR5K_PCICFG_UNK on 2112B and later chips */ | 298 | /* Enable pci core retry fix on Hainan (5213A) and later chips */ |
254 | if (ah->ah_radio_5ghz_revision > AR5K_SREV_RAD_2112B || | 299 | if (srev >= AR5K_SREV_AR5213A) |
255 | srev > AR5K_SREV_AR2413) { | ||
256 | ath5k_hw_reg_write(ah, AR5K_PCICFG_RETRY_FIX, AR5K_PCICFG); | 300 | ath5k_hw_reg_write(ah, AR5K_PCICFG_RETRY_FIX, AR5K_PCICFG); |
257 | } | ||
258 | 301 | ||
259 | /* | 302 | /* |
260 | * Get card capabilities, values, ... | 303 | * Get card capabilities, calibration values etc |
304 | * TODO: EEPROM work | ||
261 | */ | 305 | */ |
262 | ret = ath5k_eeprom_init(ah); | 306 | ret = ath5k_eeprom_init(ah); |
263 | if (ret) { | 307 | if (ret) { |
@@ -273,7 +317,7 @@ struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc, u8 mac_version) | |||
273 | goto err_free; | 317 | goto err_free; |
274 | } | 318 | } |
275 | 319 | ||
276 | /* Get MAC address */ | 320 | /* Set MAC address */ |
277 | ret = ath5k_eeprom_read_mac(ah, mac); | 321 | ret = ath5k_eeprom_read_mac(ah, mac); |
278 | if (ret) { | 322 | if (ret) { |
279 | ATH5K_ERR(sc, "unable to read address from EEPROM: 0x%04x\n", | 323 | ATH5K_ERR(sc, "unable to read address from EEPROM: 0x%04x\n", |