aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorNick Kossifidis <mick@madwifi.org>2008-09-28 18:18:16 -0400
committerJohn W. Linville <linville@tuxdriver.com>2008-09-30 14:07:26 -0400
commitee81c5544bbf49ea5b301784a605d865947ac1b0 (patch)
tree90af7f2f1d96584dad9c5946ca627406377cb00b /drivers/net
parent1d280ddcfd6666a45915ccc3a76dee033a6b917b (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.c182
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",