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.c531
1 files changed, 101 insertions, 430 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-eeprom.c
index a45d02e555cf..47a56bc1cd12 100644
--- a/drivers/net/wireless/iwlwifi/iwl-eeprom.c
+++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.c
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved. 8 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved. 33 * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
@@ -136,90 +136,57 @@ static const u8 iwl_eeprom_band_7[] = { /* 5.2 ht40 channel */
136 36, 44, 52, 60, 100, 108, 116, 124, 132, 149, 157 136 36, 44, 52, 60, 100, 108, 116, 124, 132, 149, 157
137}; 137};
138 138
139/**
140 * struct iwl_txpwr_section: eeprom section information
141 * @offset: indirect address into eeprom image
142 * @count: number of "struct iwl_eeprom_enhanced_txpwr" in this section
143 * @band: band type for the section
144 * @is_common - true: common section, false: channel section
145 * @is_cck - true: cck section, false: not cck section
146 * @is_ht_40 - true: all channel in the section are HT40 channel,
147 * false: legacy or HT 20 MHz
148 * ignore if it is common section
149 * @iwl_eeprom_section_channel: channel array in the section,
150 * ignore if common section
151 */
152struct iwl_txpwr_section {
153 u32 offset;
154 u8 count;
155 enum ieee80211_band band;
156 bool is_common;
157 bool is_cck;
158 bool is_ht40;
159 u8 iwl_eeprom_section_channel[EEPROM_MAX_TXPOWER_SECTION_ELEMENTS];
160};
161
162/**
163 * section 1 - 3 are regulatory tx power apply to all channels based on
164 * modulation: CCK, OFDM
165 * Band: 2.4GHz, 5.2GHz
166 * section 4 - 10 are regulatory tx power apply to specified channels
167 * For example:
168 * 1L - Channel 1 Legacy
169 * 1HT - Channel 1 HT
170 * (1,+1) - Channel 1 HT40 "_above_"
171 *
172 * Section 1: all CCK channels
173 * Section 2: all 2.4 GHz OFDM (Legacy, HT and HT40) channels
174 * Section 3: all 5.2 GHz OFDM (Legacy, HT and HT40) channels
175 * Section 4: 2.4 GHz 20MHz channels: 1L, 1HT, 2L, 2HT, 10L, 10HT, 11L, 11HT
176 * Section 5: 2.4 GHz 40MHz channels: (1,+1) (2,+1) (6,+1) (7,+1) (9,+1)
177 * Section 6: 5.2 GHz 20MHz channels: 36L, 64L, 100L, 36HT, 64HT, 100HT
178 * Section 7: 5.2 GHz 40MHz channels: (36,+1) (60,+1) (100,+1)
179 * Section 8: 2.4 GHz channel: 13L, 13HT
180 * Section 9: 2.4 GHz channel: 140L, 140HT
181 * Section 10: 2.4 GHz 40MHz channels: (132,+1) (44,+1)
182 *
183 */
184static const struct iwl_txpwr_section enhinfo[] = {
185 { EEPROM_LB_CCK_20_COMMON, 1, IEEE80211_BAND_2GHZ, true, true, false },
186 { EEPROM_LB_OFDM_COMMON, 3, IEEE80211_BAND_2GHZ, true, false, false },
187 { EEPROM_HB_OFDM_COMMON, 3, IEEE80211_BAND_5GHZ, true, false, false },
188 { EEPROM_LB_OFDM_20_BAND, 8, IEEE80211_BAND_2GHZ,
189 false, false, false,
190 {1, 1, 2, 2, 10, 10, 11, 11 } },
191 { EEPROM_LB_OFDM_HT40_BAND, 5, IEEE80211_BAND_2GHZ,
192 false, false, true,
193 { 1, 2, 6, 7, 9 } },
194 { EEPROM_HB_OFDM_20_BAND, 6, IEEE80211_BAND_5GHZ,
195 false, false, false,
196 { 36, 64, 100, 36, 64, 100 } },
197 { EEPROM_HB_OFDM_HT40_BAND, 3, IEEE80211_BAND_5GHZ,
198 false, false, true,
199 { 36, 60, 100 } },
200 { EEPROM_LB_OFDM_20_CHANNEL_13, 2, IEEE80211_BAND_2GHZ,
201 false, false, false,
202 { 13, 13 } },
203 { EEPROM_HB_OFDM_20_CHANNEL_140, 2, IEEE80211_BAND_5GHZ,
204 false, false, false,
205 { 140, 140 } },
206 { EEPROM_HB_OFDM_HT40_BAND_1, 2, IEEE80211_BAND_5GHZ,
207 false, false, true,
208 { 132, 44 } },
209};
210
211/****************************************************************************** 139/******************************************************************************
212 * 140 *
213 * EEPROM related functions 141 * EEPROM related functions
214 * 142 *
215******************************************************************************/ 143******************************************************************************/
216 144
217int iwlcore_eeprom_verify_signature(struct iwl_priv *priv) 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 */
151static 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
177static 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
184static int iwl_eeprom_verify_signature(struct iwl_priv *priv)
218{ 185{
219 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;
220 int ret = 0; 187 int ret = 0;
221 188
222 IWL_DEBUG_INFO(priv, "EEPROM signature=0x%08x\n", gp); 189 IWL_DEBUG_EEPROM(priv, "EEPROM signature=0x%08x\n", gp);
223 switch (gp) { 190 switch (gp) {
224 case CSR_EEPROM_GP_BAD_SIG_EEP_GOOD_SIG_OTP: 191 case CSR_EEPROM_GP_BAD_SIG_EEP_GOOD_SIG_OTP:
225 if (priv->nvm_device_type != NVM_DEVICE_TYPE_OTP) { 192 if (priv->nvm_device_type != NVM_DEVICE_TYPE_OTP) {
@@ -246,33 +213,29 @@ int iwlcore_eeprom_verify_signature(struct iwl_priv *priv)
246 } 213 }
247 return ret; 214 return ret;
248} 215}
249EXPORT_SYMBOL(iwlcore_eeprom_verify_signature);
250 216
251static void iwl_set_otp_access(struct iwl_priv *priv, enum iwl_access_mode mode) 217static void iwl_set_otp_access(struct iwl_priv *priv, enum iwl_access_mode mode)
252{ 218{
253 u32 otpgp; 219 iwl_read32(priv, CSR_OTP_GP_REG);
254 220
255 otpgp = iwl_read32(priv, CSR_OTP_GP_REG);
256 if (mode == IWL_OTP_ACCESS_ABSOLUTE) 221 if (mode == IWL_OTP_ACCESS_ABSOLUTE)
257 iwl_clear_bit(priv, CSR_OTP_GP_REG, 222 iwl_clear_bit(priv, CSR_OTP_GP_REG,
258 CSR_OTP_GP_REG_OTP_ACCESS_MODE); 223 CSR_OTP_GP_REG_OTP_ACCESS_MODE);
259 else 224 else
260 iwl_set_bit(priv, CSR_OTP_GP_REG, 225 iwl_set_bit(priv, CSR_OTP_GP_REG,
261 CSR_OTP_GP_REG_OTP_ACCESS_MODE); 226 CSR_OTP_GP_REG_OTP_ACCESS_MODE);
262} 227}
263 228
264static int iwlcore_get_nvm_type(struct iwl_priv *priv) 229static int iwlcore_get_nvm_type(struct iwl_priv *priv, u32 hw_rev)
265{ 230{
266 u32 otpgp; 231 u32 otpgp;
267 int nvm_type; 232 int nvm_type;
268 233
269 /* OTP only valid for CP/PP and after */ 234 /* OTP only valid for CP/PP and after */
270 switch (priv->hw_rev & CSR_HW_REV_TYPE_MSK) { 235 switch (hw_rev & CSR_HW_REV_TYPE_MSK) {
271 case CSR_HW_REV_TYPE_NONE: 236 case CSR_HW_REV_TYPE_NONE:
272 IWL_ERR(priv, "Unknown hardware type\n"); 237 IWL_ERR(priv, "Unknown hardware type\n");
273 return -ENOENT; 238 return -ENOENT;
274 case CSR_HW_REV_TYPE_3945:
275 case CSR_HW_REV_TYPE_4965:
276 case CSR_HW_REV_TYPE_5300: 239 case CSR_HW_REV_TYPE_5300:
277 case CSR_HW_REV_TYPE_5350: 240 case CSR_HW_REV_TYPE_5350:
278 case CSR_HW_REV_TYPE_5100: 241 case CSR_HW_REV_TYPE_5100:
@@ -290,67 +253,20 @@ static int iwlcore_get_nvm_type(struct iwl_priv *priv)
290 return nvm_type; 253 return nvm_type;
291} 254}
292 255
293/*
294 * The device's EEPROM semaphore prevents conflicts between driver and uCode
295 * when accessing the EEPROM; each access is a series of pulses to/from the
296 * EEPROM chip, not a single event, so even reads could conflict if they
297 * weren't arbitrated by the semaphore.
298 */
299int iwlcore_eeprom_acquire_semaphore(struct iwl_priv *priv)
300{
301 u16 count;
302 int ret;
303
304 for (count = 0; count < EEPROM_SEM_RETRY_LIMIT; count++) {
305 /* Request semaphore */
306 iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG,
307 CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM);
308
309 /* See if we got it */
310 ret = iwl_poll_bit(priv, CSR_HW_IF_CONFIG_REG,
311 CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM,
312 CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM,
313 EEPROM_SEM_TIMEOUT);
314 if (ret >= 0) {
315 IWL_DEBUG_IO(priv, "Acquired semaphore after %d tries.\n",
316 count+1);
317 return ret;
318 }
319 }
320
321 return ret;
322}
323EXPORT_SYMBOL(iwlcore_eeprom_acquire_semaphore);
324
325void iwlcore_eeprom_release_semaphore(struct iwl_priv *priv)
326{
327 iwl_clear_bit(priv, CSR_HW_IF_CONFIG_REG,
328 CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM);
329
330}
331EXPORT_SYMBOL(iwlcore_eeprom_release_semaphore);
332
333const u8 *iwlcore_eeprom_query_addr(const struct iwl_priv *priv, size_t offset)
334{
335 BUG_ON(offset >= priv->cfg->eeprom_size);
336 return &priv->eeprom[offset];
337}
338EXPORT_SYMBOL(iwlcore_eeprom_query_addr);
339
340static int iwl_init_otp_access(struct iwl_priv *priv) 256static int iwl_init_otp_access(struct iwl_priv *priv)
341{ 257{
342 int ret; 258 int ret;
343 259
344 /* Enable 40MHz radio clock */ 260 /* Enable 40MHz radio clock */
345 _iwl_write32(priv, CSR_GP_CNTRL, 261 iwl_write32(priv, CSR_GP_CNTRL,
346 _iwl_read32(priv, CSR_GP_CNTRL) | 262 iwl_read32(priv, CSR_GP_CNTRL) |
347 CSR_GP_CNTRL_REG_FLAG_INIT_DONE); 263 CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
348 264
349 /* wait for clock to be ready */ 265 /* wait for clock to be ready */
350 ret = iwl_poll_bit(priv, CSR_GP_CNTRL, 266 ret = iwl_poll_bit(priv, CSR_GP_CNTRL,
351 CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 267 CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY,
352 CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 268 CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY,
353 25000); 269 25000);
354 if (ret < 0) 270 if (ret < 0)
355 IWL_ERR(priv, "Time out access OTP\n"); 271 IWL_ERR(priv, "Time out access OTP\n");
356 else { 272 else {
@@ -364,7 +280,7 @@ static int iwl_init_otp_access(struct iwl_priv *priv)
364 * CSR auto clock gate disable bit - 280 * CSR auto clock gate disable bit -
365 * this is only applicable for HW with OTP shadow RAM 281 * this is only applicable for HW with OTP shadow RAM
366 */ 282 */
367 if (priv->cfg->shadow_ram_support) 283 if (priv->cfg->base_params->shadow_ram_support)
368 iwl_set_bit(priv, CSR_DBG_LINK_PWR_MGMT_REG, 284 iwl_set_bit(priv, CSR_DBG_LINK_PWR_MGMT_REG,
369 CSR_RESET_LINK_PWR_MGMT_DISABLED); 285 CSR_RESET_LINK_PWR_MGMT_DISABLED);
370 } 286 }
@@ -377,17 +293,17 @@ static int iwl_read_otp_word(struct iwl_priv *priv, u16 addr, __le16 *eeprom_dat
377 u32 r; 293 u32 r;
378 u32 otpgp; 294 u32 otpgp;
379 295
380 _iwl_write32(priv, CSR_EEPROM_REG, 296 iwl_write32(priv, CSR_EEPROM_REG,
381 CSR_EEPROM_REG_MSK_ADDR & (addr << 1)); 297 CSR_EEPROM_REG_MSK_ADDR & (addr << 1));
382 ret = iwl_poll_bit(priv, CSR_EEPROM_REG, 298 ret = iwl_poll_bit(priv, CSR_EEPROM_REG,
383 CSR_EEPROM_REG_READ_VALID_MSK, 299 CSR_EEPROM_REG_READ_VALID_MSK,
384 CSR_EEPROM_REG_READ_VALID_MSK, 300 CSR_EEPROM_REG_READ_VALID_MSK,
385 IWL_EEPROM_ACCESS_TIMEOUT); 301 IWL_EEPROM_ACCESS_TIMEOUT);
386 if (ret < 0) { 302 if (ret < 0) {
387 IWL_ERR(priv, "Time out reading OTP[%d]\n", addr); 303 IWL_ERR(priv, "Time out reading OTP[%d]\n", addr);
388 return ret; 304 return ret;
389 } 305 }
390 r = _iwl_read_direct32(priv, CSR_EEPROM_REG); 306 r = iwl_read32(priv, CSR_EEPROM_REG);
391 /* check for ECC errors: */ 307 /* check for ECC errors: */
392 otpgp = iwl_read32(priv, CSR_OTP_GP_REG); 308 otpgp = iwl_read32(priv, CSR_OTP_GP_REG);
393 if (otpgp & CSR_OTP_GP_REG_ECC_UNCORR_STATUS_MSK) { 309 if (otpgp & CSR_OTP_GP_REG_ECC_UNCORR_STATUS_MSK) {
@@ -467,7 +383,7 @@ static int iwl_find_otp_image(struct iwl_priv *priv,
467 */ 383 */
468 valid_addr = next_link_addr; 384 valid_addr = next_link_addr;
469 next_link_addr = le16_to_cpu(link_value) * sizeof(u16); 385 next_link_addr = le16_to_cpu(link_value) * sizeof(u16);
470 IWL_DEBUG_INFO(priv, "OTP blocks %d addr 0x%x\n", 386 IWL_DEBUG_EEPROM(priv, "OTP blocks %d addr 0x%x\n",
471 usedblocks, next_link_addr); 387 usedblocks, next_link_addr);
472 if (iwl_read_otp_word(priv, next_link_addr, &link_value)) 388 if (iwl_read_otp_word(priv, next_link_addr, &link_value))
473 return -EINVAL; 389 return -EINVAL;
@@ -484,13 +400,25 @@ static int iwl_find_otp_image(struct iwl_priv *priv,
484 } 400 }
485 /* more in the link list, continue */ 401 /* more in the link list, continue */
486 usedblocks++; 402 usedblocks++;
487 } while (usedblocks <= priv->cfg->max_ll_items); 403 } while (usedblocks <= priv->cfg->base_params->max_ll_items);
488 404
489 /* OTP has no valid blocks */ 405 /* OTP has no valid blocks */
490 IWL_DEBUG_INFO(priv, "OTP has no valid blocks\n"); 406 IWL_DEBUG_EEPROM(priv, "OTP has no valid blocks\n");
491 return -EINVAL; 407 return -EINVAL;
492} 408}
493 409
410const u8 *iwl_eeprom_query_addr(const struct iwl_priv *priv, size_t offset)
411{
412 return priv->cfg->ops->lib->eeprom_ops.query_addr(priv, offset);
413}
414
415u16 iwl_eeprom_query16(const struct iwl_priv *priv, size_t offset)
416{
417 if (!priv->eeprom)
418 return 0;
419 return (u16)priv->eeprom[offset] | ((u16)priv->eeprom[offset + 1] << 8);
420}
421
494/** 422/**
495 * iwl_eeprom_init - read EEPROM contents 423 * iwl_eeprom_init - read EEPROM contents
496 * 424 *
@@ -498,7 +426,7 @@ static int iwl_find_otp_image(struct iwl_priv *priv,
498 * 426 *
499 * NOTE: This routine uses the non-debug IO access functions. 427 * NOTE: This routine uses the non-debug IO access functions.
500 */ 428 */
501int iwl_eeprom_init(struct iwl_priv *priv) 429int iwl_eeprom_init(struct iwl_priv *priv, u32 hw_rev)
502{ 430{
503 __le16 *e; 431 __le16 *e;
504 u32 gp = iwl_read32(priv, CSR_EEPROM_GP); 432 u32 gp = iwl_read32(priv, CSR_EEPROM_GP);
@@ -508,12 +436,12 @@ int iwl_eeprom_init(struct iwl_priv *priv)
508 u16 validblockaddr = 0; 436 u16 validblockaddr = 0;
509 u16 cache_addr = 0; 437 u16 cache_addr = 0;
510 438
511 priv->nvm_device_type = iwlcore_get_nvm_type(priv); 439 priv->nvm_device_type = iwlcore_get_nvm_type(priv, hw_rev);
512 if (priv->nvm_device_type == -ENOENT) 440 if (priv->nvm_device_type == -ENOENT)
513 return -ENOENT; 441 return -ENOENT;
514 /* allocate eeprom */ 442 /* allocate eeprom */
515 IWL_DEBUG_INFO(priv, "NVM size = %d\n", priv->cfg->eeprom_size); 443 sz = priv->cfg->base_params->eeprom_size;
516 sz = priv->cfg->eeprom_size; 444 IWL_DEBUG_EEPROM(priv, "NVM size = %d\n", sz);
517 priv->eeprom = kzalloc(sz, GFP_KERNEL); 445 priv->eeprom = kzalloc(sz, GFP_KERNEL);
518 if (!priv->eeprom) { 446 if (!priv->eeprom) {
519 ret = -ENOMEM; 447 ret = -ENOMEM;
@@ -523,7 +451,7 @@ int iwl_eeprom_init(struct iwl_priv *priv)
523 451
524 priv->cfg->ops->lib->apm_ops.init(priv); 452 priv->cfg->ops->lib->apm_ops.init(priv);
525 453
526 ret = priv->cfg->ops->lib->eeprom_ops.verify_signature(priv); 454 ret = iwl_eeprom_verify_signature(priv);
527 if (ret < 0) { 455 if (ret < 0) {
528 IWL_ERR(priv, "EEPROM not found, EEPROM_GP=0x%08x\n", gp); 456 IWL_ERR(priv, "EEPROM not found, EEPROM_GP=0x%08x\n", gp);
529 ret = -ENOENT; 457 ret = -ENOENT;
@@ -531,7 +459,7 @@ int iwl_eeprom_init(struct iwl_priv *priv)
531 } 459 }
532 460
533 /* Make sure driver (instead of uCode) is allowed to read EEPROM */ 461 /* Make sure driver (instead of uCode) is allowed to read EEPROM */
534 ret = priv->cfg->ops->lib->eeprom_ops.acquire_semaphore(priv); 462 ret = iwl_eeprom_acquire_semaphore(priv);
535 if (ret < 0) { 463 if (ret < 0) {
536 IWL_ERR(priv, "Failed to acquire EEPROM semaphore.\n"); 464 IWL_ERR(priv, "Failed to acquire EEPROM semaphore.\n");
537 ret = -ENOENT; 465 ret = -ENOENT;
@@ -546,15 +474,15 @@ int iwl_eeprom_init(struct iwl_priv *priv)
546 ret = -ENOENT; 474 ret = -ENOENT;
547 goto done; 475 goto done;
548 } 476 }
549 _iwl_write32(priv, CSR_EEPROM_GP, 477 iwl_write32(priv, CSR_EEPROM_GP,
550 iwl_read32(priv, CSR_EEPROM_GP) & 478 iwl_read32(priv, CSR_EEPROM_GP) &
551 ~CSR_EEPROM_GP_IF_OWNER_MSK); 479 ~CSR_EEPROM_GP_IF_OWNER_MSK);
552 480
553 iwl_set_bit(priv, CSR_OTP_GP_REG, 481 iwl_set_bit(priv, CSR_OTP_GP_REG,
554 CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK | 482 CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK |
555 CSR_OTP_GP_REG_ECC_UNCORR_STATUS_MSK); 483 CSR_OTP_GP_REG_ECC_UNCORR_STATUS_MSK);
556 /* traversing the linked list if no shadow ram supported */ 484 /* traversing the linked list if no shadow ram supported */
557 if (!priv->cfg->shadow_ram_support) { 485 if (!priv->cfg->base_params->shadow_ram_support) {
558 if (iwl_find_otp_image(priv, &validblockaddr)) { 486 if (iwl_find_otp_image(priv, &validblockaddr)) {
559 ret = -ENOENT; 487 ret = -ENOENT;
560 goto done; 488 goto done;
@@ -575,8 +503,8 @@ int iwl_eeprom_init(struct iwl_priv *priv)
575 for (addr = 0; addr < sz; addr += sizeof(u16)) { 503 for (addr = 0; addr < sz; addr += sizeof(u16)) {
576 u32 r; 504 u32 r;
577 505
578 _iwl_write32(priv, CSR_EEPROM_REG, 506 iwl_write32(priv, CSR_EEPROM_REG,
579 CSR_EEPROM_REG_MSK_ADDR & (addr << 1)); 507 CSR_EEPROM_REG_MSK_ADDR & (addr << 1));
580 508
581 ret = iwl_poll_bit(priv, CSR_EEPROM_REG, 509 ret = iwl_poll_bit(priv, CSR_EEPROM_REG,
582 CSR_EEPROM_REG_READ_VALID_MSK, 510 CSR_EEPROM_REG_READ_VALID_MSK,
@@ -586,83 +514,34 @@ int iwl_eeprom_init(struct iwl_priv *priv)
586 IWL_ERR(priv, "Time out reading EEPROM[%d]\n", addr); 514 IWL_ERR(priv, "Time out reading EEPROM[%d]\n", addr);
587 goto done; 515 goto done;
588 } 516 }
589 r = _iwl_read_direct32(priv, CSR_EEPROM_REG); 517 r = iwl_read32(priv, CSR_EEPROM_REG);
590 e[addr / 2] = cpu_to_le16(r >> 16); 518 e[addr / 2] = cpu_to_le16(r >> 16);
591 } 519 }
592 } 520 }
593 521
594 IWL_DEBUG_INFO(priv, "NVM Type: %s, version: 0x%x\n", 522 IWL_DEBUG_EEPROM(priv, "NVM Type: %s, version: 0x%x\n",
595 (priv->nvm_device_type == NVM_DEVICE_TYPE_OTP) 523 (priv->nvm_device_type == NVM_DEVICE_TYPE_OTP)
596 ? "OTP" : "EEPROM", 524 ? "OTP" : "EEPROM",
597 iwl_eeprom_query16(priv, EEPROM_VERSION)); 525 iwl_eeprom_query16(priv, EEPROM_VERSION));
598 526
599 ret = 0; 527 ret = 0;
600done: 528done:
601 priv->cfg->ops->lib->eeprom_ops.release_semaphore(priv); 529 iwl_eeprom_release_semaphore(priv);
602 530
603err: 531err:
604 if (ret) 532 if (ret)
605 iwl_eeprom_free(priv); 533 iwl_eeprom_free(priv);
606 /* Reset chip to save power until we load uCode during "up". */ 534 /* Reset chip to save power until we load uCode during "up". */
607 priv->cfg->ops->lib->apm_ops.stop(priv); 535 iwl_apm_stop(priv);
608alloc_err: 536alloc_err:
609 return ret; 537 return ret;
610} 538}
611EXPORT_SYMBOL(iwl_eeprom_init);
612 539
613void iwl_eeprom_free(struct iwl_priv *priv) 540void iwl_eeprom_free(struct iwl_priv *priv)
614{ 541{
615 kfree(priv->eeprom); 542 kfree(priv->eeprom);
616 priv->eeprom = NULL; 543 priv->eeprom = NULL;
617} 544}
618EXPORT_SYMBOL(iwl_eeprom_free);
619
620int iwl_eeprom_check_version(struct iwl_priv *priv)
621{
622 u16 eeprom_ver;
623 u16 calib_ver;
624
625 eeprom_ver = iwl_eeprom_query16(priv, EEPROM_VERSION);
626 calib_ver = priv->cfg->ops->lib->eeprom_ops.calib_version(priv);
627
628 if (eeprom_ver < priv->cfg->eeprom_ver ||
629 calib_ver < priv->cfg->eeprom_calib_ver)
630 goto err;
631
632 IWL_INFO(priv, "device EEPROM VER=0x%x, CALIB=0x%x\n",
633 eeprom_ver, calib_ver);
634
635 return 0;
636err:
637 IWL_ERR(priv, "Unsupported (too old) EEPROM VER=0x%x < 0x%x CALIB=0x%x < 0x%x\n",
638 eeprom_ver, priv->cfg->eeprom_ver,
639 calib_ver, priv->cfg->eeprom_calib_ver);
640 return -EINVAL;
641
642}
643EXPORT_SYMBOL(iwl_eeprom_check_version);
644
645const u8 *iwl_eeprom_query_addr(const struct iwl_priv *priv, size_t offset)
646{
647 return priv->cfg->ops->lib->eeprom_ops.query_addr(priv, offset);
648}
649EXPORT_SYMBOL(iwl_eeprom_query_addr);
650
651u16 iwl_eeprom_query16(const struct iwl_priv *priv, size_t offset)
652{
653 if (!priv->eeprom)
654 return 0;
655 return (u16)priv->eeprom[offset] | ((u16)priv->eeprom[offset + 1] << 8);
656}
657EXPORT_SYMBOL(iwl_eeprom_query16);
658
659void iwl_eeprom_get_mac(const struct iwl_priv *priv, u8 *mac)
660{
661 const u8 *addr = priv->cfg->ops->lib->eeprom_ops.query_addr(priv,
662 EEPROM_MAC_ADDRESS);
663 memcpy(mac, addr, ETH_ALEN);
664}
665EXPORT_SYMBOL(iwl_eeprom_get_mac);
666 545
667static void iwl_init_band_reference(const struct iwl_priv *priv, 546static void iwl_init_band_reference(const struct iwl_priv *priv,
668 int eep_band, int *eeprom_ch_count, 547 int eep_band, int *eeprom_ch_count,
@@ -722,7 +601,6 @@ static void iwl_init_band_reference(const struct iwl_priv *priv,
722 601
723#define CHECK_AND_PRINT(x) ((eeprom_ch->flags & EEPROM_CHANNEL_##x) \ 602#define CHECK_AND_PRINT(x) ((eeprom_ch->flags & EEPROM_CHANNEL_##x) \
724 ? # x " " : "") 603 ? # x " " : "")
725
726/** 604/**
727 * iwl_mod_ht40_chan_info - Copy ht40 channel info into driver's priv. 605 * iwl_mod_ht40_chan_info - Copy ht40 channel info into driver's priv.
728 * 606 *
@@ -741,7 +619,7 @@ static int iwl_mod_ht40_chan_info(struct iwl_priv *priv,
741 if (!is_channel_valid(ch_info)) 619 if (!is_channel_valid(ch_info))
742 return -1; 620 return -1;
743 621
744 IWL_DEBUG_INFO(priv, "HT40 Ch. %d [%sGHz] %s%s%s%s%s(0x%02x %ddBm):" 622 IWL_DEBUG_EEPROM(priv, "HT40 Ch. %d [%sGHz] %s%s%s%s%s(0x%02x %ddBm):"
745 " Ad-Hoc %ssupported\n", 623 " Ad-Hoc %ssupported\n",
746 ch_info->channel, 624 ch_info->channel,
747 is_channel_a_band(ch_info) ? 625 is_channel_a_band(ch_info) ?
@@ -766,205 +644,6 @@ static int iwl_mod_ht40_chan_info(struct iwl_priv *priv,
766 return 0; 644 return 0;
767} 645}
768 646
769/**
770 * iwl_get_max_txpower_avg - get the highest tx power from all chains.
771 * find the highest tx power from all chains for the channel
772 */
773static s8 iwl_get_max_txpower_avg(struct iwl_priv *priv,
774 struct iwl_eeprom_enhanced_txpwr *enhanced_txpower,
775 int element, s8 *max_txpower_in_half_dbm)
776{
777 s8 max_txpower_avg = 0; /* (dBm) */
778
779 IWL_DEBUG_INFO(priv, "%d - "
780 "chain_a: %d dB chain_b: %d dB "
781 "chain_c: %d dB mimo2: %d dB mimo3: %d dB\n",
782 element,
783 enhanced_txpower[element].chain_a_max >> 1,
784 enhanced_txpower[element].chain_b_max >> 1,
785 enhanced_txpower[element].chain_c_max >> 1,
786 enhanced_txpower[element].mimo2_max >> 1,
787 enhanced_txpower[element].mimo3_max >> 1);
788 /* Take the highest tx power from any valid chains */
789 if ((priv->cfg->valid_tx_ant & ANT_A) &&
790 (enhanced_txpower[element].chain_a_max > max_txpower_avg))
791 max_txpower_avg = enhanced_txpower[element].chain_a_max;
792 if ((priv->cfg->valid_tx_ant & ANT_B) &&
793 (enhanced_txpower[element].chain_b_max > max_txpower_avg))
794 max_txpower_avg = enhanced_txpower[element].chain_b_max;
795 if ((priv->cfg->valid_tx_ant & ANT_C) &&
796 (enhanced_txpower[element].chain_c_max > max_txpower_avg))
797 max_txpower_avg = enhanced_txpower[element].chain_c_max;
798 if (((priv->cfg->valid_tx_ant == ANT_AB) |
799 (priv->cfg->valid_tx_ant == ANT_BC) |
800 (priv->cfg->valid_tx_ant == ANT_AC)) &&
801 (enhanced_txpower[element].mimo2_max > max_txpower_avg))
802 max_txpower_avg = enhanced_txpower[element].mimo2_max;
803 if ((priv->cfg->valid_tx_ant == ANT_ABC) &&
804 (enhanced_txpower[element].mimo3_max > max_txpower_avg))
805 max_txpower_avg = enhanced_txpower[element].mimo3_max;
806
807 /*
808 * max. tx power in EEPROM is in 1/2 dBm format
809 * convert from 1/2 dBm to dBm (round-up convert)
810 * but we also do not want to loss 1/2 dBm resolution which
811 * will impact performance
812 */
813 *max_txpower_in_half_dbm = max_txpower_avg;
814 return (max_txpower_avg & 0x01) + (max_txpower_avg >> 1);
815}
816
817/**
818 * iwl_update_common_txpower: update channel tx power
819 * update tx power per band based on EEPROM enhanced tx power info.
820 */
821static s8 iwl_update_common_txpower(struct iwl_priv *priv,
822 struct iwl_eeprom_enhanced_txpwr *enhanced_txpower,
823 int section, int element, s8 *max_txpower_in_half_dbm)
824{
825 struct iwl_channel_info *ch_info;
826 int ch;
827 bool is_ht40 = false;
828 s8 max_txpower_avg; /* (dBm) */
829
830 /* it is common section, contain all type (Legacy, HT and HT40)
831 * based on the element in the section to determine
832 * is it HT 40 or not
833 */
834 if (element == EEPROM_TXPOWER_COMMON_HT40_INDEX)
835 is_ht40 = true;
836 max_txpower_avg =
837 iwl_get_max_txpower_avg(priv, enhanced_txpower,
838 element, max_txpower_in_half_dbm);
839
840 ch_info = priv->channel_info;
841
842 for (ch = 0; ch < priv->channel_count; ch++) {
843 /* find matching band and update tx power if needed */
844 if ((ch_info->band == enhinfo[section].band) &&
845 (ch_info->max_power_avg < max_txpower_avg) &&
846 (!is_ht40)) {
847 /* Update regulatory-based run-time data */
848 ch_info->max_power_avg = ch_info->curr_txpow =
849 max_txpower_avg;
850 ch_info->scan_power = max_txpower_avg;
851 }
852 if ((ch_info->band == enhinfo[section].band) && is_ht40 &&
853 (ch_info->ht40_max_power_avg < max_txpower_avg)) {
854 /* Update regulatory-based run-time data */
855 ch_info->ht40_max_power_avg = max_txpower_avg;
856 }
857 ch_info++;
858 }
859 return max_txpower_avg;
860}
861
862/**
863 * iwl_update_channel_txpower: update channel tx power
864 * update channel tx power based on EEPROM enhanced tx power info.
865 */
866static s8 iwl_update_channel_txpower(struct iwl_priv *priv,
867 struct iwl_eeprom_enhanced_txpwr *enhanced_txpower,
868 int section, int element, s8 *max_txpower_in_half_dbm)
869{
870 struct iwl_channel_info *ch_info;
871 int ch;
872 u8 channel;
873 s8 max_txpower_avg; /* (dBm) */
874
875 channel = enhinfo[section].iwl_eeprom_section_channel[element];
876 max_txpower_avg =
877 iwl_get_max_txpower_avg(priv, enhanced_txpower,
878 element, max_txpower_in_half_dbm);
879
880 ch_info = priv->channel_info;
881 for (ch = 0; ch < priv->channel_count; ch++) {
882 /* find matching channel and update tx power if needed */
883 if (ch_info->channel == channel) {
884 if ((ch_info->max_power_avg < max_txpower_avg) &&
885 (!enhinfo[section].is_ht40)) {
886 /* Update regulatory-based run-time data */
887 ch_info->max_power_avg = max_txpower_avg;
888 ch_info->curr_txpow = max_txpower_avg;
889 ch_info->scan_power = max_txpower_avg;
890 }
891 if ((enhinfo[section].is_ht40) &&
892 (ch_info->ht40_max_power_avg < max_txpower_avg)) {
893 /* Update regulatory-based run-time data */
894 ch_info->ht40_max_power_avg = max_txpower_avg;
895 }
896 break;
897 }
898 ch_info++;
899 }
900 return max_txpower_avg;
901}
902
903/**
904 * iwlcore_eeprom_enhanced_txpower: process enhanced tx power info
905 */
906void iwlcore_eeprom_enhanced_txpower(struct iwl_priv *priv)
907{
908 int eeprom_section_count = 0;
909 int section, element;
910 struct iwl_eeprom_enhanced_txpwr *enhanced_txpower;
911 u32 offset;
912 s8 max_txpower_avg; /* (dBm) */
913 s8 max_txpower_in_half_dbm; /* (half-dBm) */
914
915 /* Loop through all the sections
916 * adjust bands and channel's max tx power
917 * Set the tx_power_user_lmt to the highest power
918 * supported by any channels and chains
919 */
920 for (section = 0; section < ARRAY_SIZE(enhinfo); section++) {
921 eeprom_section_count = enhinfo[section].count;
922 offset = enhinfo[section].offset;
923 enhanced_txpower = (struct iwl_eeprom_enhanced_txpwr *)
924 iwl_eeprom_query_addr(priv, offset);
925
926 /*
927 * check for valid entry -
928 * different version of EEPROM might contain different set
929 * of enhanced tx power table
930 * always check for valid entry before process
931 * the information
932 */
933 if (!enhanced_txpower->common || enhanced_txpower->reserved)
934 continue;
935
936 for (element = 0; element < eeprom_section_count; element++) {
937 if (enhinfo[section].is_common)
938 max_txpower_avg =
939 iwl_update_common_txpower(priv,
940 enhanced_txpower, section,
941 element,
942 &max_txpower_in_half_dbm);
943 else
944 max_txpower_avg =
945 iwl_update_channel_txpower(priv,
946 enhanced_txpower, section,
947 element,
948 &max_txpower_in_half_dbm);
949
950 /* Update the tx_power_user_lmt to the highest power
951 * supported by any channel */
952 if (max_txpower_avg > priv->tx_power_user_lmt)
953 priv->tx_power_user_lmt = max_txpower_avg;
954
955 /*
956 * Update the tx_power_lmt_in_half_dbm to
957 * the highest power supported by any channel
958 */
959 if (max_txpower_in_half_dbm >
960 priv->tx_power_lmt_in_half_dbm)
961 priv->tx_power_lmt_in_half_dbm =
962 max_txpower_in_half_dbm;
963 }
964 }
965}
966EXPORT_SYMBOL(iwlcore_eeprom_enhanced_txpower);
967
968#define CHECK_AND_PRINT_I(x) ((eeprom_ch_info[ch].flags & EEPROM_CHANNEL_##x) \ 647#define CHECK_AND_PRINT_I(x) ((eeprom_ch_info[ch].flags & EEPROM_CHANNEL_##x) \
969 ? # x " " : "") 648 ? # x " " : "")
970 649
@@ -980,11 +659,11 @@ int iwl_init_channel_map(struct iwl_priv *priv)
980 struct iwl_channel_info *ch_info; 659 struct iwl_channel_info *ch_info;
981 660
982 if (priv->channel_count) { 661 if (priv->channel_count) {
983 IWL_DEBUG_INFO(priv, "Channel map already initialized.\n"); 662 IWL_DEBUG_EEPROM(priv, "Channel map already initialized.\n");
984 return 0; 663 return 0;
985 } 664 }
986 665
987 IWL_DEBUG_INFO(priv, "Initializing regulatory info from EEPROM\n"); 666 IWL_DEBUG_EEPROM(priv, "Initializing regulatory info from EEPROM\n");
988 667
989 priv->channel_count = 668 priv->channel_count =
990 ARRAY_SIZE(iwl_eeprom_band_1) + 669 ARRAY_SIZE(iwl_eeprom_band_1) +
@@ -993,7 +672,8 @@ int iwl_init_channel_map(struct iwl_priv *priv)
993 ARRAY_SIZE(iwl_eeprom_band_4) + 672 ARRAY_SIZE(iwl_eeprom_band_4) +
994 ARRAY_SIZE(iwl_eeprom_band_5); 673 ARRAY_SIZE(iwl_eeprom_band_5);
995 674
996 IWL_DEBUG_INFO(priv, "Parsing data for %d channels.\n", priv->channel_count); 675 IWL_DEBUG_EEPROM(priv, "Parsing data for %d channels.\n",
676 priv->channel_count);
997 677
998 priv->channel_info = kzalloc(sizeof(struct iwl_channel_info) * 678 priv->channel_info = kzalloc(sizeof(struct iwl_channel_info) *
999 priv->channel_count, GFP_KERNEL); 679 priv->channel_count, GFP_KERNEL);
@@ -1032,7 +712,8 @@ int iwl_init_channel_map(struct iwl_priv *priv)
1032 IEEE80211_CHAN_NO_HT40; 712 IEEE80211_CHAN_NO_HT40;
1033 713
1034 if (!(is_channel_valid(ch_info))) { 714 if (!(is_channel_valid(ch_info))) {
1035 IWL_DEBUG_INFO(priv, "Ch. %d Flags %x [%sGHz] - " 715 IWL_DEBUG_EEPROM(priv,
716 "Ch. %d Flags %x [%sGHz] - "
1036 "No traffic\n", 717 "No traffic\n",
1037 ch_info->channel, 718 ch_info->channel,
1038 ch_info->flags, 719 ch_info->flags,
@@ -1048,7 +729,8 @@ int iwl_init_channel_map(struct iwl_priv *priv)
1048 ch_info->scan_power = eeprom_ch_info[ch].max_power_avg; 729 ch_info->scan_power = eeprom_ch_info[ch].max_power_avg;
1049 ch_info->min_power = 0; 730 ch_info->min_power = 0;
1050 731
1051 IWL_DEBUG_INFO(priv, "Ch. %d [%sGHz] %s%s%s%s%s%s(0x%02x %ddBm):" 732 IWL_DEBUG_EEPROM(priv, "Ch. %d [%sGHz] "
733 "%s%s%s%s%s%s(0x%02x %ddBm):"
1052 " Ad-Hoc %ssupported\n", 734 " Ad-Hoc %ssupported\n",
1053 ch_info->channel, 735 ch_info->channel,
1054 is_channel_a_band(ch_info) ? 736 is_channel_a_band(ch_info) ?
@@ -1067,13 +749,6 @@ int iwl_init_channel_map(struct iwl_priv *priv)
1067 flags & EEPROM_CHANNEL_RADAR)) 749 flags & EEPROM_CHANNEL_RADAR))
1068 ? "" : "not "); 750 ? "" : "not ");
1069 751
1070 /* Set the tx_power_user_lmt to the highest power
1071 * supported by any channel */
1072 if (eeprom_ch_info[ch].max_power_avg >
1073 priv->tx_power_user_lmt)
1074 priv->tx_power_user_lmt =
1075 eeprom_ch_info[ch].max_power_avg;
1076
1077 ch_info++; 752 ch_info++;
1078 } 753 }
1079 } 754 }
@@ -1122,7 +797,6 @@ int iwl_init_channel_map(struct iwl_priv *priv)
1122 797
1123 return 0; 798 return 0;
1124} 799}
1125EXPORT_SYMBOL(iwl_init_channel_map);
1126 800
1127/* 801/*
1128 * iwl_free_channel_map - undo allocations in iwl_init_channel_map 802 * iwl_free_channel_map - undo allocations in iwl_init_channel_map
@@ -1132,7 +806,6 @@ void iwl_free_channel_map(struct iwl_priv *priv)
1132 kfree(priv->channel_info); 806 kfree(priv->channel_info);
1133 priv->channel_count = 0; 807 priv->channel_count = 0;
1134} 808}
1135EXPORT_SYMBOL(iwl_free_channel_map);
1136 809
1137/** 810/**
1138 * iwl_get_channel_info - Find driver's private channel info 811 * iwl_get_channel_info - Find driver's private channel info
@@ -1161,5 +834,3 @@ const struct iwl_channel_info *iwl_get_channel_info(const struct iwl_priv *priv,
1161 834
1162 return NULL; 835 return NULL;
1163} 836}
1164EXPORT_SYMBOL(iwl_get_channel_info);
1165