aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-1000.c4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-6000.c20
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.h4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-dev.h11
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-eeprom.c185
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-eeprom.h10
6 files changed, 191 insertions, 43 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c
index 191718a0c545..9bb6a287eaee 100644
--- a/drivers/net/wireless/iwlwifi/iwl-1000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-1000.c
@@ -149,12 +149,14 @@ struct iwl_cfg iwl1000_bgn_cfg = {
149 .ucode_api_min = IWL1000_UCODE_API_MIN, 149 .ucode_api_min = IWL1000_UCODE_API_MIN,
150 .sku = IWL_SKU_G|IWL_SKU_N, 150 .sku = IWL_SKU_G|IWL_SKU_N,
151 .ops = &iwl1000_ops, 151 .ops = &iwl1000_ops,
152 .eeprom_size = IWL_5000_EEPROM_IMG_SIZE, 152 .eeprom_size = OTP_LOW_IMAGE_SIZE,
153 .eeprom_ver = EEPROM_5000_EEPROM_VERSION, 153 .eeprom_ver = EEPROM_5000_EEPROM_VERSION,
154 .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, 154 .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
155 .mod_params = &iwl50_mod_params, 155 .mod_params = &iwl50_mod_params,
156 .valid_tx_ant = ANT_A, 156 .valid_tx_ant = ANT_A,
157 .valid_rx_ant = ANT_AB, 157 .valid_rx_ant = ANT_AB,
158 .need_pll_cfg = true, 158 .need_pll_cfg = true,
159 .max_ll_items = OTP_MAX_LL_ITEMS_1000,
160 .shadow_ram_support = false,
159}; 161};
160 162
diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c
index c3ec6c20cc94..0b731fd5ad1c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-6000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-6000.c
@@ -161,7 +161,7 @@ struct iwl_cfg iwl6000h_2agn_cfg = {
161 .ucode_api_min = IWL6000_UCODE_API_MIN, 161 .ucode_api_min = IWL6000_UCODE_API_MIN,
162 .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N, 162 .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
163 .ops = &iwl6000_ops, 163 .ops = &iwl6000_ops,
164 .eeprom_size = IWL_5000_EEPROM_IMG_SIZE, 164 .eeprom_size = OTP_LOW_IMAGE_SIZE,
165 .eeprom_ver = EEPROM_5000_EEPROM_VERSION, 165 .eeprom_ver = EEPROM_5000_EEPROM_VERSION,
166 .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, 166 .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
167 .mod_params = &iwl50_mod_params, 167 .mod_params = &iwl50_mod_params,
@@ -169,6 +169,8 @@ struct iwl_cfg iwl6000h_2agn_cfg = {
169 .valid_rx_ant = ANT_AB, 169 .valid_rx_ant = ANT_AB,
170 .need_pll_cfg = false, 170 .need_pll_cfg = false,
171 .pa_type = IWL_PA_HYBRID, 171 .pa_type = IWL_PA_HYBRID,
172 .max_ll_items = OTP_MAX_LL_ITEMS_6x00,
173 .shadow_ram_support = true,
172}; 174};
173 175
174/* 176/*
@@ -181,7 +183,7 @@ struct iwl_cfg iwl6000i_2agn_cfg = {
181 .ucode_api_min = IWL6000_UCODE_API_MIN, 183 .ucode_api_min = IWL6000_UCODE_API_MIN,
182 .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N, 184 .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
183 .ops = &iwl6000_ops, 185 .ops = &iwl6000_ops,
184 .eeprom_size = IWL_5000_EEPROM_IMG_SIZE, 186 .eeprom_size = OTP_LOW_IMAGE_SIZE,
185 .eeprom_ver = EEPROM_5000_EEPROM_VERSION, 187 .eeprom_ver = EEPROM_5000_EEPROM_VERSION,
186 .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, 188 .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
187 .mod_params = &iwl50_mod_params, 189 .mod_params = &iwl50_mod_params,
@@ -189,6 +191,8 @@ struct iwl_cfg iwl6000i_2agn_cfg = {
189 .valid_rx_ant = ANT_BC, 191 .valid_rx_ant = ANT_BC,
190 .need_pll_cfg = false, 192 .need_pll_cfg = false,
191 .pa_type = IWL_PA_INTERNAL, 193 .pa_type = IWL_PA_INTERNAL,
194 .max_ll_items = OTP_MAX_LL_ITEMS_6x00,
195 .shadow_ram_support = true,
192}; 196};
193 197
194struct iwl_cfg iwl6050_2agn_cfg = { 198struct iwl_cfg iwl6050_2agn_cfg = {
@@ -198,7 +202,7 @@ struct iwl_cfg iwl6050_2agn_cfg = {
198 .ucode_api_min = IWL6050_UCODE_API_MIN, 202 .ucode_api_min = IWL6050_UCODE_API_MIN,
199 .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N, 203 .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
200 .ops = &iwl6000_ops, 204 .ops = &iwl6000_ops,
201 .eeprom_size = IWL_5000_EEPROM_IMG_SIZE, 205 .eeprom_size = OTP_LOW_IMAGE_SIZE,
202 .eeprom_ver = EEPROM_5000_EEPROM_VERSION, 206 .eeprom_ver = EEPROM_5000_EEPROM_VERSION,
203 .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, 207 .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
204 .mod_params = &iwl50_mod_params, 208 .mod_params = &iwl50_mod_params,
@@ -206,6 +210,8 @@ struct iwl_cfg iwl6050_2agn_cfg = {
206 .valid_rx_ant = ANT_AB, 210 .valid_rx_ant = ANT_AB,
207 .need_pll_cfg = false, 211 .need_pll_cfg = false,
208 .pa_type = IWL_PA_SYSTEM, 212 .pa_type = IWL_PA_SYSTEM,
213 .max_ll_items = OTP_MAX_LL_ITEMS_6x00,
214 .shadow_ram_support = true,
209}; 215};
210 216
211struct iwl_cfg iwl6000_3agn_cfg = { 217struct iwl_cfg iwl6000_3agn_cfg = {
@@ -215,7 +221,7 @@ struct iwl_cfg iwl6000_3agn_cfg = {
215 .ucode_api_min = IWL6000_UCODE_API_MIN, 221 .ucode_api_min = IWL6000_UCODE_API_MIN,
216 .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N, 222 .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
217 .ops = &iwl6000_ops, 223 .ops = &iwl6000_ops,
218 .eeprom_size = IWL_5000_EEPROM_IMG_SIZE, 224 .eeprom_size = OTP_LOW_IMAGE_SIZE,
219 .eeprom_ver = EEPROM_5000_EEPROM_VERSION, 225 .eeprom_ver = EEPROM_5000_EEPROM_VERSION,
220 .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, 226 .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
221 .mod_params = &iwl50_mod_params, 227 .mod_params = &iwl50_mod_params,
@@ -223,6 +229,8 @@ struct iwl_cfg iwl6000_3agn_cfg = {
223 .valid_rx_ant = ANT_ABC, 229 .valid_rx_ant = ANT_ABC,
224 .need_pll_cfg = false, 230 .need_pll_cfg = false,
225 .pa_type = IWL_PA_SYSTEM, 231 .pa_type = IWL_PA_SYSTEM,
232 .max_ll_items = OTP_MAX_LL_ITEMS_6x00,
233 .shadow_ram_support = true,
226}; 234};
227 235
228struct iwl_cfg iwl6050_3agn_cfg = { 236struct iwl_cfg iwl6050_3agn_cfg = {
@@ -232,7 +240,7 @@ struct iwl_cfg iwl6050_3agn_cfg = {
232 .ucode_api_min = IWL6050_UCODE_API_MIN, 240 .ucode_api_min = IWL6050_UCODE_API_MIN,
233 .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N, 241 .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
234 .ops = &iwl6000_ops, 242 .ops = &iwl6000_ops,
235 .eeprom_size = IWL_5000_EEPROM_IMG_SIZE, 243 .eeprom_size = OTP_LOW_IMAGE_SIZE,
236 .eeprom_ver = EEPROM_5000_EEPROM_VERSION, 244 .eeprom_ver = EEPROM_5000_EEPROM_VERSION,
237 .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, 245 .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
238 .mod_params = &iwl50_mod_params, 246 .mod_params = &iwl50_mod_params,
@@ -240,6 +248,8 @@ struct iwl_cfg iwl6050_3agn_cfg = {
240 .valid_rx_ant = ANT_ABC, 248 .valid_rx_ant = ANT_ABC,
241 .need_pll_cfg = false, 249 .need_pll_cfg = false,
242 .pa_type = IWL_PA_SYSTEM, 250 .pa_type = IWL_PA_SYSTEM,
251 .max_ll_items = OTP_MAX_LL_ITEMS_6x00,
252 .shadow_ram_support = true,
243}; 253};
244 254
245MODULE_FIRMWARE(IWL6000_MODULE_FIRMWARE(IWL6000_UCODE_API_MAX)); 255MODULE_FIRMWARE(IWL6000_MODULE_FIRMWARE(IWL6000_UCODE_API_MAX));
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index 32750f4f1ce1..509683487e0e 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -209,6 +209,8 @@ struct iwl_mod_params {
209 * @ucode_api_max: Highest version of uCode API supported by driver. 209 * @ucode_api_max: Highest version of uCode API supported by driver.
210 * @ucode_api_min: Lowest version of uCode API supported by driver. 210 * @ucode_api_min: Lowest version of uCode API supported by driver.
211 * @pa_type: used by 6000 series only to identify the type of Power Amplifier 211 * @pa_type: used by 6000 series only to identify the type of Power Amplifier
212 * @max_ll_items: max number of OTP blocks
213 * @shadow_ram_support: shadow support for OTP memory
212 * 214 *
213 * We enable the driver to be backward compatible wrt API version. The 215 * We enable the driver to be backward compatible wrt API version. The
214 * driver specifies which APIs it supports (with @ucode_api_max being the 216 * driver specifies which APIs it supports (with @ucode_api_max being the
@@ -247,6 +249,8 @@ struct iwl_cfg {
247 bool need_pll_cfg; 249 bool need_pll_cfg;
248 bool use_isr_legacy; 250 bool use_isr_legacy;
249 enum iwl_pa_type pa_type; 251 enum iwl_pa_type pa_type;
252 const u16 max_ll_items;
253 const bool shadow_ram_support;
250}; 254};
251 255
252/*************************** 256/***************************
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index c34f9d73306d..0b19a6f93c84 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -887,6 +887,17 @@ enum iwl_nvm_type {
887 NVM_DEVICE_TYPE_OTP, 887 NVM_DEVICE_TYPE_OTP,
888}; 888};
889 889
890/*
891 * Two types of OTP memory access modes
892 * IWL_OTP_ACCESS_ABSOLUTE - absolute address mode,
893 * based on physical memory addressing
894 * IWL_OTP_ACCESS_RELATIVE - relative address mode,
895 * based on logical memory addressing
896 */
897enum iwl_access_mode {
898 IWL_OTP_ACCESS_ABSOLUTE,
899 IWL_OTP_ACCESS_RELATIVE,
900};
890 901
891/** 902/**
892 * enum iwl_pa_type - Power Amplifier type 903 * enum iwl_pa_type - Power Amplifier type
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-eeprom.c
index ded63320a463..01b95e89009a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-eeprom.c
+++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.c
@@ -152,6 +152,19 @@ 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 void iwl_set_otp_access(struct iwl_priv *priv, enum iwl_access_mode mode)
156{
157 u32 otpgp;
158
159 otpgp = iwl_read32(priv, CSR_OTP_GP_REG);
160 if (mode == IWL_OTP_ACCESS_ABSOLUTE)
161 iwl_clear_bit(priv, CSR_OTP_GP_REG,
162 CSR_OTP_GP_REG_OTP_ACCESS_MODE);
163 else
164 iwl_set_bit(priv, CSR_OTP_GP_REG,
165 CSR_OTP_GP_REG_OTP_ACCESS_MODE);
166}
167
155static int iwlcore_get_nvm_type(struct iwl_priv *priv) 168static int iwlcore_get_nvm_type(struct iwl_priv *priv)
156{ 169{
157 u32 otpgp; 170 u32 otpgp;
@@ -252,6 +265,124 @@ static int iwl_init_otp_access(struct iwl_priv *priv)
252 return ret; 265 return ret;
253} 266}
254 267
268static int iwl_read_otp_word(struct iwl_priv *priv, u16 addr, u16 *eeprom_data)
269{
270 int ret = 0;
271 u32 r;
272 u32 otpgp;
273
274 _iwl_write32(priv, CSR_EEPROM_REG,
275 CSR_EEPROM_REG_MSK_ADDR & (addr << 1));
276 ret = iwl_poll_direct_bit(priv, CSR_EEPROM_REG,
277 CSR_EEPROM_REG_READ_VALID_MSK,
278 IWL_EEPROM_ACCESS_TIMEOUT);
279 if (ret < 0) {
280 IWL_ERR(priv, "Time out reading OTP[%d]\n", addr);
281 return ret;
282 }
283 r = _iwl_read_direct32(priv, CSR_EEPROM_REG);
284 /* check for ECC errors: */
285 otpgp = iwl_read32(priv, CSR_OTP_GP_REG);
286 if (otpgp & CSR_OTP_GP_REG_ECC_UNCORR_STATUS_MSK) {
287 /* stop in this case */
288 /* set the uncorrectable OTP ECC bit for acknowledgement */
289 iwl_set_bit(priv, CSR_OTP_GP_REG,
290 CSR_OTP_GP_REG_ECC_UNCORR_STATUS_MSK);
291 IWL_ERR(priv, "Uncorrectable OTP ECC error, abort OTP read\n");
292 return -EINVAL;
293 }
294 if (otpgp & CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK) {
295 /* continue in this case */
296 /* set the correctable OTP ECC bit for acknowledgement */
297 iwl_set_bit(priv, CSR_OTP_GP_REG,
298 CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK);
299 IWL_ERR(priv, "Correctable OTP ECC error, continue read\n");
300 }
301 *eeprom_data = le16_to_cpu((__force __le16)(r >> 16));
302 return 0;
303}
304
305/*
306 * iwl_is_otp_empty: check for empty OTP
307 */
308static bool iwl_is_otp_empty(struct iwl_priv *priv)
309{
310 u16 next_link_addr = 0, link_value;
311 bool is_empty = false;
312
313 /* locate the beginning of OTP link list */
314 if (!iwl_read_otp_word(priv, next_link_addr, &link_value)) {
315 if (!link_value) {
316 IWL_ERR(priv, "OTP is empty\n");
317 is_empty = true;
318 }
319 } else {
320 IWL_ERR(priv, "Unable to read first block of OTP list.\n");
321 is_empty = true;
322 }
323
324 return is_empty;
325}
326
327
328/*
329 * iwl_find_otp_image: find EEPROM image in OTP
330 * finding the OTP block that contains the EEPROM image.
331 * the last valid block on the link list (the block _before_ the last block)
332 * is the block we should read and used to configure the device.
333 * If all the available OTP blocks are full, the last block will be the block
334 * we should read and used to configure the device.
335 * only perform this operation if shadow RAM is disabled
336 */
337static int iwl_find_otp_image(struct iwl_priv *priv,
338 u16 *validblockaddr)
339{
340 u16 next_link_addr = 0, link_value = 0, valid_addr;
341 int ret = 0;
342 int usedblocks = 0;
343
344 /* set addressing mode to absolute to traverse the link list */
345 iwl_set_otp_access(priv, IWL_OTP_ACCESS_ABSOLUTE);
346
347 /* checking for empty OTP or error */
348 if (iwl_is_otp_empty(priv))
349 return -EINVAL;
350
351 /*
352 * start traverse link list
353 * until reach the max number of OTP blocks
354 * different devices have different number of OTP blocks
355 */
356 do {
357 /* save current valid block address
358 * check for more block on the link list
359 */
360 valid_addr = next_link_addr;
361 next_link_addr = link_value;
362 IWL_DEBUG_INFO(priv, "OTP blocks %d addr 0x%x\n",
363 usedblocks, next_link_addr);
364 if (iwl_read_otp_word(priv, next_link_addr, &link_value))
365 return -EINVAL;
366 if (!link_value) {
367 /*
368 * reach the end of link list,
369 * set address point to the starting address
370 * of the image
371 */
372 goto done;
373 }
374 /* more in the link list, continue */
375 usedblocks++;
376 } while (usedblocks < priv->cfg->max_ll_items);
377 /* OTP full, use last block */
378 IWL_DEBUG_INFO(priv, "OTP is full, use last block\n");
379done:
380 *validblockaddr = valid_addr;
381 /* skip first 2 bytes (link list pointer) */
382 *validblockaddr += 2;
383 return ret;
384}
385
255/** 386/**
256 * iwl_eeprom_init - read EEPROM contents 387 * iwl_eeprom_init - read EEPROM contents
257 * 388 *
@@ -266,15 +397,14 @@ int iwl_eeprom_init(struct iwl_priv *priv)
266 int sz; 397 int sz;
267 int ret; 398 int ret;
268 u16 addr; 399 u16 addr;
269 u32 otpgp; 400 u16 validblockaddr = 0;
401 u16 cache_addr = 0;
270 402
271 priv->nvm_device_type = iwlcore_get_nvm_type(priv); 403 priv->nvm_device_type = iwlcore_get_nvm_type(priv);
272 if (priv->nvm_device_type == -ENOENT) 404 if (priv->nvm_device_type == -ENOENT)
273 return -ENOENT; 405 return -ENOENT;
274 /* allocate eeprom */ 406 /* allocate eeprom */
275 if (priv->nvm_device_type == NVM_DEVICE_TYPE_OTP) 407 IWL_DEBUG_INFO(priv, "NVM size = %d\n", priv->cfg->eeprom_size);
276 priv->cfg->eeprom_size =
277 OTP_BLOCK_SIZE * OTP_LOWER_BLOCKS_TOTAL;
278 sz = priv->cfg->eeprom_size; 408 sz = priv->cfg->eeprom_size;
279 priv->eeprom = kzalloc(sz, GFP_KERNEL); 409 priv->eeprom = kzalloc(sz, GFP_KERNEL);
280 if (!priv->eeprom) { 410 if (!priv->eeprom) {
@@ -302,46 +432,31 @@ int iwl_eeprom_init(struct iwl_priv *priv)
302 if (ret) { 432 if (ret) {
303 IWL_ERR(priv, "Failed to initialize OTP access.\n"); 433 IWL_ERR(priv, "Failed to initialize OTP access.\n");
304 ret = -ENOENT; 434 ret = -ENOENT;
305 goto err; 435 goto done;
306 } 436 }
307 _iwl_write32(priv, CSR_EEPROM_GP, 437 _iwl_write32(priv, CSR_EEPROM_GP,
308 iwl_read32(priv, CSR_EEPROM_GP) & 438 iwl_read32(priv, CSR_EEPROM_GP) &
309 ~CSR_EEPROM_GP_IF_OWNER_MSK); 439 ~CSR_EEPROM_GP_IF_OWNER_MSK);
310 /* clear */ 440
311 _iwl_write32(priv, CSR_OTP_GP_REG, 441 iwl_set_bit(priv, CSR_OTP_GP_REG,
312 iwl_read32(priv, CSR_OTP_GP_REG) |
313 CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK | 442 CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK |
314 CSR_OTP_GP_REG_ECC_UNCORR_STATUS_MSK); 443 CSR_OTP_GP_REG_ECC_UNCORR_STATUS_MSK);
315 444 /* traversing the linked list if no shadow ram supported */
316 for (addr = 0; addr < sz; addr += sizeof(u16)) { 445 if (!priv->cfg->shadow_ram_support) {
317 u32 r; 446 if (iwl_find_otp_image(priv, &validblockaddr)) {
318 447 ret = -ENOENT;
319 _iwl_write32(priv, CSR_EEPROM_REG,
320 CSR_EEPROM_REG_MSK_ADDR & (addr << 1));
321
322 ret = iwl_poll_direct_bit(priv, CSR_EEPROM_REG,
323 CSR_EEPROM_REG_READ_VALID_MSK,
324 IWL_EEPROM_ACCESS_TIMEOUT);
325 if (ret < 0) {
326 IWL_ERR(priv, "Time out reading OTP[%d]\n", addr);
327 goto done; 448 goto done;
328 } 449 }
329 r = _iwl_read_direct32(priv, CSR_EEPROM_REG); 450 }
330 /* check for ECC errors: */ 451 for (addr = validblockaddr; addr < validblockaddr + sz;
331 otpgp = iwl_read32(priv, CSR_OTP_GP_REG); 452 addr += sizeof(u16)) {
332 if (otpgp & CSR_OTP_GP_REG_ECC_UNCORR_STATUS_MSK) { 453 u16 eeprom_data;
333 /* stop in this case */ 454
334 IWL_ERR(priv, "Uncorrectable OTP ECC error, Abort OTP read\n"); 455 ret = iwl_read_otp_word(priv, addr, &eeprom_data);
456 if (ret)
335 goto done; 457 goto done;
336 } 458 e[cache_addr / 2] = eeprom_data;
337 if (otpgp & CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK) { 459 cache_addr += sizeof(u16);
338 /* continue in this case */
339 _iwl_write32(priv, CSR_OTP_GP_REG,
340 iwl_read32(priv, CSR_OTP_GP_REG) |
341 CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK);
342 IWL_ERR(priv, "Correctable OTP ECC error, continue read\n");
343 }
344 e[addr / 2] = le16_to_cpu((__force __le16)(r >> 16));
345 } 460 }
346 } else { 461 } else {
347 /* eeprom is an array of 16bit values */ 462 /* eeprom is an array of 16bit values */
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.h b/drivers/net/wireless/iwlwifi/iwl-eeprom.h
index 05d4fc4451dc..ca7920a8f52f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-eeprom.h
+++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.h
@@ -180,8 +180,14 @@ struct iwl_eeprom_channel {
180#define EEPROM_5050_EEPROM_VERSION (0x21E) 180#define EEPROM_5050_EEPROM_VERSION (0x21E)
181 181
182/* OTP */ 182/* OTP */
183#define OTP_LOWER_BLOCKS_TOTAL (3) 183/* lower blocks contain EEPROM image and calibration data */
184#define OTP_BLOCK_SIZE (0x400) 184#define OTP_LOW_IMAGE_SIZE (2 * 512 * sizeof(u16)) /* 2 KB */
185/* high blocks contain PAPD data */
186#define OTP_HIGH_IMAGE_SIZE_6x00 (6 * 512 * sizeof(u16)) /* 6 KB */
187#define OTP_HIGH_IMAGE_SIZE_1000 (0x200 * sizeof(u16)) /* 1024 bytes */
188#define OTP_MAX_LL_ITEMS_1000 (3) /* OTP blocks for 1000 */
189#define OTP_MAX_LL_ITEMS_6x00 (4) /* OTP blocks for 6x00 */
190#define OTP_MAX_LL_ITEMS_6x50 (7) /* OTP blocks for 6x50 */
185 191
186/* 2.4 GHz */ 192/* 2.4 GHz */
187extern const u8 iwl_eeprom_band_1[14]; 193extern const u8 iwl_eeprom_band_1[14];