diff options
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-eeprom.c')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-eeprom.c | 50 |
1 files changed, 41 insertions, 9 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-eeprom.c index 402733638f50..c8397962632c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom.c +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.c | |||
@@ -142,6 +142,45 @@ static const u8 iwl_eeprom_band_7[] = { /* 5.2 ht40 channel */ | |||
142 | * | 142 | * |
143 | ******************************************************************************/ | 143 | ******************************************************************************/ |
144 | 144 | ||
145 | /* | ||
146 | * The device's EEPROM semaphore prevents conflicts between driver and uCode | ||
147 | * when accessing the EEPROM; each access is a series of pulses to/from the | ||
148 | * EEPROM chip, not a single event, so even reads could conflict if they | ||
149 | * weren't arbitrated by the semaphore. | ||
150 | */ | ||
151 | static int iwl_eeprom_acquire_semaphore(struct iwl_priv *priv) | ||
152 | { | ||
153 | u16 count; | ||
154 | int ret; | ||
155 | |||
156 | for (count = 0; count < EEPROM_SEM_RETRY_LIMIT; count++) { | ||
157 | /* Request semaphore */ | ||
158 | iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG, | ||
159 | CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM); | ||
160 | |||
161 | /* See if we got it */ | ||
162 | ret = iwl_poll_bit(priv, CSR_HW_IF_CONFIG_REG, | ||
163 | CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM, | ||
164 | CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM, | ||
165 | EEPROM_SEM_TIMEOUT); | ||
166 | if (ret >= 0) { | ||
167 | IWL_DEBUG_EEPROM(priv, | ||
168 | "Acquired semaphore after %d tries.\n", | ||
169 | count+1); | ||
170 | return ret; | ||
171 | } | ||
172 | } | ||
173 | |||
174 | return ret; | ||
175 | } | ||
176 | |||
177 | static void iwl_eeprom_release_semaphore(struct iwl_priv *priv) | ||
178 | { | ||
179 | iwl_clear_bit(priv, CSR_HW_IF_CONFIG_REG, | ||
180 | CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM); | ||
181 | |||
182 | } | ||
183 | |||
145 | static int iwl_eeprom_verify_signature(struct iwl_priv *priv) | 184 | static int iwl_eeprom_verify_signature(struct iwl_priv *priv) |
146 | { | 185 | { |
147 | u32 gp = iwl_read32(priv, CSR_EEPROM_GP) & CSR_EEPROM_GP_VALID_MSK; | 186 | u32 gp = iwl_read32(priv, CSR_EEPROM_GP) & CSR_EEPROM_GP_VALID_MSK; |
@@ -421,7 +460,7 @@ int iwl_eeprom_init(struct iwl_priv *priv, u32 hw_rev) | |||
421 | } | 460 | } |
422 | 461 | ||
423 | /* Make sure driver (instead of uCode) is allowed to read EEPROM */ | 462 | /* Make sure driver (instead of uCode) is allowed to read EEPROM */ |
424 | ret = priv->cfg->ops->lib->eeprom_ops.acquire_semaphore(priv); | 463 | ret = iwl_eeprom_acquire_semaphore(priv); |
425 | if (ret < 0) { | 464 | if (ret < 0) { |
426 | IWL_ERR(priv, "Failed to acquire EEPROM semaphore.\n"); | 465 | IWL_ERR(priv, "Failed to acquire EEPROM semaphore.\n"); |
427 | ret = -ENOENT; | 466 | ret = -ENOENT; |
@@ -488,7 +527,7 @@ int iwl_eeprom_init(struct iwl_priv *priv, u32 hw_rev) | |||
488 | 527 | ||
489 | ret = 0; | 528 | ret = 0; |
490 | done: | 529 | done: |
491 | priv->cfg->ops->lib->eeprom_ops.release_semaphore(priv); | 530 | iwl_eeprom_release_semaphore(priv); |
492 | 531 | ||
493 | err: | 532 | err: |
494 | if (ret) | 533 | if (ret) |
@@ -711,13 +750,6 @@ int iwl_init_channel_map(struct iwl_priv *priv) | |||
711 | flags & EEPROM_CHANNEL_RADAR)) | 750 | flags & EEPROM_CHANNEL_RADAR)) |
712 | ? "" : "not "); | 751 | ? "" : "not "); |
713 | 752 | ||
714 | /* Set the tx_power_user_lmt to the highest power | ||
715 | * supported by any channel */ | ||
716 | if (eeprom_ch_info[ch].max_power_avg > | ||
717 | priv->tx_power_user_lmt) | ||
718 | priv->tx_power_user_lmt = | ||
719 | eeprom_ch_info[ch].max_power_avg; | ||
720 | |||
721 | ch_info++; | 753 | ch_info++; |
722 | } | 754 | } |
723 | } | 755 | } |