diff options
author | Carolyn Wyborny <carolyn.wyborny@intel.com> | 2013-07-17 15:02:53 -0400 |
---|---|---|
committer | Jeff Kirsher <jeffrey.t.kirsher@intel.com> | 2013-08-22 05:26:00 -0400 |
commit | ef3a009297c50876980f21060aee61e8b516a990 (patch) | |
tree | 9875242d44568e9a3c66f460a9a8c778bd658dfb | |
parent | 5a823d8cdd0e16081bc09a03fa253b9750c4b034 (diff) |
igb: Refactor NVM read functions to accommodate devices with no flash
This patch refactors NVM read functions in order to accommodate i210 devices
that do not have a flash. Previously, this was not supported on i210
devices.
Signed-off-by: Carolyn Wyborny <carolyn.wyborny@intel.com>
Tested-by: Aaron Brown <aaron.f.brown@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
-rw-r--r-- | drivers/net/ethernet/intel/igb/e1000_defines.h | 5 | ||||
-rw-r--r-- | drivers/net/ethernet/intel/igb/e1000_i210.c | 110 | ||||
-rw-r--r-- | drivers/net/ethernet/intel/igb/e1000_i210.h | 3 | ||||
-rw-r--r-- | drivers/net/ethernet/intel/igb/igb_main.c | 19 |
4 files changed, 77 insertions, 60 deletions
diff --git a/drivers/net/ethernet/intel/igb/e1000_defines.h b/drivers/net/ethernet/intel/igb/e1000_defines.h index 179935576e14..452219811cc3 100644 --- a/drivers/net/ethernet/intel/igb/e1000_defines.h +++ b/drivers/net/ethernet/intel/igb/e1000_defines.h | |||
@@ -628,6 +628,11 @@ | |||
628 | #define E1000_I210_FIFO_SEL_TX_LEGACY E1000_I210_FIFO_SEL_TX_QAV(0) | 628 | #define E1000_I210_FIFO_SEL_TX_LEGACY E1000_I210_FIFO_SEL_TX_QAV(0) |
629 | #define E1000_I210_FIFO_SEL_BMC2OS_TX 0x06 | 629 | #define E1000_I210_FIFO_SEL_BMC2OS_TX 0x06 |
630 | #define E1000_I210_FIFO_SEL_BMC2OS_RX 0x01 | 630 | #define E1000_I210_FIFO_SEL_BMC2OS_RX 0x01 |
631 | #define E1000_I210_FLASH_SECTOR_SIZE 0x1000 /* 4KB FLASH sector unit size */ | ||
632 | /* Secure FLASH mode requires removing MSb */ | ||
633 | #define E1000_I210_FW_PTR_MASK 0x7FFF | ||
634 | /* Firmware code revision field word offset*/ | ||
635 | #define E1000_I210_FW_VER_OFFSET 328 | ||
631 | #define E1000_EECD_FLUPD_I210 0x00800000 /* Update FLASH */ | 636 | #define E1000_EECD_FLUPD_I210 0x00800000 /* Update FLASH */ |
632 | #define E1000_EECD_FLUDONE_I210 0x04000000 /* Update FLASH done*/ | 637 | #define E1000_EECD_FLUDONE_I210 0x04000000 /* Update FLASH done*/ |
633 | #define E1000_FLUDONE_ATTEMPTS 20000 | 638 | #define E1000_FLUDONE_ATTEMPTS 20000 |
diff --git a/drivers/net/ethernet/intel/igb/e1000_i210.c b/drivers/net/ethernet/intel/igb/e1000_i210.c index 4aebf35a0d75..0c0393316a3a 100644 --- a/drivers/net/ethernet/intel/igb/e1000_i210.c +++ b/drivers/net/ethernet/intel/igb/e1000_i210.c | |||
@@ -335,57 +335,101 @@ s32 igb_write_nvm_srwr_i210(struct e1000_hw *hw, u16 offset, u16 words, | |||
335 | } | 335 | } |
336 | 336 | ||
337 | /** | 337 | /** |
338 | * igb_read_nvm_i211 - Read NVM wrapper function for I211 | 338 | * igb_read_invm_word_i210 - Reads OTP |
339 | * @hw: pointer to the HW structure | ||
340 | * @address: the word address (aka eeprom offset) to read | ||
341 | * @data: pointer to the data read | ||
342 | * | ||
343 | * Reads 16-bit words from the OTP. Return error when the word is not | ||
344 | * stored in OTP. | ||
345 | **/ | ||
346 | static s32 igb_read_invm_word_i210(struct e1000_hw *hw, u8 address, u16 *data) | ||
347 | { | ||
348 | s32 status = -E1000_ERR_INVM_VALUE_NOT_FOUND; | ||
349 | u32 invm_dword; | ||
350 | u16 i; | ||
351 | u8 record_type, word_address; | ||
352 | |||
353 | for (i = 0; i < E1000_INVM_SIZE; i++) { | ||
354 | invm_dword = rd32(E1000_INVM_DATA_REG(i)); | ||
355 | /* Get record type */ | ||
356 | record_type = INVM_DWORD_TO_RECORD_TYPE(invm_dword); | ||
357 | if (record_type == E1000_INVM_UNINITIALIZED_STRUCTURE) | ||
358 | break; | ||
359 | if (record_type == E1000_INVM_CSR_AUTOLOAD_STRUCTURE) | ||
360 | i += E1000_INVM_CSR_AUTOLOAD_DATA_SIZE_IN_DWORDS; | ||
361 | if (record_type == E1000_INVM_RSA_KEY_SHA256_STRUCTURE) | ||
362 | i += E1000_INVM_RSA_KEY_SHA256_DATA_SIZE_IN_DWORDS; | ||
363 | if (record_type == E1000_INVM_WORD_AUTOLOAD_STRUCTURE) { | ||
364 | word_address = INVM_DWORD_TO_WORD_ADDRESS(invm_dword); | ||
365 | if (word_address == address) { | ||
366 | *data = INVM_DWORD_TO_WORD_DATA(invm_dword); | ||
367 | hw_dbg("Read INVM Word 0x%02x = %x", | ||
368 | address, *data); | ||
369 | status = E1000_SUCCESS; | ||
370 | break; | ||
371 | } | ||
372 | } | ||
373 | } | ||
374 | if (status != E1000_SUCCESS) | ||
375 | hw_dbg("Requested word 0x%02x not found in OTP\n", address); | ||
376 | return status; | ||
377 | } | ||
378 | |||
379 | /** | ||
380 | * igb_read_invm_i210 - Read invm wrapper function for I210/I211 | ||
339 | * @hw: pointer to the HW structure | 381 | * @hw: pointer to the HW structure |
340 | * @words: number of words to read | 382 | * @words: number of words to read |
341 | * @data: pointer to the data read | 383 | * @data: pointer to the data read |
342 | * | 384 | * |
343 | * Wrapper function to return data formerly found in the NVM. | 385 | * Wrapper function to return data formerly found in the NVM. |
344 | **/ | 386 | **/ |
345 | s32 igb_read_nvm_i211(struct e1000_hw *hw, u16 offset, u16 words, | 387 | static s32 igb_read_invm_i210(struct e1000_hw *hw, u16 offset, |
346 | u16 *data) | 388 | u16 words __always_unused, u16 *data) |
347 | { | 389 | { |
348 | s32 ret_val = E1000_SUCCESS; | 390 | s32 ret_val = E1000_SUCCESS; |
349 | 391 | ||
350 | /* Only the MAC addr is required to be present in the iNVM */ | 392 | /* Only the MAC addr is required to be present in the iNVM */ |
351 | switch (offset) { | 393 | switch (offset) { |
352 | case NVM_MAC_ADDR: | 394 | case NVM_MAC_ADDR: |
353 | ret_val = igb_read_invm_i211(hw, offset, &data[0]); | 395 | ret_val = igb_read_invm_word_i210(hw, (u8)offset, &data[0]); |
354 | ret_val |= igb_read_invm_i211(hw, offset+1, &data[1]); | 396 | ret_val |= igb_read_invm_word_i210(hw, (u8)offset+1, |
355 | ret_val |= igb_read_invm_i211(hw, offset+2, &data[2]); | 397 | &data[1]); |
398 | ret_val |= igb_read_invm_word_i210(hw, (u8)offset+2, | ||
399 | &data[2]); | ||
356 | if (ret_val != E1000_SUCCESS) | 400 | if (ret_val != E1000_SUCCESS) |
357 | hw_dbg("MAC Addr not found in iNVM\n"); | 401 | hw_dbg("MAC Addr not found in iNVM\n"); |
358 | break; | 402 | break; |
359 | case NVM_INIT_CTRL_2: | 403 | case NVM_INIT_CTRL_2: |
360 | ret_val = igb_read_invm_i211(hw, (u8)offset, data); | 404 | ret_val = igb_read_invm_word_i210(hw, (u8)offset, data); |
361 | if (ret_val != E1000_SUCCESS) { | 405 | if (ret_val != E1000_SUCCESS) { |
362 | *data = NVM_INIT_CTRL_2_DEFAULT_I211; | 406 | *data = NVM_INIT_CTRL_2_DEFAULT_I211; |
363 | ret_val = E1000_SUCCESS; | 407 | ret_val = E1000_SUCCESS; |
364 | } | 408 | } |
365 | break; | 409 | break; |
366 | case NVM_INIT_CTRL_4: | 410 | case NVM_INIT_CTRL_4: |
367 | ret_val = igb_read_invm_i211(hw, (u8)offset, data); | 411 | ret_val = igb_read_invm_word_i210(hw, (u8)offset, data); |
368 | if (ret_val != E1000_SUCCESS) { | 412 | if (ret_val != E1000_SUCCESS) { |
369 | *data = NVM_INIT_CTRL_4_DEFAULT_I211; | 413 | *data = NVM_INIT_CTRL_4_DEFAULT_I211; |
370 | ret_val = E1000_SUCCESS; | 414 | ret_val = E1000_SUCCESS; |
371 | } | 415 | } |
372 | break; | 416 | break; |
373 | case NVM_LED_1_CFG: | 417 | case NVM_LED_1_CFG: |
374 | ret_val = igb_read_invm_i211(hw, (u8)offset, data); | 418 | ret_val = igb_read_invm_word_i210(hw, (u8)offset, data); |
375 | if (ret_val != E1000_SUCCESS) { | 419 | if (ret_val != E1000_SUCCESS) { |
376 | *data = NVM_LED_1_CFG_DEFAULT_I211; | 420 | *data = NVM_LED_1_CFG_DEFAULT_I211; |
377 | ret_val = E1000_SUCCESS; | 421 | ret_val = E1000_SUCCESS; |
378 | } | 422 | } |
379 | break; | 423 | break; |
380 | case NVM_LED_0_2_CFG: | 424 | case NVM_LED_0_2_CFG: |
381 | igb_read_invm_i211(hw, offset, data); | 425 | ret_val = igb_read_invm_word_i210(hw, (u8)offset, data); |
382 | if (ret_val != E1000_SUCCESS) { | 426 | if (ret_val != E1000_SUCCESS) { |
383 | *data = NVM_LED_0_2_CFG_DEFAULT_I211; | 427 | *data = NVM_LED_0_2_CFG_DEFAULT_I211; |
384 | ret_val = E1000_SUCCESS; | 428 | ret_val = E1000_SUCCESS; |
385 | } | 429 | } |
386 | break; | 430 | break; |
387 | case NVM_ID_LED_SETTINGS: | 431 | case NVM_ID_LED_SETTINGS: |
388 | ret_val = igb_read_invm_i211(hw, (u8)offset, data); | 432 | ret_val = igb_read_invm_word_i210(hw, (u8)offset, data); |
389 | if (ret_val != E1000_SUCCESS) { | 433 | if (ret_val != E1000_SUCCESS) { |
390 | *data = ID_LED_RESERVED_FFFF; | 434 | *data = ID_LED_RESERVED_FFFF; |
391 | ret_val = E1000_SUCCESS; | 435 | ret_val = E1000_SUCCESS; |
@@ -411,48 +455,6 @@ s32 igb_read_nvm_i211(struct e1000_hw *hw, u16 offset, u16 words, | |||
411 | } | 455 | } |
412 | 456 | ||
413 | /** | 457 | /** |
414 | * igb_read_invm_i211 - Reads OTP | ||
415 | * @hw: pointer to the HW structure | ||
416 | * @address: the word address (aka eeprom offset) to read | ||
417 | * @data: pointer to the data read | ||
418 | * | ||
419 | * Reads 16-bit words from the OTP. Return error when the word is not | ||
420 | * stored in OTP. | ||
421 | **/ | ||
422 | s32 igb_read_invm_i211(struct e1000_hw *hw, u16 address, u16 *data) | ||
423 | { | ||
424 | s32 status = -E1000_ERR_INVM_VALUE_NOT_FOUND; | ||
425 | u32 invm_dword; | ||
426 | u16 i; | ||
427 | u8 record_type, word_address; | ||
428 | |||
429 | for (i = 0; i < E1000_INVM_SIZE; i++) { | ||
430 | invm_dword = rd32(E1000_INVM_DATA_REG(i)); | ||
431 | /* Get record type */ | ||
432 | record_type = INVM_DWORD_TO_RECORD_TYPE(invm_dword); | ||
433 | if (record_type == E1000_INVM_UNINITIALIZED_STRUCTURE) | ||
434 | break; | ||
435 | if (record_type == E1000_INVM_CSR_AUTOLOAD_STRUCTURE) | ||
436 | i += E1000_INVM_CSR_AUTOLOAD_DATA_SIZE_IN_DWORDS; | ||
437 | if (record_type == E1000_INVM_RSA_KEY_SHA256_STRUCTURE) | ||
438 | i += E1000_INVM_RSA_KEY_SHA256_DATA_SIZE_IN_DWORDS; | ||
439 | if (record_type == E1000_INVM_WORD_AUTOLOAD_STRUCTURE) { | ||
440 | word_address = INVM_DWORD_TO_WORD_ADDRESS(invm_dword); | ||
441 | if (word_address == (u8)address) { | ||
442 | *data = INVM_DWORD_TO_WORD_DATA(invm_dword); | ||
443 | hw_dbg("Read INVM Word 0x%02x = %x", | ||
444 | address, *data); | ||
445 | status = E1000_SUCCESS; | ||
446 | break; | ||
447 | } | ||
448 | } | ||
449 | } | ||
450 | if (status != E1000_SUCCESS) | ||
451 | hw_dbg("Requested word 0x%02x not found in OTP\n", address); | ||
452 | return status; | ||
453 | } | ||
454 | |||
455 | /** | ||
456 | * igb_read_invm_version - Reads iNVM version and image type | 458 | * igb_read_invm_version - Reads iNVM version and image type |
457 | * @hw: pointer to the HW structure | 459 | * @hw: pointer to the HW structure |
458 | * @invm_ver: version structure for the version read | 460 | * @invm_ver: version structure for the version read |
@@ -826,7 +828,7 @@ s32 igb_init_nvm_params_i210(struct e1000_hw *hw) | |||
826 | nvm->ops.update = igb_update_nvm_checksum_i210; | 828 | nvm->ops.update = igb_update_nvm_checksum_i210; |
827 | } else { | 829 | } else { |
828 | hw->nvm.type = e1000_nvm_invm; | 830 | hw->nvm.type = e1000_nvm_invm; |
829 | nvm->ops.read = igb_read_nvm_i211; | 831 | nvm->ops.read = igb_read_invm_i210; |
830 | nvm->ops.write = NULL; | 832 | nvm->ops.write = NULL; |
831 | nvm->ops.validate = NULL; | 833 | nvm->ops.validate = NULL; |
832 | nvm->ops.update = NULL; | 834 | nvm->ops.update = NULL; |
diff --git a/drivers/net/ethernet/intel/igb/e1000_i210.h b/drivers/net/ethernet/intel/igb/e1000_i210.h index a2a1f70cc8dd..dde3c4b7ea99 100644 --- a/drivers/net/ethernet/intel/igb/e1000_i210.h +++ b/drivers/net/ethernet/intel/igb/e1000_i210.h | |||
@@ -35,14 +35,11 @@ extern s32 igb_write_nvm_srwr_i210(struct e1000_hw *hw, u16 offset, | |||
35 | u16 words, u16 *data); | 35 | u16 words, u16 *data); |
36 | extern s32 igb_read_nvm_srrd_i210(struct e1000_hw *hw, u16 offset, | 36 | extern s32 igb_read_nvm_srrd_i210(struct e1000_hw *hw, u16 offset, |
37 | u16 words, u16 *data); | 37 | u16 words, u16 *data); |
38 | extern s32 igb_read_invm_i211(struct e1000_hw *hw, u16 address, u16 *data); | ||
39 | extern s32 igb_acquire_swfw_sync_i210(struct e1000_hw *hw, u16 mask); | 38 | extern s32 igb_acquire_swfw_sync_i210(struct e1000_hw *hw, u16 mask); |
40 | extern void igb_release_swfw_sync_i210(struct e1000_hw *hw, u16 mask); | 39 | extern void igb_release_swfw_sync_i210(struct e1000_hw *hw, u16 mask); |
41 | extern s32 igb_acquire_nvm_i210(struct e1000_hw *hw); | 40 | extern s32 igb_acquire_nvm_i210(struct e1000_hw *hw); |
42 | extern void igb_release_nvm_i210(struct e1000_hw *hw); | 41 | extern void igb_release_nvm_i210(struct e1000_hw *hw); |
43 | extern s32 igb_valid_led_default_i210(struct e1000_hw *hw, u16 *data); | 42 | extern s32 igb_valid_led_default_i210(struct e1000_hw *hw, u16 *data); |
44 | extern s32 igb_read_nvm_i211(struct e1000_hw *hw, u16 offset, u16 words, | ||
45 | u16 *data); | ||
46 | extern s32 igb_read_invm_version(struct e1000_hw *hw, | 43 | extern s32 igb_read_invm_version(struct e1000_hw *hw, |
47 | struct e1000_fw_version *invm_ver); | 44 | struct e1000_fw_version *invm_ver); |
48 | extern s32 igb_read_xmdio_reg(struct e1000_hw *hw, u16 addr, u8 dev_addr, | 45 | extern s32 igb_read_xmdio_reg(struct e1000_hw *hw, u16 addr, u8 dev_addr, |
diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c index 1a0137d68109..387864db7259 100644 --- a/drivers/net/ethernet/intel/igb/igb_main.c +++ b/drivers/net/ethernet/intel/igb/igb_main.c | |||
@@ -2166,15 +2166,28 @@ static int igb_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
2166 | */ | 2166 | */ |
2167 | hw->mac.ops.reset_hw(hw); | 2167 | hw->mac.ops.reset_hw(hw); |
2168 | 2168 | ||
2169 | /* make sure the NVM is good , i211 parts have special NVM that | 2169 | /* make sure the NVM is good , i211/i210 parts can have special NVM |
2170 | * doesn't contain a checksum | 2170 | * that doesn't contain a checksum |
2171 | */ | 2171 | */ |
2172 | if (hw->mac.type != e1000_i211) { | 2172 | switch (hw->mac.type) { |
2173 | case e1000_i210: | ||
2174 | case e1000_i211: | ||
2175 | if (igb_get_flash_presence_i210(hw)) { | ||
2176 | if (hw->nvm.ops.validate(hw) < 0) { | ||
2177 | dev_err(&pdev->dev, | ||
2178 | "The NVM Checksum Is Not Valid\n"); | ||
2179 | err = -EIO; | ||
2180 | goto err_eeprom; | ||
2181 | } | ||
2182 | } | ||
2183 | break; | ||
2184 | default: | ||
2173 | if (hw->nvm.ops.validate(hw) < 0) { | 2185 | if (hw->nvm.ops.validate(hw) < 0) { |
2174 | dev_err(&pdev->dev, "The NVM Checksum Is Not Valid\n"); | 2186 | dev_err(&pdev->dev, "The NVM Checksum Is Not Valid\n"); |
2175 | err = -EIO; | 2187 | err = -EIO; |
2176 | goto err_eeprom; | 2188 | goto err_eeprom; |
2177 | } | 2189 | } |
2190 | break; | ||
2178 | } | 2191 | } |
2179 | 2192 | ||
2180 | /* copy the MAC address out of the NVM */ | 2193 | /* copy the MAC address out of the NVM */ |