diff options
author | Carolyn Wyborny <carolyn.wyborny@intel.com> | 2012-10-23 09:04:37 -0400 |
---|---|---|
committer | Jeff Kirsher <jeffrey.t.kirsher@intel.com> | 2012-11-01 05:35:52 -0400 |
commit | 09e77287e752c8fc9743d865ddadc1a0d81a4927 (patch) | |
tree | f86cf9a83520ce45bbc9e06adf817cf68b372af6 /drivers/net/ethernet/intel/igb | |
parent | 40b20122f92b9e29d7770c12eb58b3a30e1cce33 (diff) |
igb: Add function to read i211's invm version
The i211's one-time programmable (invm) version field is different than the
other fields contained in it. This patch adds a function to get the invm version
of it and store it for output from ethtool.
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>
Diffstat (limited to 'drivers/net/ethernet/intel/igb')
-rw-r--r-- | drivers/net/ethernet/intel/igb/e1000_i210.c | 94 | ||||
-rw-r--r-- | drivers/net/ethernet/intel/igb/e1000_i210.h | 11 | ||||
-rw-r--r-- | drivers/net/ethernet/intel/igb/e1000_mac.h | 1 | ||||
-rw-r--r-- | drivers/net/ethernet/intel/igb/e1000_nvm.c | 1 |
4 files changed, 107 insertions, 0 deletions
diff --git a/drivers/net/ethernet/intel/igb/e1000_i210.c b/drivers/net/ethernet/intel/igb/e1000_i210.c index 77a5f939bc74..41474298d365 100644 --- a/drivers/net/ethernet/intel/igb/e1000_i210.c +++ b/drivers/net/ethernet/intel/igb/e1000_i210.c | |||
@@ -423,6 +423,100 @@ s32 igb_read_invm_i211(struct e1000_hw *hw, u16 address, u16 *data) | |||
423 | } | 423 | } |
424 | 424 | ||
425 | /** | 425 | /** |
426 | * igb_read_invm_version - Reads iNVM version and image type | ||
427 | * @hw: pointer to the HW structure | ||
428 | * @invm_ver: version structure for the version read | ||
429 | * | ||
430 | * Reads iNVM version and image type. | ||
431 | **/ | ||
432 | s32 igb_read_invm_version(struct e1000_hw *hw, | ||
433 | struct e1000_fw_version *invm_ver) { | ||
434 | u32 *record = NULL; | ||
435 | u32 *next_record = NULL; | ||
436 | u32 i = 0; | ||
437 | u32 invm_dword = 0; | ||
438 | u32 invm_blocks = E1000_INVM_SIZE - (E1000_INVM_ULT_BYTES_SIZE / | ||
439 | E1000_INVM_RECORD_SIZE_IN_BYTES); | ||
440 | u32 buffer[E1000_INVM_SIZE]; | ||
441 | s32 status = -E1000_ERR_INVM_VALUE_NOT_FOUND; | ||
442 | u16 version = 0; | ||
443 | |||
444 | /* Read iNVM memory */ | ||
445 | for (i = 0; i < E1000_INVM_SIZE; i++) { | ||
446 | invm_dword = rd32(E1000_INVM_DATA_REG(i)); | ||
447 | buffer[i] = invm_dword; | ||
448 | } | ||
449 | |||
450 | /* Read version number */ | ||
451 | for (i = 1; i < invm_blocks; i++) { | ||
452 | record = &buffer[invm_blocks - i]; | ||
453 | next_record = &buffer[invm_blocks - i + 1]; | ||
454 | |||
455 | /* Check if we have first version location used */ | ||
456 | if ((i == 1) && ((*record & E1000_INVM_VER_FIELD_ONE) == 0)) { | ||
457 | version = 0; | ||
458 | status = E1000_SUCCESS; | ||
459 | break; | ||
460 | } | ||
461 | /* Check if we have second version location used */ | ||
462 | else if ((i == 1) && | ||
463 | ((*record & E1000_INVM_VER_FIELD_TWO) == 0)) { | ||
464 | version = (*record & E1000_INVM_VER_FIELD_ONE) >> 3; | ||
465 | status = E1000_SUCCESS; | ||
466 | break; | ||
467 | } | ||
468 | /* Check if we have odd version location | ||
469 | * used and it is the last one used | ||
470 | */ | ||
471 | else if ((((*record & E1000_INVM_VER_FIELD_ONE) == 0) && | ||
472 | ((*record & 0x3) == 0)) || (((*record & 0x3) != 0) && | ||
473 | (i != 1))) { | ||
474 | version = (*next_record & E1000_INVM_VER_FIELD_TWO) | ||
475 | >> 13; | ||
476 | status = E1000_SUCCESS; | ||
477 | break; | ||
478 | } | ||
479 | /* Check if we have even version location | ||
480 | * used and it is the last one used | ||
481 | */ | ||
482 | else if (((*record & E1000_INVM_VER_FIELD_TWO) == 0) && | ||
483 | ((*record & 0x3) == 0)) { | ||
484 | version = (*record & E1000_INVM_VER_FIELD_ONE) >> 3; | ||
485 | status = E1000_SUCCESS; | ||
486 | break; | ||
487 | } | ||
488 | } | ||
489 | |||
490 | if (status == E1000_SUCCESS) { | ||
491 | invm_ver->invm_major = (version & E1000_INVM_MAJOR_MASK) | ||
492 | >> E1000_INVM_MAJOR_SHIFT; | ||
493 | invm_ver->invm_minor = version & E1000_INVM_MINOR_MASK; | ||
494 | } | ||
495 | /* Read Image Type */ | ||
496 | for (i = 1; i < invm_blocks; i++) { | ||
497 | record = &buffer[invm_blocks - i]; | ||
498 | next_record = &buffer[invm_blocks - i + 1]; | ||
499 | |||
500 | /* Check if we have image type in first location used */ | ||
501 | if ((i == 1) && ((*record & E1000_INVM_IMGTYPE_FIELD) == 0)) { | ||
502 | invm_ver->invm_img_type = 0; | ||
503 | status = E1000_SUCCESS; | ||
504 | break; | ||
505 | } | ||
506 | /* Check if we have image type in first location used */ | ||
507 | else if ((((*record & 0x3) == 0) && | ||
508 | ((*record & E1000_INVM_IMGTYPE_FIELD) == 0)) || | ||
509 | ((((*record & 0x3) != 0) && (i != 1)))) { | ||
510 | invm_ver->invm_img_type = | ||
511 | (*next_record & E1000_INVM_IMGTYPE_FIELD) >> 23; | ||
512 | status = E1000_SUCCESS; | ||
513 | break; | ||
514 | } | ||
515 | } | ||
516 | return status; | ||
517 | } | ||
518 | |||
519 | /** | ||
426 | * igb_validate_nvm_checksum_i210 - Validate EEPROM checksum | 520 | * igb_validate_nvm_checksum_i210 - Validate EEPROM checksum |
427 | * @hw: pointer to the HW structure | 521 | * @hw: pointer to the HW structure |
428 | * | 522 | * |
diff --git a/drivers/net/ethernet/intel/igb/e1000_i210.h b/drivers/net/ethernet/intel/igb/e1000_i210.h index 5dc2bd3f50bc..974d23584d70 100644 --- a/drivers/net/ethernet/intel/igb/e1000_i210.h +++ b/drivers/net/ethernet/intel/igb/e1000_i210.h | |||
@@ -43,6 +43,8 @@ extern void igb_release_nvm_i210(struct e1000_hw *hw); | |||
43 | extern s32 igb_valid_led_default_i210(struct e1000_hw *hw, u16 *data); | 43 | 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, | 44 | extern s32 igb_read_nvm_i211(struct e1000_hw *hw, u16 offset, u16 words, |
45 | u16 *data); | 45 | u16 *data); |
46 | extern s32 igb_read_invm_version(struct e1000_hw *hw, | ||
47 | struct e1000_fw_version *invm_ver); | ||
46 | 48 | ||
47 | #define E1000_STM_OPCODE 0xDB00 | 49 | #define E1000_STM_OPCODE 0xDB00 |
48 | #define E1000_EEPROM_FLASH_SIZE_WORD 0x11 | 50 | #define E1000_EEPROM_FLASH_SIZE_WORD 0x11 |
@@ -65,6 +67,15 @@ enum E1000_INVM_STRUCTURE_TYPE { | |||
65 | 67 | ||
66 | #define E1000_INVM_RSA_KEY_SHA256_DATA_SIZE_IN_DWORDS 8 | 68 | #define E1000_INVM_RSA_KEY_SHA256_DATA_SIZE_IN_DWORDS 8 |
67 | #define E1000_INVM_CSR_AUTOLOAD_DATA_SIZE_IN_DWORDS 1 | 69 | #define E1000_INVM_CSR_AUTOLOAD_DATA_SIZE_IN_DWORDS 1 |
70 | #define E1000_INVM_ULT_BYTES_SIZE 8 | ||
71 | #define E1000_INVM_RECORD_SIZE_IN_BYTES 4 | ||
72 | #define E1000_INVM_VER_FIELD_ONE 0x1FF8 | ||
73 | #define E1000_INVM_VER_FIELD_TWO 0x7FE000 | ||
74 | #define E1000_INVM_IMGTYPE_FIELD 0x1F800000 | ||
75 | |||
76 | #define E1000_INVM_MAJOR_MASK 0x3F0 | ||
77 | #define E1000_INVM_MINOR_MASK 0xF | ||
78 | #define E1000_INVM_MAJOR_SHIFT 4 | ||
68 | 79 | ||
69 | #define ID_LED_DEFAULT_I210 ((ID_LED_OFF1_ON2 << 8) | \ | 80 | #define ID_LED_DEFAULT_I210 ((ID_LED_OFF1_ON2 << 8) | \ |
70 | (ID_LED_OFF1_OFF2 << 4) | \ | 81 | (ID_LED_OFF1_OFF2 << 4) | \ |
diff --git a/drivers/net/ethernet/intel/igb/e1000_mac.h b/drivers/net/ethernet/intel/igb/e1000_mac.h index cbddc4e51e30..e2b2c4b9c951 100644 --- a/drivers/net/ethernet/intel/igb/e1000_mac.h +++ b/drivers/net/ethernet/intel/igb/e1000_mac.h | |||
@@ -33,6 +33,7 @@ | |||
33 | #include "e1000_phy.h" | 33 | #include "e1000_phy.h" |
34 | #include "e1000_nvm.h" | 34 | #include "e1000_nvm.h" |
35 | #include "e1000_defines.h" | 35 | #include "e1000_defines.h" |
36 | #include "e1000_i210.h" | ||
36 | 37 | ||
37 | /* | 38 | /* |
38 | * Functions that should not be called directly from drivers but can be used | 39 | * Functions that should not be called directly from drivers but can be used |
diff --git a/drivers/net/ethernet/intel/igb/e1000_nvm.c b/drivers/net/ethernet/intel/igb/e1000_nvm.c index 54ff53905ffe..7db3f80bcd57 100644 --- a/drivers/net/ethernet/intel/igb/e1000_nvm.c +++ b/drivers/net/ethernet/intel/igb/e1000_nvm.c | |||
@@ -727,6 +727,7 @@ void igb_get_fw_version(struct e1000_hw *hw, struct e1000_fw_version *fw_vers) | |||
727 | 727 | ||
728 | switch (hw->mac.type) { | 728 | switch (hw->mac.type) { |
729 | case e1000_i211: | 729 | case e1000_i211: |
730 | igb_read_invm_version(hw, fw_vers); | ||
730 | return; | 731 | return; |
731 | case e1000_82575: | 732 | case e1000_82575: |
732 | case e1000_82576: | 733 | case e1000_82576: |