aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath/ath5k/attach.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/ath/ath5k/attach.c')
-rw-r--r--drivers/net/wireless/ath/ath5k/attach.c80
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 */
105int ath5k_hw_attach(struct ath5k_softc *sc) 105int 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;
343err_free: 352err:
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 */
353void ath5k_hw_detach(struct ath5k_hw *ah) 361void 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