aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/iwl-eeprom.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-eeprom.c')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-eeprom.c153
1 files changed, 130 insertions, 23 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-eeprom.c
index 75517d05df08..7d7554a2f341 100644
--- a/drivers/net/wireless/iwlwifi/iwl-eeprom.c
+++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.c
@@ -152,6 +152,32 @@ int iwlcore_eeprom_verify_signature(struct iwl_priv *priv)
152} 152}
153EXPORT_SYMBOL(iwlcore_eeprom_verify_signature); 153EXPORT_SYMBOL(iwlcore_eeprom_verify_signature);
154 154
155static int iwlcore_get_nvm_type(struct iwl_priv *priv)
156{
157 u32 otpgp;
158 int nvm_type;
159
160 /* OTP only valid for CP/PP and after */
161 switch (priv->hw_rev & CSR_HW_REV_TYPE_MSK) {
162 case CSR_HW_REV_TYPE_3945:
163 case CSR_HW_REV_TYPE_4965:
164 case CSR_HW_REV_TYPE_5300:
165 case CSR_HW_REV_TYPE_5350:
166 case CSR_HW_REV_TYPE_5100:
167 case CSR_HW_REV_TYPE_5150:
168 nvm_type = NVM_DEVICE_TYPE_EEPROM;
169 break;
170 default:
171 otpgp = iwl_read32(priv, CSR_OTP_GP_REG);
172 if (otpgp & CSR_OTP_GP_REG_DEVICE_SELECT)
173 nvm_type = NVM_DEVICE_TYPE_OTP;
174 else
175 nvm_type = NVM_DEVICE_TYPE_EEPROM;
176 break;
177 }
178 return nvm_type;
179}
180
155/* 181/*
156 * The device's EEPROM semaphore prevents conflicts between driver and uCode 182 * The device's EEPROM semaphore prevents conflicts between driver and uCode
157 * when accessing the EEPROM; each access is a series of pulses to/from the 183 * when accessing the EEPROM; each access is a series of pulses to/from the
@@ -198,6 +224,31 @@ const u8 *iwlcore_eeprom_query_addr(const struct iwl_priv *priv, size_t offset)
198} 224}
199EXPORT_SYMBOL(iwlcore_eeprom_query_addr); 225EXPORT_SYMBOL(iwlcore_eeprom_query_addr);
200 226
227static int iwl_init_otp_access(struct iwl_priv *priv)
228{
229 int ret;
230
231 /* Enable 40MHz radio clock */
232 _iwl_write32(priv, CSR_GP_CNTRL,
233 _iwl_read32(priv, CSR_GP_CNTRL) |
234 CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
235
236 /* wait for clock to be ready */
237 ret = iwl_poll_direct_bit(priv, CSR_GP_CNTRL,
238 CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY,
239 25000);
240 if (ret < 0)
241 IWL_ERR(priv, "Time out access OTP\n");
242 else {
243 iwl_set_bits_prph(priv, APMG_PS_CTRL_REG,
244 APMG_PS_CTRL_VAL_RESET_REQ);
245 udelay(5);
246 iwl_clear_bits_prph(priv, APMG_PS_CTRL_REG,
247 APMG_PS_CTRL_VAL_RESET_REQ);
248 }
249 return ret;
250}
251
201/** 252/**
202 * iwl_eeprom_init - read EEPROM contents 253 * iwl_eeprom_init - read EEPROM contents
203 * 254 *
@@ -209,11 +260,18 @@ int iwl_eeprom_init(struct iwl_priv *priv)
209{ 260{
210 u16 *e; 261 u16 *e;
211 u32 gp = iwl_read32(priv, CSR_EEPROM_GP); 262 u32 gp = iwl_read32(priv, CSR_EEPROM_GP);
212 int sz = priv->cfg->eeprom_size; 263 int sz;
213 int ret; 264 int ret;
214 u16 addr; 265 u16 addr;
266 u32 otpgp;
267
268 priv->nvm_device_type = iwlcore_get_nvm_type(priv);
215 269
216 /* allocate eeprom */ 270 /* allocate eeprom */
271 if (priv->nvm_device_type == NVM_DEVICE_TYPE_OTP)
272 priv->cfg->eeprom_size =
273 OTP_BLOCK_SIZE * OTP_LOWER_BLOCKS_TOTAL;
274 sz = priv->cfg->eeprom_size;
217 priv->eeprom = kzalloc(sz, GFP_KERNEL); 275 priv->eeprom = kzalloc(sz, GFP_KERNEL);
218 if (!priv->eeprom) { 276 if (!priv->eeprom) {
219 ret = -ENOMEM; 277 ret = -ENOMEM;
@@ -235,30 +293,77 @@ int iwl_eeprom_init(struct iwl_priv *priv)
235 ret = -ENOENT; 293 ret = -ENOENT;
236 goto err; 294 goto err;
237 } 295 }
238 296 if (priv->nvm_device_type == NVM_DEVICE_TYPE_OTP) {
239 /* eeprom is an array of 16bit values */ 297 ret = iwl_init_otp_access(priv);
240 for (addr = 0; addr < sz; addr += sizeof(u16)) { 298 if (ret) {
241 u32 r; 299 IWL_ERR(priv, "Failed to initialize OTP access.\n");
242 300 ret = -ENOENT;
243 _iwl_write32(priv, CSR_EEPROM_REG, 301 goto err;
244 CSR_EEPROM_REG_MSK_ADDR & (addr << 1)); 302 }
245 303 _iwl_write32(priv, CSR_EEPROM_GP,
246 ret = iwl_poll_direct_bit(priv, CSR_EEPROM_REG, 304 iwl_read32(priv, CSR_EEPROM_GP) &
247 CSR_EEPROM_REG_READ_VALID_MSK, 305 ~CSR_EEPROM_GP_IF_OWNER_MSK);
248 IWL_EEPROM_ACCESS_TIMEOUT); 306 /* clear */
249 if (ret < 0) { 307 _iwl_write32(priv, CSR_OTP_GP_REG,
250 IWL_ERR(priv, "Time out reading EEPROM[%d]\n", addr); 308 iwl_read32(priv, CSR_OTP_GP_REG) |
251 goto done; 309 CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK |
310 CSR_OTP_GP_REG_ECC_UNCORR_STATUS_MSK);
311
312 for (addr = 0; addr < sz; addr += sizeof(u16)) {
313 u32 r;
314
315 _iwl_write32(priv, CSR_EEPROM_REG,
316 CSR_EEPROM_REG_MSK_ADDR & (addr << 1));
317
318 ret = iwl_poll_direct_bit(priv, CSR_EEPROM_REG,
319 CSR_EEPROM_REG_READ_VALID_MSK,
320 IWL_EEPROM_ACCESS_TIMEOUT);
321 if (ret < 0) {
322 IWL_ERR(priv, "Time out reading OTP[%d]\n", addr);
323 goto done;
324 }
325 r = _iwl_read_direct32(priv, CSR_EEPROM_REG);
326 /* check for ECC errors: */
327 otpgp = iwl_read32(priv, CSR_OTP_GP_REG);
328 if (otpgp & CSR_OTP_GP_REG_ECC_UNCORR_STATUS_MSK) {
329 /* stop in this case */
330 IWL_ERR(priv, "Uncorrectable OTP ECC error, Abort OTP read\n");
331 goto done;
332 }
333 if (otpgp & CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK) {
334 /* continue in this case */
335 _iwl_write32(priv, CSR_OTP_GP_REG,
336 iwl_read32(priv, CSR_OTP_GP_REG) |
337 CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK);
338 IWL_ERR(priv, "Correctable OTP ECC error, continue read\n");
339 }
340 e[addr / 2] = le16_to_cpu((__force __le16)(r >> 16));
341 }
342 } else {
343 /* eeprom is an array of 16bit values */
344 for (addr = 0; addr < sz; addr += sizeof(u16)) {
345 u32 r;
346
347 _iwl_write32(priv, CSR_EEPROM_REG,
348 CSR_EEPROM_REG_MSK_ADDR & (addr << 1));
349
350 ret = iwl_poll_direct_bit(priv, CSR_EEPROM_REG,
351 CSR_EEPROM_REG_READ_VALID_MSK,
352 IWL_EEPROM_ACCESS_TIMEOUT);
353 if (ret < 0) {
354 IWL_ERR(priv, "Time out reading EEPROM[%d]\n", addr);
355 goto done;
356 }
357 r = _iwl_read_direct32(priv, CSR_EEPROM_REG);
358 e[addr / 2] = le16_to_cpu((__force __le16)(r >> 16));
252 } 359 }
253 r = _iwl_read_direct32(priv, CSR_EEPROM_REG);
254 e[addr / 2] = le16_to_cpu((__force __le16)(r >> 16));
255 } 360 }
256 ret = 0; 361 ret = 0;
257done: 362done:
258 priv->cfg->ops->lib->eeprom_ops.release_semaphore(priv); 363 priv->cfg->ops->lib->eeprom_ops.release_semaphore(priv);
259err: 364err:
260 if (ret) 365 if (ret)
261 kfree(priv->eeprom); 366 iwl_eeprom_free(priv);
262alloc_err: 367alloc_err:
263 return ret; 368 return ret;
264} 369}
@@ -285,7 +390,7 @@ int iwl_eeprom_check_version(struct iwl_priv *priv)
285 390
286 return 0; 391 return 0;
287err: 392err:
288 IWL_ERR(priv, "Unsupported EEPROM VER=0x%x < 0x%x CALIB=0x%x < 0x%x\n", 393 IWL_ERR(priv, "Unsupported (too old) EEPROM VER=0x%x < 0x%x CALIB=0x%x < 0x%x\n",
289 eeprom_ver, priv->cfg->eeprom_ver, 394 eeprom_ver, priv->cfg->eeprom_ver,
290 calib_ver, priv->cfg->eeprom_calib_ver); 395 calib_ver, priv->cfg->eeprom_calib_ver);
291 return -EINVAL; 396 return -EINVAL;
@@ -301,6 +406,8 @@ EXPORT_SYMBOL(iwl_eeprom_query_addr);
301 406
302u16 iwl_eeprom_query16(const struct iwl_priv *priv, size_t offset) 407u16 iwl_eeprom_query16(const struct iwl_priv *priv, size_t offset)
303{ 408{
409 if (!priv->eeprom)
410 return 0;
304 return (u16)priv->eeprom[offset] | ((u16)priv->eeprom[offset + 1] << 8); 411 return (u16)priv->eeprom[offset] | ((u16)priv->eeprom[offset + 1] << 8);
305} 412}
306EXPORT_SYMBOL(iwl_eeprom_query16); 413EXPORT_SYMBOL(iwl_eeprom_query16);
@@ -481,8 +588,8 @@ int iwl_init_channel_map(struct iwl_priv *priv)
481 /* First write that fat is not enabled, and then enable 588 /* First write that fat is not enabled, and then enable
482 * one by one */ 589 * one by one */
483 ch_info->fat_extension_channel = 590 ch_info->fat_extension_channel =
484 (IEEE80211_CHAN_NO_FAT_ABOVE | 591 (IEEE80211_CHAN_NO_HT40PLUS |
485 IEEE80211_CHAN_NO_FAT_BELOW); 592 IEEE80211_CHAN_NO_HT40MINUS);
486 593
487 if (!(is_channel_valid(ch_info))) { 594 if (!(is_channel_valid(ch_info))) {
488 IWL_DEBUG_INFO(priv, "Ch. %d Flags %x [%sGHz] - " 595 IWL_DEBUG_INFO(priv, "Ch. %d Flags %x [%sGHz] - "
@@ -561,7 +668,7 @@ int iwl_init_channel_map(struct iwl_priv *priv)
561 fat_extension_chan = 0; 668 fat_extension_chan = 0;
562 else 669 else
563 fat_extension_chan = 670 fat_extension_chan =
564 IEEE80211_CHAN_NO_FAT_BELOW; 671 IEEE80211_CHAN_NO_HT40MINUS;
565 672
566 /* Set up driver's info for lower half */ 673 /* Set up driver's info for lower half */
567 iwl_set_fat_chan_info(priv, ieeeband, 674 iwl_set_fat_chan_info(priv, ieeeband,
@@ -573,7 +680,7 @@ int iwl_init_channel_map(struct iwl_priv *priv)
573 iwl_set_fat_chan_info(priv, ieeeband, 680 iwl_set_fat_chan_info(priv, ieeeband,
574 (eeprom_ch_index[ch] + 4), 681 (eeprom_ch_index[ch] + 4),
575 &(eeprom_ch_info[ch]), 682 &(eeprom_ch_info[ch]),
576 IEEE80211_CHAN_NO_FAT_ABOVE); 683 IEEE80211_CHAN_NO_HT40PLUS);
577 } 684 }
578 } 685 }
579 686