diff options
Diffstat (limited to 'drivers/net/wireless/ath/ath5k/attach.c')
-rw-r--r-- | drivers/net/wireless/ath/ath5k/attach.c | 80 |
1 files changed, 44 insertions, 36 deletions
diff --git a/drivers/net/wireless/ath/ath5k/attach.c b/drivers/net/wireless/ath/ath5k/attach.c index b32e28caeee2..1588401de3c4 100644 --- a/drivers/net/wireless/ath/ath5k/attach.c +++ b/drivers/net/wireless/ath/ath5k/attach.c | |||
@@ -93,16 +93,16 @@ static int ath5k_hw_post(struct ath5k_hw *ah) | |||
93 | } | 93 | } |
94 | 94 | ||
95 | /** | 95 | /** |
96 | * ath5k_hw_attach - Check if hw is supported and init the needed structs | 96 | * ath5k_hw_init - Check if hw is supported and init the needed structs |
97 | * | 97 | * |
98 | * @sc: The &struct ath5k_softc we got from the driver's attach function | 98 | * @sc: The &struct ath5k_softc we got from the driver's init_softc function |
99 | * | 99 | * |
100 | * Check if the device is supported, perform a POST and initialize the needed | 100 | * Check if the device is supported, perform a POST and initialize the needed |
101 | * structs. Returns -ENOMEM if we don't have memory for the needed structs, | 101 | * structs. Returns -ENOMEM if we don't have memory for the needed structs, |
102 | * -ENODEV if the device is not supported or prints an error msg if something | 102 | * -ENODEV if the device is not supported or prints an error msg if something |
103 | * else went wrong. | 103 | * else went wrong. |
104 | */ | 104 | */ |
105 | int ath5k_hw_attach(struct ath5k_softc *sc) | 105 | int ath5k_hw_init(struct ath5k_softc *sc) |
106 | { | 106 | { |
107 | struct ath5k_hw *ah = sc->ah; | 107 | struct ath5k_hw *ah = sc->ah; |
108 | struct ath_common *common = ath5k_hw_common(ah); | 108 | struct ath_common *common = ath5k_hw_common(ah); |
@@ -115,14 +115,11 @@ int ath5k_hw_attach(struct ath5k_softc *sc) | |||
115 | * HW information | 115 | * HW information |
116 | */ | 116 | */ |
117 | ah->ah_radar.r_enabled = AR5K_TUNE_RADAR_ALERT; | 117 | ah->ah_radar.r_enabled = AR5K_TUNE_RADAR_ALERT; |
118 | ah->ah_turbo = false; | 118 | ah->ah_bwmode = AR5K_BWMODE_DEFAULT; |
119 | ah->ah_txpower.txp_tpc = AR5K_TUNE_TPC_TXPOWER; | 119 | ah->ah_txpower.txp_tpc = AR5K_TUNE_TPC_TXPOWER; |
120 | ah->ah_imr = 0; | 120 | ah->ah_imr = 0; |
121 | ah->ah_atim_window = 0; | 121 | ah->ah_retry_short = AR5K_INIT_RETRY_SHORT; |
122 | ah->ah_aifs = AR5K_TUNE_AIFS; | 122 | ah->ah_retry_long = AR5K_INIT_RETRY_LONG; |
123 | ah->ah_cw_min = AR5K_TUNE_CWMIN; | ||
124 | ah->ah_limit_tx_retries = AR5K_INIT_TX_RETRY; | ||
125 | ah->ah_software_retry = false; | ||
126 | ah->ah_ant_mode = AR5K_ANTMODE_DEFAULT; | 123 | ah->ah_ant_mode = AR5K_ANTMODE_DEFAULT; |
127 | ah->ah_noise_floor = -95; /* until first NF calibration is run */ | 124 | ah->ah_noise_floor = -95; /* until first NF calibration is run */ |
128 | sc->ani_state.ani_mode = ATH5K_ANI_MODE_AUTO; | 125 | sc->ani_state.ani_mode = ATH5K_ANI_MODE_AUTO; |
@@ -131,7 +128,8 @@ int ath5k_hw_attach(struct ath5k_softc *sc) | |||
131 | /* | 128 | /* |
132 | * Find the mac version | 129 | * Find the mac version |
133 | */ | 130 | */ |
134 | srev = ath5k_hw_reg_read(ah, AR5K_SREV); | 131 | ath5k_hw_read_srev(ah); |
132 | srev = ah->ah_mac_srev; | ||
135 | if (srev < AR5K_SREV_AR5311) | 133 | if (srev < AR5K_SREV_AR5311) |
136 | ah->ah_version = AR5K_AR5210; | 134 | ah->ah_version = AR5K_AR5210; |
137 | else if (srev < AR5K_SREV_AR5212) | 135 | else if (srev < AR5K_SREV_AR5212) |
@@ -139,26 +137,28 @@ int ath5k_hw_attach(struct ath5k_softc *sc) | |||
139 | else | 137 | else |
140 | ah->ah_version = AR5K_AR5212; | 138 | ah->ah_version = AR5K_AR5212; |
141 | 139 | ||
142 | /*Fill the ath5k_hw struct with the needed functions*/ | 140 | /* Get the MAC revision */ |
141 | ah->ah_mac_version = AR5K_REG_MS(srev, AR5K_SREV_VER); | ||
142 | ah->ah_mac_revision = AR5K_REG_MS(srev, AR5K_SREV_REV); | ||
143 | |||
144 | /* Fill the ath5k_hw struct with the needed functions */ | ||
143 | ret = ath5k_hw_init_desc_functions(ah); | 145 | ret = ath5k_hw_init_desc_functions(ah); |
144 | if (ret) | 146 | if (ret) |
145 | goto err_free; | 147 | goto err; |
146 | 148 | ||
147 | /* Bring device out of sleep and reset it's units */ | 149 | /* Bring device out of sleep and reset its units */ |
148 | ret = ath5k_hw_nic_wakeup(ah, 0, true); | 150 | ret = ath5k_hw_nic_wakeup(ah, 0, true); |
149 | if (ret) | 151 | if (ret) |
150 | goto err_free; | 152 | goto err; |
151 | 153 | ||
152 | /* Get MAC, PHY and RADIO revisions */ | 154 | /* Get PHY and RADIO revisions */ |
153 | ah->ah_mac_srev = srev; | ||
154 | ah->ah_mac_version = AR5K_REG_MS(srev, AR5K_SREV_VER); | ||
155 | ah->ah_phy_revision = ath5k_hw_reg_read(ah, AR5K_PHY_CHIP_ID) & | 155 | ah->ah_phy_revision = ath5k_hw_reg_read(ah, AR5K_PHY_CHIP_ID) & |
156 | 0xffffffff; | 156 | 0xffffffff; |
157 | ah->ah_radio_5ghz_revision = ath5k_hw_radio_revision(ah, | 157 | ah->ah_radio_5ghz_revision = ath5k_hw_radio_revision(ah, |
158 | CHANNEL_5GHZ); | 158 | CHANNEL_5GHZ); |
159 | ah->ah_phy = AR5K_PHY(0); | 159 | ah->ah_phy = AR5K_PHY(0); |
160 | 160 | ||
161 | /* Try to identify radio chip based on it's srev */ | 161 | /* Try to identify radio chip based on its srev */ |
162 | switch (ah->ah_radio_5ghz_revision & 0xf0) { | 162 | switch (ah->ah_radio_5ghz_revision & 0xf0) { |
163 | case AR5K_SREV_RAD_5111: | 163 | case AR5K_SREV_RAD_5111: |
164 | ah->ah_radio = AR5K_RF5111; | 164 | ah->ah_radio = AR5K_RF5111; |
@@ -220,7 +220,8 @@ int ath5k_hw_attach(struct ath5k_softc *sc) | |||
220 | ah->ah_radio = AR5K_RF5112; | 220 | ah->ah_radio = AR5K_RF5112; |
221 | ah->ah_single_chip = false; | 221 | ah->ah_single_chip = false; |
222 | ah->ah_radio_5ghz_revision = AR5K_SREV_RAD_5112B; | 222 | ah->ah_radio_5ghz_revision = AR5K_SREV_RAD_5112B; |
223 | } else if (ah->ah_mac_version == (AR5K_SREV_AR2415 >> 4)) { | 223 | } else if (ah->ah_mac_version == (AR5K_SREV_AR2415 >> 4) || |
224 | ah->ah_mac_version == (AR5K_SREV_AR2315_R6 >> 4)) { | ||
224 | ah->ah_radio = AR5K_RF2316; | 225 | ah->ah_radio = AR5K_RF2316; |
225 | ah->ah_single_chip = true; | 226 | ah->ah_single_chip = true; |
226 | ah->ah_radio_5ghz_revision = AR5K_SREV_RAD_2316; | 227 | ah->ah_radio_5ghz_revision = AR5K_SREV_RAD_2316; |
@@ -237,7 +238,7 @@ int ath5k_hw_attach(struct ath5k_softc *sc) | |||
237 | } else { | 238 | } else { |
238 | ATH5K_ERR(sc, "Couldn't identify radio revision.\n"); | 239 | ATH5K_ERR(sc, "Couldn't identify radio revision.\n"); |
239 | ret = -ENODEV; | 240 | ret = -ENODEV; |
240 | goto err_free; | 241 | goto err; |
241 | } | 242 | } |
242 | } | 243 | } |
243 | 244 | ||
@@ -247,7 +248,7 @@ int ath5k_hw_attach(struct ath5k_softc *sc) | |||
247 | (srev < AR5K_SREV_AR2425)) { | 248 | (srev < AR5K_SREV_AR2425)) { |
248 | ATH5K_ERR(sc, "Device not yet supported.\n"); | 249 | ATH5K_ERR(sc, "Device not yet supported.\n"); |
249 | ret = -ENODEV; | 250 | ret = -ENODEV; |
250 | goto err_free; | 251 | goto err; |
251 | } | 252 | } |
252 | 253 | ||
253 | /* | 254 | /* |
@@ -255,7 +256,7 @@ int ath5k_hw_attach(struct ath5k_softc *sc) | |||
255 | */ | 256 | */ |
256 | ret = ath5k_hw_post(ah); | 257 | ret = ath5k_hw_post(ah); |
257 | if (ret) | 258 | if (ret) |
258 | goto err_free; | 259 | goto err; |
259 | 260 | ||
260 | /* Enable pci core retry fix on Hainan (5213A) and later chips */ | 261 | /* Enable pci core retry fix on Hainan (5213A) and later chips */ |
261 | if (srev >= AR5K_SREV_AR5213A) | 262 | if (srev >= AR5K_SREV_AR5213A) |
@@ -268,7 +269,7 @@ int ath5k_hw_attach(struct ath5k_softc *sc) | |||
268 | ret = ath5k_eeprom_init(ah); | 269 | ret = ath5k_eeprom_init(ah); |
269 | if (ret) { | 270 | if (ret) { |
270 | ATH5K_ERR(sc, "unable to init EEPROM\n"); | 271 | ATH5K_ERR(sc, "unable to init EEPROM\n"); |
271 | goto err_free; | 272 | goto err; |
272 | } | 273 | } |
273 | 274 | ||
274 | ee = &ah->ah_capabilities.cap_eeprom; | 275 | ee = &ah->ah_capabilities.cap_eeprom; |
@@ -276,7 +277,7 @@ int ath5k_hw_attach(struct ath5k_softc *sc) | |||
276 | /* | 277 | /* |
277 | * Write PCI-E power save settings | 278 | * Write PCI-E power save settings |
278 | */ | 279 | */ |
279 | if ((ah->ah_version == AR5K_AR5212) && (pdev->is_pcie)) { | 280 | if ((ah->ah_version == AR5K_AR5212) && pdev && (pci_is_pcie(pdev))) { |
280 | ath5k_hw_reg_write(ah, 0x9248fc00, AR5K_PCIE_SERDES); | 281 | ath5k_hw_reg_write(ah, 0x9248fc00, AR5K_PCIE_SERDES); |
281 | ath5k_hw_reg_write(ah, 0x24924924, AR5K_PCIE_SERDES); | 282 | ath5k_hw_reg_write(ah, 0x24924924, AR5K_PCIE_SERDES); |
282 | 283 | ||
@@ -308,18 +309,26 @@ int ath5k_hw_attach(struct ath5k_softc *sc) | |||
308 | /* Get misc capabilities */ | 309 | /* Get misc capabilities */ |
309 | ret = ath5k_hw_set_capabilities(ah); | 310 | ret = ath5k_hw_set_capabilities(ah); |
310 | if (ret) { | 311 | if (ret) { |
311 | ATH5K_ERR(sc, "unable to get device capabilities: 0x%04x\n", | 312 | ATH5K_ERR(sc, "unable to get device capabilities\n"); |
312 | sc->pdev->device); | 313 | goto err; |
313 | goto err_free; | 314 | } |
315 | |||
316 | if (test_bit(ATH_STAT_2G_DISABLED, sc->status)) { | ||
317 | __clear_bit(AR5K_MODE_11B, ah->ah_capabilities.cap_mode); | ||
318 | __clear_bit(AR5K_MODE_11G, ah->ah_capabilities.cap_mode); | ||
314 | } | 319 | } |
315 | 320 | ||
316 | /* Crypto settings */ | 321 | /* Crypto settings */ |
317 | ah->ah_aes_support = srev >= AR5K_SREV_AR5212_V4 && | 322 | common->keymax = (sc->ah->ah_version == AR5K_AR5210 ? |
318 | (ee->ee_version >= AR5K_EEPROM_VERSION_5_0 && | 323 | AR5K_KEYTABLE_SIZE_5210 : AR5K_KEYTABLE_SIZE_5211); |
319 | !AR5K_EEPROM_AES_DIS(ee->ee_misc5)); | 324 | |
325 | if (srev >= AR5K_SREV_AR5212_V4 && | ||
326 | (ee->ee_version < AR5K_EEPROM_VERSION_5_0 || | ||
327 | !AR5K_EEPROM_AES_DIS(ee->ee_misc5))) | ||
328 | common->crypt_caps |= ATH_CRYPT_CAP_CIPHER_AESCCM; | ||
320 | 329 | ||
321 | if (srev >= AR5K_SREV_AR2414) { | 330 | if (srev >= AR5K_SREV_AR2414) { |
322 | ah->ah_combined_mic = true; | 331 | common->crypt_caps |= ATH_CRYPT_CAP_MIC_COMBINED; |
323 | AR5K_REG_ENABLE_BITS(ah, AR5K_MISC_MODE, | 332 | AR5K_REG_ENABLE_BITS(ah, AR5K_MISC_MODE, |
324 | AR5K_MISC_MODE_COMBINED_MIC); | 333 | AR5K_MISC_MODE_COMBINED_MIC); |
325 | } | 334 | } |
@@ -329,7 +338,7 @@ int ath5k_hw_attach(struct ath5k_softc *sc) | |||
329 | 338 | ||
330 | /* Set BSSID to bcast address: ff:ff:ff:ff:ff:ff for now */ | 339 | /* Set BSSID to bcast address: ff:ff:ff:ff:ff:ff for now */ |
331 | memcpy(common->curbssid, ath_bcast_mac, ETH_ALEN); | 340 | memcpy(common->curbssid, ath_bcast_mac, ETH_ALEN); |
332 | ath5k_hw_set_associd(ah); | 341 | ath5k_hw_set_bssid(ah); |
333 | ath5k_hw_set_opmode(ah, sc->opmode); | 342 | ath5k_hw_set_opmode(ah, sc->opmode); |
334 | 343 | ||
335 | ath5k_hw_rfgain_opt_init(ah); | 344 | ath5k_hw_rfgain_opt_init(ah); |
@@ -340,17 +349,16 @@ int ath5k_hw_attach(struct ath5k_softc *sc) | |||
340 | ath5k_hw_set_ledstate(ah, AR5K_LED_INIT); | 349 | ath5k_hw_set_ledstate(ah, AR5K_LED_INIT); |
341 | 350 | ||
342 | return 0; | 351 | return 0; |
343 | err_free: | 352 | err: |
344 | kfree(ah); | ||
345 | return ret; | 353 | return ret; |
346 | } | 354 | } |
347 | 355 | ||
348 | /** | 356 | /** |
349 | * ath5k_hw_detach - Free the ath5k_hw struct | 357 | * ath5k_hw_deinit - Free the ath5k_hw struct |
350 | * | 358 | * |
351 | * @ah: The &struct ath5k_hw | 359 | * @ah: The &struct ath5k_hw |
352 | */ | 360 | */ |
353 | void ath5k_hw_detach(struct ath5k_hw *ah) | 361 | void ath5k_hw_deinit(struct ath5k_hw *ah) |
354 | { | 362 | { |
355 | __set_bit(ATH_STAT_INVALID, ah->ah_sc->status); | 363 | __set_bit(ATH_STAT_INVALID, ah->ah_sc->status); |
356 | 364 | ||